from buildutils import * Import('env','build','install') localenv = env.Clone() localenv.Prepend(CPPPATH=['#include', '#src', 'shared']) localenv.Append(CCFLAGS=env['warning_flags']) # Turn off optimization to speed up compilation ccflags = localenv['CCFLAGS'] for optimize_flag in ('-O3', '-O2', '/O2'): if optimize_flag in ccflags: ccflags.remove(optimize_flag) localenv['CCFLAGS'] = ccflags # Where possible, link tests against the shared libraries to minimize the sizes # of the resulting binaries. if localenv['OS'] == 'Linux': cantera_libs = localenv['cantera_shared_libs'] else: cantera_libs = localenv['cantera_libs'] if localenv['python_package'] in ('full', 'minimal'): localenv['ENV']['PYTHONPATH'] = localenv['pythonpath_build2'] localenv['ENV']['PYTHON_CMD'] = localenv.subst('$python_cmd') haveConverters = True elif localenv['python3_package'] == 'y': localenv['ENV']['PYTHONPATH'] = localenv['pythonpath_build3'] localenv['ENV']['PYTHON_CMD'] = localenv.subst('$python3_cmd') haveConverters = True else: haveConverters = False localenv['ENV']['CANTERA_DATA'] = pjoin(os.getcwd(), '..', 'build', 'data') # Add build/lib in order to find Cantera shared library if localenv['ENV'].get('LD_LIBRARY_PATH'): localenv['ENV']['LD_LIBRARY_PATH'] += os.pathsep + Dir('#build/lib').abspath else: localenv['ENV']['LD_LIBRARY_PATH'] = Dir('#build/lib').abspath PASSED_FILES = {} class Test(object): _validArgs = set(['arguments', 'options', 'artifacts', 'comparisons', 'tolerance', 'threshold', 'ignoreLines', 'extensions', 'dependencies']) def __init__(self, testName, subdir, programName, blessedName, **kwargs): assert set(kwargs.keys()) <= self._validArgs, kwargs.keys() self.subdir = subdir self.programName = programName arguments = kwargs.get('arguments') or [] if isinstance(arguments, str): arguments = [arguments] self.arguments = arguments # file arguments self.options = kwargs.get('options') or '' self.blessedName = blessedName self.artifacts = kwargs.get('artifacts') or () if isinstance(self.artifacts, str): self.artifacts = [self.artifacts] self.comparisons = kwargs.get('comparisons') or () self.tolerance = kwargs.get('tolerance') or 1e-5 # error tolerance for CSV comparison self.threshold = kwargs.get('threshold') or 1e-14 # error threshold for CSV comparison # ignore lines starting with specified strings when comparing output files self.ignoreLines = kwargs.get('ignoreLines') or [] self.testName = testName self.passedFile = '.passed-%s' % testName PASSED_FILES[self.testName] = pjoin(self.subdir, self.passedFile) testResults.tests[self.testName] = self run = self.run(localenv) localenv.Depends(env['test_results'], run) localenv.Alias('test-clean', self.clean(localenv)) localenv.Alias('test-%s' % self.testName, run) env['testNames'].append(self.testName) # reset: just delete the ".passed" file so that this test will be re-run localenv.Alias('test-reset', self.reset(localenv)) for dep in kwargs.get('dependencies', []): localenv.Depends(run, dep) env.Depends(run, localenv.get('cantera_shlib', ())) def run(self, env, *args): source = list(args) if not source: source.append(self.programName) source.extend(pjoin(self.subdir, arg) for arg in self.arguments) test = env.RegressionTest(pjoin(self.subdir, self.passedFile), source, active_test_name=self.testName, test_blessed_file=self.blessedName, test_command_options=self.options, test_comparisons=self.comparisons, test_csv_threshold=self.threshold, test_csv_tolerance=self.tolerance, test_ignoreLines=self.ignoreLines) return test def reset(self, env, **kwargs): f = pjoin(os.getcwd(), self.subdir, self.passedFile) if os.path.exists(f): uniqueName = 'reset-%s' % self.testName target = env.Command(uniqueName, [], [Delete(f)]) return target def clean(self, env, **kwargs): # Name used for the output file if self.blessedName is not None and 'blessed' in self.blessedName: outName = self.blessedName.replace('blessed', 'output') else: outName = 'test_output.txt' files = kwargs.get('files') or [] files += [self.passedFile, outName] files += list(self.artifacts) files += [comp[1] for comp in self.comparisons] files = [pjoin(os.getcwd(), self.subdir, name) for name in files] uniqueName = 'clean-%s-' % self.testName target = env.Command(uniqueName, [], [Delete(f) for f in files if os.path.exists(f)]) return target class CompileAndTest(Test): def __init__(self, testName, subdir, programName, blessedName, **kwargs): self.extensions = kwargs.get('extensions') or ('cpp',) Test.__init__(self, testName, subdir, programName, blessedName, **kwargs) def run(self, env): prog = env.Program(pjoin(self.subdir, self.programName), mglob(env, self.subdir, *self.extensions), LIBS=cantera_libs) source = [prog] return Test.run(self, env, *source) def clean(self, env): files = [self.programName + ext for ext in ['', '.o', '.exe', '.exe.manifest', '.ilk', '.obj', '.pdb']] return Test.clean(self, env, files=files) dhGraph = localenv.Program('cathermo/DH_graph_1/DH_graph_1', mglob(env, 'cathermo/DH_graph_1', 'cpp'), LIBS=cantera_libs) dhGraph_name = dhGraph[0].name Test('DH_graph_dilute', 'cathermo/DH_graph_1', dhGraph, 'DH_NaCl_dilute_blessed.csv', artifacts=['DH_graph_1.log', dhGraph_name], arguments='DH_NaCl_dilute.xml') Test('DH_graph_acommon', 'cathermo/DH_graph_1', dhGraph, 'DH_NaCl_acommon_blessed.csv', artifacts=['DH_graph_1.log', dhGraph_name], arguments='DH_NaCl_acommon.xml') Test('DH_graph_bdotak', 'cathermo/DH_graph_1', dhGraph, 'DH_NaCl_bdotak_blessed.csv', artifacts=['DH_graph_1.log', dhGraph_name], arguments='DH_NaCl_bdotak.xml') Test('DH_graph_NM', 'cathermo/DH_graph_1', dhGraph, 'DH_NaCl_NM_blessed.csv', artifacts=['DH_graph_1.log', dhGraph_name], arguments='DH_NaCl_NM.xml') Test('DH_graph_Pitzer', 'cathermo/DH_graph_1', dhGraph, 'DH_NaCl_Pitzer_blessed.csv', artifacts=['DH_graph_1.log', dhGraph_name], arguments='DH_NaCl_Pitzer.xml') CompileAndTest('HMW_dupl_test', 'cathermo/HMW_dupl_test', 'HMW_dupl_test', 'output_blessed.txt', artifacts=['DH_graph_1.log'], arguments='HMW_NaCl_sp1977_alt.xml') CompileAndTest('HMW_graph_CpvT', 'cathermo/HMW_graph_CpvT', 'HMW_graph_CpvT', 'output_blessed.txt', extensions=['^HMW_graph_CpvT.cpp'], arguments='HMW_NaCl_sp1977_alt.xml') CompileAndTest('HMW_graph_GvI', 'cathermo/HMW_graph_GvI', 'HMW_graph_GvI', None, comparisons=[('T298_blessed.csv', 'T298.csv'), ('T523_blessed.csv', 'T523.csv')], artifacts=['T373.csv','T423.csv','T473.csv', 'T548.csv','T573.csv']) CompileAndTest('HMW_graph_GvT', 'cathermo/HMW_graph_GvT', 'HMW_graph_GvT', 'output_blessed.txt', extensions=['^HMW_graph_GvT.cpp'], arguments='HMW_NaCl_sp1977_alt.xml') CompileAndTest('HMW_graph_HvT', 'cathermo/HMW_graph_HvT', 'HMW_graph_HvT', 'output_blessed.txt', extensions=['^HMW_graph_HvT.cpp'], arguments='HMW_NaCl_sp1977_alt.xml') CompileAndTest('HMW_graph_VvT', 'cathermo/HMW_graph_VvT', 'HMW_graph_VvT', 'output_blessed.txt', extensions=['^HMW_graph_VvT.cpp'], arguments='HMW_NaCl_sp1977_alt.xml') CompileAndTest('HMW_test_1', 'cathermo/HMW_test_1', 'HMW_test_1', 'output_noD_blessed.txt') CompileAndTest('HMW_test_3', 'cathermo/HMW_test_3', 'HMW_test_3', 'output_noD_blessed.txt') CompileAndTest('IMSTester', 'cathermo/ims', 'IMSTester', 'output_blessed.txt') CompileAndTest('ISSPTester', 'cathermo/issp', 'ISSPTester', 'output_blessed.txt') CompileAndTest('stoichSub', 'cathermo/stoichSub', 'stoichSub', 'output_blessed.txt') CompileAndTest('IAPWSphi', 'cathermo/testIAPWS', 'testIAPWSphi', 'output_blessed.txt') CompileAndTest('IAPWSPres', 'cathermo/testIAPWSPres', 'testIAPWSPres', 'output_blessed.txt') CompileAndTest('IAPWSTripP', 'cathermo/testIAPWSTripP', 'testIAPWSTripP', 'output_blessed.txt') CompileAndTest('WaterPDSS', 'cathermo/testWaterPDSS', 'testWaterPDSS', 'output_blessed.txt') CompileAndTest('WaterSSTP', 'cathermo/testWaterTP', 'testWaterSSTP', 'output_blessed.txt') CompileAndTest('ISSPTester2', 'cathermo/VPissp', 'ISSPTester2', 'output_blessed.txt') CompileAndTest('wtWater', 'cathermo/wtWater', 'wtWater', 'output_blessed.txt') CompileAndTest('ChemEquil_ionizedGas', 'ChemEquil_ionizedGas', 'ionizedGasEquil', 'output_blessed.txt', comparisons=[('table_blessed.csv', 'table.csv')]) #CompileAndTest('CpJump', 'CpJump', 'CpJump', 'output_blessed.txt') CompileAndTest('cxx_ex', 'cxx_ex', 'cxx_examples', 'output_blessed.txt', comparisons=[('eq1_blessed.csv', 'eq1.csv'), ('kin1_blessed.csv', 'kin1.csv'), ('tr1_blessed.csv', 'tr1.csv'), ('tr2_blessed.csv', 'tr2.csv')], tolerance=3e-3, threshold=1e-7, artifacts=['eq1.dat', 'kin1.dat', 'kin2.dat', 'kin3.csv', 'kin3.dat', 'tr1.dat', 'tr2.dat']) diamond = localenv.Program('diamondSurf/runDiamond', 'diamondSurf/runDiamond.cpp', LIBS=cantera_libs) diamond_name = diamond[0].name Test('diamondSurf-xml', 'diamondSurf', diamond, 'runDiamond_blessed.out', options='diamond_blessed.xml', artifacts=diamond_name) if haveConverters: Test('diamondSurf-cti', 'diamondSurf', diamond, 'runDiamond_blessed.out', options='diamond.cti', artifacts=diamond_name) CompileAndTest('dustyGasTransport', 'dustyGasTransport', 'dustyGasTransport', 'output_blessed.txt') CompileAndTest('mixGasTransport', 'mixGasTransport', 'mixGasTransport', 'output_blessed.txt') CompileAndTest('multiGasTransport', 'multiGasTransport', 'multiGasTransport', 'output_blessed.txt') CompileAndTest('pureFluid', 'pureFluidTest', 'testPureWater', 'output_blessed.txt') if haveConverters: CompileAndTest('rankine_democxx', 'rankine_democxx', 'rankine', 'output_blessed.txt') CompileAndTest('silane_equil', 'silane_equil', 'silane_equi', 'output_blessed.txt') CompileAndTest('simpleTransport', 'simpleTransport', 'simpleTransport', 'output_blessed.txt') CompileAndTest('stoichSolidKinetics', 'stoichSolidKinetics', 'stoichSolidKinetics', 'output_blessed.txt') CompileAndTest('surfkin', 'surfkin', 'surfdemo', 'output_blessed.txt') CompileAndTest('surfSolver', 'surfSolverTest', 'surfaceSolver', None, arguments='haca2.xml', comparisons=[('results_blessed.txt', 'results.txt')], artifacts=['results.txt'], extensions=['^surfaceSolver.cpp']) CompileAndTest('surfSolver2', 'surfSolverTest', 'surfaceSolver2', None, arguments='haca2.xml', comparisons=[('results2_blessed.txt', 'results2.txt')], artifacts=['results2.txt'], extensions=['^surfaceSolver2.cpp']) CompileAndTest('VCS-NaCl', 'VCSnonideal/NaCl_equil', 'nacl_equil', 'good_out.txt', options='-d 3', artifacts=['vcs_equilibrate_res.csv']), # not testing this file because it's not really csv CompileAndTest('VCS-LiSi', 'VCSnonideal/LatticeSolid_LiSi', 'latticeSolid_LiSi', 'output_blessed.txt', artifacts=['vcs_equilibrate_res.csv']) CompileAndTest('VPsilane_test', 'VPsilane_test', 'VPsilane_test', 'output_blessed.txt') # Force explicitly-named tests to run even if SCons thinks they're up to date for command in COMMAND_LINE_TARGETS: if command.startswith('test-'): name = command[5:] if name in PASSED_FILES and os.path.exists(PASSED_FILES[name]): os.remove(PASSED_FILES[name])