| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- from __future__ import print_function
- 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 exitProc(cmakeCommand):
- # Tell the server to exit.
- cmakeCommand.stdin.close()
- cmakeCommand.stdout.close()
- # Wait for the server to exit.
- # If this version of python supports it, terminate the server after a timeout.
- try:
- cmakeCommand.wait(timeout=5)
- except TypeError:
- cmakeCommand.wait()
- except:
- cmakeCommand.terminate()
- raise
- 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)
- def validateCache(cmakeCommand, data):
- packet = waitForReply(cmakeCommand, 'cache', '', False)
- cache = packet['cache']
- if (data['isEmpty']):
- if (cache != []):
- print('Expected empty cache, but got data.\n')
- sys.exit(1)
- return;
- if (cache == []):
- print('Expected cache contents, but got none.\n')
- sys.exit(1)
- hadHomeDir = False
- for value in cache:
- if (value['key'] == 'CMAKE_HOME_DIRECTORY'):
- hadHomeDir = True
- if (not hadHomeDir):
- print('No CMAKE_HOME_DIRECTORY found in cache.')
- sys.exit(1)
|