Fix run.py (#71)

* fix run.py

* run.py: fix Windows support

* fix test listing
This commit is contained in:
Dimon4eg 2019-05-13 04:37:22 +03:00 committed by Benjamin Sergeant
parent 8a94c945b7
commit d8dc977fc1
4 changed files with 63 additions and 60 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
build build
*.pyc

7
test/.gitignore vendored
View File

@ -1,9 +1,10 @@
CMakeCache.txt CMakeCache.txt
package-lock.json package-lock.json
CMakeFiles CMakeFiles
ixwebsocket_unittest ixwebsocket_unittest
cmake_install.cmake cmake_install.cmake
node_modules node_modules
ixwebsocket ixwebsocket
Makefile Makefile
build build
ixwebsocket_unittest.xml

View File

@ -5,12 +5,11 @@
cmake_minimum_required (VERSION 3.4.1) cmake_minimum_required (VERSION 3.4.1)
project (ixwebsocket_unittest) project (ixwebsocket_unittest)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../third_party/sanitizers-cmake/cmake" ${CMAKE_MODULE_PATH})
find_package(Sanitizers)
set (CMAKE_CXX_STANDARD 14) set (CMAKE_CXX_STANDARD 14)
if (NOT WIN32) if (NOT WIN32)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../third_party/sanitizers-cmake/cmake" ${CMAKE_MODULE_PATH})
find_package(Sanitizers)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
set(CMAKE_LD_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread") set(CMAKE_LD_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
option(USE_TLS "Add TLS support" ON) option(USE_TLS "Add TLS support" ON)
@ -51,7 +50,10 @@ if (NOT WIN32)
endif() endif()
add_executable(ixwebsocket_unittest ${SOURCES}) add_executable(ixwebsocket_unittest ${SOURCES})
add_sanitizers(ixwebsocket_unittest)
if (NOT WIN32)
add_sanitizers(ixwebsocket_unittest)
endif()
if (APPLE AND USE_TLS) if (APPLE AND USE_TLS)
target_link_libraries(ixwebsocket_unittest "-framework foundation" "-framework security") target_link_libraries(ixwebsocket_unittest "-framework foundation" "-framework security")

View File

@ -28,9 +28,9 @@ try:
except ImportError: except ImportError:
hasClick = False hasClick = False
BUILD_TYPE = 'Debug'
DEFAULT_EXE = 'ixwebsocket_unittest' XML_OUTPUT_FILE = 'ixwebsocket_unittest.xml'
TEST_EXE_PATH = None
class Command(object): class Command(object):
"""Run system commands with timeout """Run system commands with timeout
@ -65,7 +65,7 @@ class Command(object):
return True, self.process.returncode return True, self.process.returncode
def runCommand(cmd, assertOnFailure=True, timeout=None): def runCommand(cmd, abortOnFailure=True, timeout=None):
'''Small wrapper to run a command and make sure it succeed''' '''Small wrapper to run a command and make sure it succeed'''
if timeout is None: if timeout is None:
@ -73,16 +73,13 @@ def runCommand(cmd, assertOnFailure=True, timeout=None):
print('\nRunning', cmd) print('\nRunning', cmd)
command = Command(cmd) command = Command(cmd)
timedout, ret = command.run(timeout) succeed, ret = command.run(timeout)
if timedout: if not succeed or ret != 0:
print('Unittest timed out') msg = 'cmd {}\nfailed with error code {}'.format(cmd, ret)
msg = 'cmd {} failed with error code {}'.format(cmd, ret)
if ret != 0:
print(msg) print(msg)
if assertOnFailure: if abortOnFailure:
assert False sys.exit(-1)
def runCMake(sanitizer, buildDir): def runCMake(sanitizer, buildDir):
@ -91,12 +88,6 @@ def runCMake(sanitizer, buildDir):
(remove build sub-folder). (remove build sub-folder).
''' '''
# CMake installed via Self Service ends up here.
cmake_executable = '/Applications/CMake.app/Contents/bin/cmake'
if not os.path.exists(cmake_executable):
cmake_executable = 'cmake'
sanitizersFlags = { sanitizersFlags = {
'asan': '-DSANITIZE_ADDRESS=On', 'asan': '-DSANITIZE_ADDRESS=On',
'ubsan': '-DSANITIZE_UNDEFINED=On', 'ubsan': '-DSANITIZE_UNDEFINED=On',
@ -110,19 +101,22 @@ def runCMake(sanitizer, buildDir):
if not os.path.exists(cmakeExecutable): if not os.path.exists(cmakeExecutable):
cmakeExecutable = 'cmake' cmakeExecutable = 'cmake'
generator = '"Unix Makefiles"'
if platform.system() == 'Windows': if platform.system() == 'Windows':
generator = '"NMake Makefiles"' #generator = '"NMake Makefiles"'
generator = '"Visual Studio 16 2019"'
else:
generator = '"Unix Makefiles"'
fmt = ''' CMAKE_BUILD_TYPE = BUILD_TYPE
{cmakeExecutable} -H. \
fmt = '{cmakeExecutable} -H. \
{sanitizerFlag} \ {sanitizerFlag} \
-B{buildDir} \ -B"{buildDir}" \
-DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_BUILD_TYPE={CMAKE_BUILD_TYPE} \
-DUSE_TLS=1 \ -DUSE_TLS=1 \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-G{generator} -G{generator}'
'''
cmakeCmd = fmt.format(**locals()) cmakeCmd = fmt.format(**locals())
runCommand(cmakeCmd) runCommand(cmakeCmd)
@ -133,10 +127,10 @@ def runTest(args, buildDir, xmlOutput, testRunName):
if args is None: if args is None:
args = '' args = ''
fmt = '{buildDir}/{DEFAULT_EXE} -o {xmlOutput} -n "{testRunName}" -r junit "{args}"' testCommand = '{} -o {} -n "{}" -r junit "{}"'.format(TEST_EXE_PATH, xmlOutput, testRunName, args)
testCommand = fmt.format(**locals())
runCommand(testCommand, runCommand(testCommand,
assertOnFailure=False) abortOnFailure=False)
def validateTestSuite(xmlOutput): def validateTestSuite(xmlOutput):
@ -296,8 +290,7 @@ def executeJobs(jobs):
def computeAllTestNames(buildDir): def computeAllTestNames(buildDir):
'''Compute all test case names, by executing the unittest in a custom mode''' '''Compute all test case names, by executing the unittest in a custom mode'''
executable = os.path.join(buildDir, DEFAULT_EXE) cmd = '"{}" --list-test-names-only'.format(TEST_EXE_PATH)
cmd = '"{}" --list-test-names-only'.format(executable)
names = os.popen(cmd).read().splitlines() names = os.popen(cmd).read().splitlines()
names.sort() # Sort test names for execution determinism names.sort() # Sort test names for execution determinism
return names return names
@ -344,7 +337,7 @@ def generateXmlOutput(results, xmlOutput, testRunName, runTime):
}) })
systemOut = ET.Element('system-out') systemOut = ET.Element('system-out')
systemOut.text = result['output'].decode('utf-8') systemOut.text = result['output'].decode('utf-8', 'ignore')
testCase.append(systemOut) testCase.append(systemOut)
if not result['success']: if not result['success']:
@ -365,16 +358,19 @@ def run(testName, buildDir, sanitizer, xmlOutput, testRunName, buildOnly, useLLD
runCMake(sanitizer, buildDir) runCMake(sanitizer, buildDir)
# build with make # build with make
makeCmd = 'make' #makeCmd = 'cmake --build '
jobs = '-j8' #jobs = '-j8'
if platform.system() == 'Windows': #if platform.system() == 'Windows':
makeCmd = 'nmake' # makeCmd = 'nmake'
# nmake does not have a -j option # nmake does not have a -j option
jobs = '' # jobs = ''
runCommand('{} -C {} {}'.format(makeCmd, buildDir, jobs)) #runCommand('{} -C {} {}'.format(makeCmd, buildDir, jobs))
# build with cmake
runCommand('cmake --build ' + buildDir)
if buildOnly: if buildOnly:
return return
@ -409,12 +405,7 @@ def run(testName, buildDir, sanitizer, xmlOutput, testRunName, buildOnly, useLLD
continue continue
# testName can contains spaces, so we enclose them in double quotes # testName can contains spaces, so we enclose them in double quotes
executable = os.path.join(buildDir, DEFAULT_EXE) cmd = '{} "{}" "{}" > "{}" 2>&1'.format(lldb, TEST_EXE_PATH, testName, outputPath)
if platform.system() == 'Windows':
executable += '.exe'
cmd = '{} "{}" "{}" > "{}" 2>&1'.format(lldb, executable, testName, outputPath)
jobs.append({ jobs.append({
'name': testName, 'name': testName,
@ -454,8 +445,6 @@ def main():
if not os.path.exists(buildDir): if not os.path.exists(buildDir):
os.makedirs(buildDir) os.makedirs(buildDir)
defaultOutput = DEFAULT_EXE + '.xml'
parser = argparse.ArgumentParser(description='Build and Run the engine unittest') parser = argparse.ArgumentParser(description='Build and Run the engine unittest')
sanitizers = ['tsan', 'asan', 'ubsan', 'none'] sanitizers = ['tsan', 'asan', 'ubsan', 'none']
@ -481,14 +470,29 @@ def main():
# Default sanitizer is tsan # Default sanitizer is tsan
sanitizer = args.sanitizer sanitizer = args.sanitizer
if args.sanitizer is None:
if args.no_sanitizer:
sanitizer = 'none'
elif args.sanitizer is None:
sanitizer = 'tsan' sanitizer = 'tsan'
# Sanitizers display lots of strange errors on Linux on CI,
# which looks like false positives
if platform.system() != 'Darwin':
sanitizer = 'none'
defaultRunName = 'ixengine_{}_{}'.format(platform.system(), sanitizer) defaultRunName = 'ixengine_{}_{}'.format(platform.system(), sanitizer)
xmlOutput = args.output or defaultOutput xmlOutput = args.output or XML_OUTPUT_FILE
testRunName = args.run_name or os.getenv('IXENGINE_TEST_RUN_NAME') or defaultRunName testRunName = args.run_name or os.getenv('IXENGINE_TEST_RUN_NAME') or defaultRunName
global TEST_EXE_PATH
if platform.system() == 'Windows':
TEST_EXE_PATH = os.path.join(buildDir, BUILD_TYPE, 'ixwebsocket_unittest.exe')
else:
TEST_EXE_PATH = os.path.join(buildDir, 'ixwebsocket_unittest')
if args.list: if args.list:
# catch2 exit with a different error code when requesting the list of files # catch2 exit with a different error code when requesting the list of files
try: try:
@ -505,11 +509,6 @@ def main():
print('LLDB is only supported on Apple at this point') print('LLDB is only supported on Apple at this point')
args.lldb = False args.lldb = False
# Sanitizers display lots of strange errors on Linux on CI,
# which looks like false positives
if platform.system() != 'Darwin':
sanitizer = 'none'
return run(args.test, buildDir, sanitizer, xmlOutput, return run(args.test, buildDir, sanitizer, xmlOutput,
testRunName, args.build_only, args.lldb) testRunName, args.build_only, args.lldb)