# -*- 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','artifacts','core')
env = env.Clone()
env.Append(CPPPATH='include')  # additional headers for tests



def testExecutable(env,tree, exeName=None, obj=None):
    """ declare all targets needed to create a standalone
        Test executable of the given Sub-tree.
        @note this tree uses separate Environment/Includepath
    """
    env = env.Clone()
    env.Append(CPPPATH=tree) # add subdir to Includepath 
    tree = env.subst(tree)  # expand Construction Vars
    if obj:
        obj = [path.join(tree,name) for name in obj]
    else:
        obj = srcSubtree(tree) # use all sourcefiles found in subtree
    if not exeName:
        exeName = 'test-%s' % tree
    return env.Program(exeName, obj + core)


def testCollection(env,dir):
    """ treat a Directory containing a collection of standalone tests.
        Link each of them into an independent executable
    """
    env = env.Clone()
    env.Append(CPPPATH=dir) # add subdir to Includepath 
    srcpatt = ['test-*.c']
    exeName = lambda p: path.basename(path.splitext(p)[0])
    buildIt = lambda p: env.Program(exeName(p), [p] + core)
    return [buildIt(f) for f in scanSubtree(dir,srcpatt)] 





# but have to treat some subdirs individually.
specials = ['plugin','lib','components']
moduledirs = globRootdirs('*')



artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['lib','components'] ]
                              + [ testCollection(env, dir) for dir in moduledirs if not dir in specials]
                              + createPlugins(env, 'plugin')
                              + env.File(glob('*.tests'))     # depending on the test definition files for test.sh
                              + artifacts['config']
                              )




# for creating a Valgrind-Suppression file
vgsuppr = env.Program('vgsuppression','tool/vgsuppression.c', LIBS=core)   ## for suppressing false valgrind alarms
artifacts['tools'] += [vgsuppr]
Depends(ts,vgsuppr)


#
# actually run the Testsuite
#
#  - the product of running the Testsuite is the ",testlog"
#  - it depends on all artifacts defined as "ts" above
#  - including the tests/*.tests (suite definition files)
#  - if not set via options switch, the environment variables
#    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' : './'
                     })

testsuites = env['TESTSUITES'] or os.environ.get('TESTSUITES')
if testsuites:
    testEnv['ENV']['TESTSUITES'] = testsuites
    
pluginpath = os.environ.get('LUMIERA_PLUGIN_PATH')
if testsuites:
    testEnv['ENV']['LUMIERA_PLUGIN_PATH'] = pluginpath

# specify path to test.conf
testEnv['ENV']['TEST_CONF'] = env.File("test.conf").abspath


testDir = env.Dir('#$TARGDIR')
runTest = env.File("test.sh").abspath

runTs = testEnv.Command('#$TARGDIR/,testlog', ts, runTest,  chdir=testDir)



#
# define Phony targets
#  - 'scons testcode' triggers building of the Testsuite
#  - 'scons check' triggers building and running
#
env.Alias('testcode', ts )
env.Alias('check', runTs )

# allow tempfiles of test.sh to be cleaned  
env.Clean ('check', [',testlog',',testlog.pre',',expect_stdout',',stdout',',stderr',',testtmp','.libs'])
