71a505870c
Do some basic unit tests for "codemodel", "cmakeInputs" and "cache" commands of the cmake server. This just calls the commands right now and makes sure the server thinks it can reply to the request. The data itself is currently not validated.
199 lines
5.6 KiB
Python
199 lines
5.6 KiB
Python
import sys, subprocess, json
|
|
|
|
termwidth = 150
|
|
|
|
print_communication = True
|
|
|
|
def ordered(obj):
|
|
if isinstance(obj, dict):
|
|
return sorted((k, ordered(v)) for k, v in obj.items())
|
|
if isinstance(obj, list):
|
|
return sorted(ordered(x) for x in obj)
|
|
else:
|
|
return obj
|
|
|
|
def col_print(title, array):
|
|
print
|
|
print
|
|
print(title)
|
|
|
|
indentwidth = 4
|
|
indent = " " * indentwidth
|
|
|
|
if not array:
|
|
print(indent + "<None>")
|
|
return
|
|
|
|
padwidth = 2
|
|
|
|
maxitemwidth = len(max(array, key=len))
|
|
|
|
numCols = max(1, int((termwidth - indentwidth + padwidth) / (maxitemwidth + padwidth)))
|
|
|
|
numRows = len(array) // numCols + 1
|
|
|
|
pad = " " * padwidth
|
|
|
|
for index in range(numRows):
|
|
print(indent + pad.join(item.ljust(maxitemwidth) for item in array[index::numRows]))
|
|
|
|
def waitForRawMessage(cmakeCommand):
|
|
stdoutdata = ""
|
|
payload = ""
|
|
while not cmakeCommand.poll():
|
|
stdoutdataLine = cmakeCommand.stdout.readline()
|
|
if stdoutdataLine:
|
|
stdoutdata += stdoutdataLine.decode('utf-8')
|
|
else:
|
|
break
|
|
begin = stdoutdata.find("[== CMake Server ==[\n")
|
|
end = stdoutdata.find("]== CMake Server ==]")
|
|
|
|
if (begin != -1 and end != -1):
|
|
begin += len("[== CMake Server ==[\n")
|
|
payload = stdoutdata[begin:end]
|
|
if print_communication:
|
|
print("\nSERVER>", json.loads(payload), "\n")
|
|
return json.loads(payload)
|
|
|
|
def writeRawData(cmakeCommand, content):
|
|
writeRawData.counter += 1
|
|
payload = """
|
|
[== CMake Server ==[
|
|
%s
|
|
]== CMake Server ==]
|
|
""" % content
|
|
|
|
rn = ( writeRawData.counter % 2 ) == 0
|
|
|
|
if rn:
|
|
payload = payload.replace('\n', '\r\n')
|
|
|
|
if print_communication:
|
|
print("\nCLIENT>", content, "(Use \\r\\n:", rn, ")\n")
|
|
cmakeCommand.stdin.write(payload.encode('utf-8'))
|
|
cmakeCommand.stdin.flush()
|
|
writeRawData.counter = 0
|
|
|
|
def writePayload(cmakeCommand, obj):
|
|
writeRawData(cmakeCommand, json.dumps(obj))
|
|
|
|
def initProc(cmakeCommand):
|
|
cmakeCommand = subprocess.Popen([cmakeCommand, "-E", "server", "--experimental", "--debug"],
|
|
stdin=subprocess.PIPE,
|
|
stdout=subprocess.PIPE)
|
|
|
|
packet = waitForRawMessage(cmakeCommand)
|
|
if packet == None:
|
|
print("Not in server mode")
|
|
sys.exit(1)
|
|
|
|
if packet['type'] != 'hello':
|
|
print("No hello message")
|
|
sys.exit(1)
|
|
|
|
return cmakeCommand
|
|
|
|
def waitForMessage(cmakeCommand, expected):
|
|
data = ordered(expected)
|
|
packet = ordered(waitForRawMessage(cmakeCommand))
|
|
|
|
if packet != data:
|
|
sys.exit(-1)
|
|
return packet
|
|
|
|
def waitForReply(cmakeCommand, originalType, cookie, skipProgress):
|
|
gotResult = False
|
|
while True:
|
|
packet = waitForRawMessage(cmakeCommand)
|
|
t = packet['type']
|
|
if packet['cookie'] != cookie or packet['inReplyTo'] != originalType:
|
|
sys.exit(1)
|
|
if t == 'message' or t == 'progress':
|
|
if skipProgress:
|
|
continue
|
|
if t == 'reply':
|
|
break
|
|
sys.exit(1)
|
|
|
|
return packet
|
|
|
|
def waitForError(cmakeCommand, originalType, cookie, message):
|
|
packet = waitForRawMessage(cmakeCommand)
|
|
if packet['cookie'] != cookie or packet['type'] != 'error' or packet['inReplyTo'] != originalType or packet['errorMessage'] != message:
|
|
sys.exit(1)
|
|
|
|
def waitForProgress(cmakeCommand, originalType, cookie, current, message):
|
|
packet = waitForRawMessage(cmakeCommand)
|
|
if packet['cookie'] != cookie or packet['type'] != 'progress' or packet['inReplyTo'] != originalType or packet['progressCurrent'] != current or packet['progressMessage'] != message:
|
|
sys.exit(1)
|
|
|
|
def handshake(cmakeCommand, major, minor, source, build, generator, extraGenerator):
|
|
version = { 'major': major }
|
|
if minor >= 0:
|
|
version['minor'] = minor
|
|
|
|
writePayload(cmakeCommand, { 'type': 'handshake', 'protocolVersion': version,
|
|
'cookie': 'TEST_HANDSHAKE', 'sourceDirectory': source, 'buildDirectory': build,
|
|
'generator': generator, 'extraGenerator': extraGenerator })
|
|
waitForReply(cmakeCommand, 'handshake', 'TEST_HANDSHAKE', False)
|
|
|
|
def validateGlobalSettings(cmakeCommand, cmakeCommandPath, data):
|
|
packet = waitForReply(cmakeCommand, 'globalSettings', '', False)
|
|
|
|
capabilities = packet['capabilities']
|
|
|
|
# validate version:
|
|
cmakeoutput = subprocess.check_output([ cmakeCommandPath, "--version" ], universal_newlines=True)
|
|
cmakeVersion = cmakeoutput.splitlines()[0][14:]
|
|
|
|
version = capabilities['version']
|
|
versionString = version['string']
|
|
vs = str(version['major']) + '.' + str(version['minor']) + '.' + str(version['patch'])
|
|
if (versionString != vs and not versionString.startswith(vs + '-')):
|
|
sys.exit(1)
|
|
if (versionString != cmakeVersion):
|
|
sys.exit(1)
|
|
|
|
# validate generators:
|
|
generatorObjects = capabilities['generators']
|
|
|
|
cmakeoutput = subprocess.check_output([ cmakeCommandPath, "--help" ], universal_newlines=True)
|
|
index = cmakeoutput.index('\nGenerators\n\n')
|
|
cmakeGenerators = []
|
|
for line in cmakeoutput[index + 12:].splitlines():
|
|
if not line.startswith(' '):
|
|
continue
|
|
if line.startswith(' '):
|
|
continue
|
|
equalPos = line.find('=')
|
|
tmp = ''
|
|
if (equalPos > 0):
|
|
tmp = line[2:equalPos].strip()
|
|
else:
|
|
tmp = line.strip()
|
|
if tmp.endswith(" [arch]"):
|
|
tmp = tmp[0:len(tmp) - 7]
|
|
if (len(tmp) > 0) and (" - " not in tmp) and (tmp != 'KDevelop3'):
|
|
cmakeGenerators.append(tmp)
|
|
|
|
generators = []
|
|
for genObj in generatorObjects:
|
|
generators.append(genObj['name'])
|
|
|
|
generators.sort()
|
|
cmakeGenerators.sort()
|
|
|
|
for gen in cmakeGenerators:
|
|
if (not gen in generators):
|
|
sys.exit(1)
|
|
|
|
gen = packet['generator']
|
|
if (gen != '' and not (gen in generators)):
|
|
sys.exit(1)
|
|
|
|
for i in data:
|
|
print("Validating", i)
|
|
if (packet[i] != data[i]):
|
|
sys.exit(1)
|