tests used to be defined ad hoc and test definitions are scattered confusingly over various directories. Now built some simple rules into the buildsystem to allow organising the tests into layers and linking them accordingly. Note: this switches to building shared objects for the test classes too, which effectively speeds up both re-building and re-running of test cases
138 lines
4.1 KiB
Python
138 lines
4.1 KiB
Python
# -*- python -*-
|
|
##
|
|
## SConscript - SCons buildscript for the Testsuite (called by SConstruct)
|
|
##
|
|
|
|
import os
|
|
from os import path
|
|
from glob import glob
|
|
|
|
from Buildhelper import srcSubtree
|
|
from Buildhelper import scanSubtree
|
|
from Buildhelper import globRootdirs
|
|
from Buildhelper import createPlugins
|
|
|
|
Import('env core_lib app_lib backend_lib tools config')
|
|
env = env.Clone()
|
|
env.Append(CPPPATH='include') # additional headers for tests
|
|
|
|
# test classes of subcomponents linked in shared objects
|
|
sharedTestLibs = {}
|
|
|
|
|
|
|
|
def linkContext(id):
|
|
if id.startswith('lib'):
|
|
return app_lib # tests in 'lib*' subdirs only linked against application framework
|
|
elif id.startswith('back'):
|
|
return backend_lib # tests in 'back*' subdirs only linked against backend layer
|
|
else:
|
|
return core_lib # all other tests linked against complete application core
|
|
|
|
|
|
def exeTestName(srcName):
|
|
name = path.basename(path.splitext(srcName)[0])
|
|
if not name.startswith('test-'):
|
|
name = 'test-'+name
|
|
return name
|
|
|
|
|
|
def testCases(env,dir):
|
|
""" visit a source subtree and declare all testcases.
|
|
Test classes will be linked into shared libraries,
|
|
while plain-C tests end up as standalone test-XXX.
|
|
@note: using the tree root as additional includepath
|
|
@note: linking scope chosen based on the name-prefix
|
|
"""
|
|
env = env.Clone()
|
|
env.Append(CPPPATH=dir) # add subdir to Includepath
|
|
|
|
# pick up all test classes and link them shared
|
|
testlib = []
|
|
testClasses = list(scanSubtree(dir,['*.cpp']))
|
|
if testClasses:
|
|
testlib = sharedTestLibs[dir] = env.SharedLibrary('test-'+dir, testClasses)
|
|
|
|
# pick up standalone plain-C tests
|
|
standaloneTests = list(scanSubtree(dir,['test-*.c']))
|
|
simpletests = [env.Program(exeTestName(p), [p]+linkContext(dir)) for p in standaloneTests]
|
|
|
|
return testlib + simpletests
|
|
|
|
|
|
|
|
|
|
# have to treat some subdirs separately.
|
|
specialDirs = ['plugin','tool','include']
|
|
testSrcDirs = globRootdirs('*')
|
|
|
|
|
|
testcases = [testCases(env, dir) for dir in testSrcDirs if not dir in specialDirs]
|
|
testLibs = sharedTestLibs.values()
|
|
testrunner = env.Program("test-suite", ["testrunner.cpp"]+testLibs+core_lib)
|
|
|
|
|
|
testsuite = ( testcases
|
|
+ testrunner
|
|
+ createPlugins(env, 'plugin')
|
|
+ env.File(glob('*.tests')) # depend explicitly on the test definition files for test.sh
|
|
+ config
|
|
)
|
|
Export('testsuite')
|
|
|
|
|
|
|
|
|
|
# for creating a Valgrind-Suppression file
|
|
vgsuppr = env.Program('vgsuppression',['tool/vgsuppression.c']+core_lib) ## for suppressing false valgrind alarms
|
|
tools += [vgsuppr]
|
|
Depends(testsuite,vgsuppr)
|
|
|
|
|
|
#
|
|
# actually run the Testsuite
|
|
#
|
|
# - the product of running the Testsuite is the ",testlog"
|
|
# - it depends on all artifacts defined as "testsuite" above
|
|
# - including the tests/*.tests (suite definition files)
|
|
# - if not set via options switch, the environment variables TESTMODE,
|
|
# TESTSUITES and VALGRINDFLAGS are explicitly propagated to test.sh
|
|
#
|
|
testEnv = env.Clone()
|
|
|
|
valgrind = os.environ.get('VALGRINDFLAGS', '') # unset if not defined
|
|
if not valgrind and not env['VALGRIND']:
|
|
valgrind = 'DISABLE'
|
|
|
|
testEnv.Append(ENV = { 'VALGRINDFLAGS' : valgrind
|
|
, 'LUMIERA_CONFIG_PATH' : './'
|
|
, 'TEST_CONF' : env.File("test.conf").abspath
|
|
})
|
|
|
|
def propagateSetting(env, key):
|
|
setting = key in env and env[key] or os.environ.get(key)
|
|
if setting:
|
|
env['ENV'][key] = setting
|
|
|
|
|
|
propagateSetting(testEnv, 'TESTSUITES')
|
|
propagateSetting(testEnv, 'TESTMODE')
|
|
propagateSetting(testEnv, 'LUMIERA_PLUGIN_PATH')
|
|
|
|
testDir = env.Dir('#$TARGDIR')
|
|
runTest = env.File("test.sh").abspath
|
|
|
|
runTests = testEnv.Command('#$TARGDIR/,testlog', testsuite, runTest, chdir=testDir)
|
|
|
|
|
|
|
|
#
|
|
# define Phony targets
|
|
# - 'scons testcode' triggers building of the Testsuite
|
|
# - 'scons check' triggers building and running
|
|
#
|
|
env.Alias('testcode', testsuite )
|
|
env.Alias('check', runTests )
|
|
|
|
# allow tempfiles of test.sh to be cleaned
|
|
env.Clean ('check', [',testlog',',testlog.pre',',expect_stdout',',stdout',',stderr',',testtmp','.libs'])
|