# -*- 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 vault_lib guimodule 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('vault'): return vault_lib # tests in 'vault*' subdirs only linked against vault layer elif id.startswith('stage'): return guimodule+core_lib # tests in 'stage*' are additionally linked against the GTK GUI module 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 if dir.startswith('stage'): # additional libs used from GUI tests env.mergeConf(['sigc++-2.0']) # 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, addLibs=linkContext(dir)) # note: linking dependencies according to application layers # 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 # Specific linker treatment for the testsuite: # force explicit linking against all dependencies to ensure auto-registration of # any test-class on startup, even if no code dependency is visible for the linker envSuite = env.Clone() envSuite.Append(LINKFLAGS='-Wl,--no-as-needed') # 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 = envSuite.Program("test-suite", ["testrunner.cpp"]+list(testLibs)+list(core_lib)) testsuite = ( testcases + testrunner + createPlugins(env, 'plugin', addLibs=core_lib) + env.File(glob('*.tests')) # depend explicitly on the test definition files for test.sh + config ) Export('testsuite') # for creating a Valgrind-Suppression file vgsuppression = envSuite.Program('vgsuppression',['tool/vgsuppression.c']+list(testLibs)+list(core_lib)) ## for suppressing false valgrind alarms tools += [vgsuppression] # # 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') propagateSetting(testEnv, 'HOME') testDir = env.Dir('#$TARGDIR') runTest = env.File("test.sh").abspath runTests = testEnv.Command('#$TARGDIR/,testlog', testsuite, runTest, chdir=testDir) Depends(runTests,vgsuppression) # # 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'])