lumiera_documentation/tests/SConscript
Ichthyostega 3caa5cfb03 Tests: reorganise test folders
This resolves a long-standing issue:
we could not use proper include paths for test-helper code that was defined alongside the tests.

Since some test-helper code must now be relocated into the »Vault«-Layer,
I took the opportunity to finally resolve this annoyance. The solution is two-fold
 * introduce a dedicated test-support library
 * remove the quirks that were necessary to support some plain-C tests
Together, this allows to raise the include-directory by one level,
and then to adjust all folder names so that they match the namespace
2026-03-07 00:56:19 +01:00

151 lines
5 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 vessel_lib vault_lib test_support guimodule tools config')
env = env.Clone()
env.Append(CPPPATH='.') # tests/ rootdir (relevant for layer specific test support headers)
# test classes of subcomponents linked in shared objects
sharedTestLibs = {}
def linkContext(id):
if id.startswith('lib'):
return test_support + vessel_lib # tests in 'lib*' subdirs only linked with framework (including support-lib)
elif id.startswith('vessel'):
return test_support + vessel_lib # framework tests linked with framework and support-lib
elif id.startswith('vault'):
return test_support + vault_lib # tests in 'vault*' subdirs only linked against vault layer (including framework)
elif id.startswith('stage'):
return test_support + guimodule+core_lib # tests in 'stage*' are additionally linked against the GTK GUI module
else:
return test_support + 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()
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']
testSrcDirs = globRootdirs('*')
testcases = [testCases(env, dir) for dir in testSrcDirs if not dir in specialDirs]
testLibs = list(sharedTestLibs.values())
testrunner = envSuite.Program("test-suite", ["testrunner.cpp"]+testLibs+test_support+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']+testLibs+core_lib) ## for suppressing false valgrind alarms
#
# 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 Alias targets
# - 'scons testcode' triggers building of the Testsuite
# - 'scons check' triggers building and running
#
env.Alias('testcode', testsuite + vgsuppression)
env.Alias('check', runTests )
# allow tempfiles of test.sh to be cleaned
env.Clean ('check', [',testlog',',testlog.pre',',expect_stdout',',stdout',',stderr',',testtmp','.libs'])