run-tests.py 4.65 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
#!/usr/bin/python3
import os
import re
import sys
import time
import argparse
import subprocess
from helperslib import BuildSpecs, BuildSystem, CommonUtils, EnvironmentHandler

# Parse the command line arguments we've been given
parser = argparse.ArgumentParser(description='Utility to execute tests for a build.')
12
parser.add_argument('--product', type=str, required=True)
13 14 15 16 17 18 19
parser.add_argument('--project', type=str, required=True)
parser.add_argument('--branchGroup', type=str, required=True)
parser.add_argument('--platform', type=str, required=True)
parser.add_argument('--usingInstall', type=str, required=True)
arguments = parser.parse_args()

# Load our build specification, which governs how we handle this build
20
buildSpecification = BuildSpecs.Loader( product=arguments.product, project=arguments.project, branchGroup=arguments.branchGroup, platform=arguments.platform )
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38

# Determine the environment we need to provide for the installation process
buildEnvironment = EnvironmentHandler.generateFor( installPrefix=arguments.usingInstall )

# Determine where our source code is checked out to and where we will be building it
# We'll assume that the directory we're running from is where the sources are located
sourcesLocation = os.getcwd()
buildLocation = CommonUtils.buildDirectoryForSources( sources=sourcesLocation, inSourceBuild=buildSpecification['in-source-build'] )

# First Check: Is this a CMake project, and is testing enabled for it?
if not BuildSystem.CMake.canConfigure(sourcesLocation) or not buildSpecification['run-tests']:
	# We either can't test (not CMake) or tests are disabled, so nothing for us to do here!
	sys.exit(0)

# Get a count of the number of available tests
# This relies on the command "ctest -N" producing at least one line that matches "Total Tests: x" where x is the number of tests
process = subprocess.Popen( "ctest -N", stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, env=buildEnvironment, cwd=buildLocation)
stdout, stderr = process.communicate()
Ben Cooksley's avatar
Ben Cooksley committed
39
testsFound = int( re.search( b'Total Tests: ([0-9]+)', stdout, re.MULTILINE ).group(1) )
40 41 42 43 44 45 46 47

# If we had less than 1 test then there is nothing for us to do - bail
if testsFound == 0:
	sys.exit(0)

# Spawn a X windowing system if needed
# We'll also launch a Window Manager at the same time as some tests often need or unknowingly rely on one being present
# As X doesn't belong on Windows or OSX we don't run it there
Ben Cooksley's avatar
Ben Cooksley committed
48
if buildSpecification['setup-x-environment'] and ( sys.platform != 'win32' and sys.platform != 'darwin' ):
49 50 51 52 53 54 55 56 57 58 59
	# Setup Xvfb
	buildEnvironment['DISPLAY'] = ':90'
	commandToRun = "Xvfb :90 -ac -screen 0 1600x1200x24+32"
	xvfbProcess = subprocess.Popen( commandToRun, stdout=open(os.devnull, 'w'), stderr=subprocess.STDOUT, shell=True, env=buildEnvironment )

	# Startup a Window Manager
	commandToRun = "openbox"
	wmProcess = subprocess.Popen( commandToRun, stdout=open(os.devnull, 'w'), stderr=subprocess.STDOUT, shell=True, env=buildEnvironment )

# Spawn D-Bus if needed
# Same rules apply for X in regards to Windows and OSX - it doesn't belong so we don't support it
Ben Cooksley's avatar
Ben Cooksley committed
60
if buildSpecification['launch-dbus-session'] and ( sys.platform != 'win32' and sys.platform != 'darwin' ):
61
	# Determine the command to run, then launch it and wait for it to exit
62
	commandToRun = 'dbus-launch'
Ben Cooksley's avatar
Ben Cooksley committed
63
	process = subprocess.Popen( commandToRun, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=buildEnvironment )
64 65 66
	process.wait()
	# Determine what environment variables need to be set, and ensure those are included in our build environment
	for variable in process.stdout:
67 68
		variable  = str(variable, 'utf-8')
		splitVars = variable.split('=', 1)
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
		buildEnvironment[ splitVars[0] ] = splitVars[1].strip()

# As some of the above might still be getting themselves ready, wait for a few moments...
time.sleep( 5 )

# Now it's time to invoke CTest! Build up the command...
commandToRun = "ctest -T Test --output-on-failure --no-compress-output --timeout {0}"
commandToRun.format( buildSpecification['per-test-timeout'] )
# And run it!
ctestProcess = subprocess.Popen( commandToRun, stdout=sys.stdout, stderr=sys.stderr, shell=True, cwd=buildLocation, env=buildEnvironment )
ctestProcess.wait()

# Now that CTest is done, we convert it's output to JUnit format
junitOutput = BuildSystem.CMake.convertCTestResultsToJUnit( buildLocation )
junitFilename = os.path.join( sourcesLocation, 'JUnitTestResults.xml' )
with open(junitFilename, 'w') as junitFile:
	junitFile.write( str(junitOutput) )

# To ensure we don't hang, cleanup the Window Manager and X server if needed
Ben Cooksley's avatar
Ben Cooksley committed
88
if buildSpecification['setup-x-environment'] and ( sys.platform != 'win32' and sys.platform != 'darwin' ):
89 90 91 92 93
	wmProcess.terminate()
	xvfbProcess.terminate()

# All done!
sys.exit(0)