diff --git a/interfaces/cython/.gitignore b/interfaces/cython/.gitignore index f836ae32b..68d3fbce0 100644 --- a/interfaces/cython/.gitignore +++ b/interfaces/cython/.gitignore @@ -2,5 +2,12 @@ cantera/*.cpp cantera/*.c cantera/data/*.cti cantera/data/*.xml +cantera/test/data/*.cti +cantera/test/data/*.xml +cantera/test/data/*.inp +cantera/test/data/*.dat +cantera/test/data/*.csv setup2.py setup3.py +Cantera.egg-info +dist diff --git a/interfaces/cython/SConscript b/interfaces/cython/SConscript index 801dcaae3..9a23ba312 100644 --- a/interfaces/cython/SConscript +++ b/interfaces/cython/SConscript @@ -16,9 +16,13 @@ else: localenv['py_extra_compiler_args'] = repr([]) dataFiles = localenv.RecursiveInstall('#interfaces/cython/cantera/data', - '#data/inputs', ['\\.inp$', '\\.in$']) + '#build/data') build(dataFiles) +testFiles = localenv.RecursiveInstall('#interfaces/cython/cantera/test/data', + '#test/data') +build(testFiles) + if localenv['python3_package'] == 'y': info = getCommandOutput(localenv['python3_cmd'], '-c', '\n'.join(("from distutils.sysconfig import *", @@ -44,11 +48,14 @@ if localenv['python3_package'] == 'y': mod = build(localenv.Command('#build/python3/cantera/_cantera%s' % module_ext, 'setup3.py', build_cmd)) + env['python3_module'] = mod localenv.AddPreAction(mod, Delete('interfaces/cython/cantera/_cantera.cpp')) localenv.Depends(mod, localenv['cantera_staticlib']) - for f in mglob(localenv, 'cantera', 'pyx', 'pxd'): + localenv.Depends(mod, dataFiles + testFiles) + for f in (mglob(localenv, 'cantera', 'pyx', 'pxd') + + mglob(localenv, 'cantera/test', 'py')): localenv.Depends(mod, f) # Install the Python module @@ -97,11 +104,14 @@ if localenv['python_package'] == 'new': mod = build(localenv.Command('#build/python2/cantera/_cantera%s' % module_ext, 'setup2.py', build_cmd)) + env['python2_module'] = mod localenv.AddPreAction(mod, Delete('interfaces/cython/cantera/_cantera.cpp')) localenv.Depends(mod, localenv['cantera_staticlib']) - for f in mglob(localenv, 'cantera', 'pyx', 'pxd'): + localenv.Depends(mod, dataFiles + testFiles) + for f in (mglob(localenv, 'cantera', 'pyx', 'pxd') + + mglob(localenv, 'cantera/test', 'py')): localenv.Depends(mod, f) # Install the Python module diff --git a/interfaces/cython/cantera/test/__init__.py b/interfaces/cython/cantera/test/__init__.py index 398fd69bd..75b2fcc80 100644 --- a/interfaces/cython/cantera/test/__init__.py +++ b/interfaces/cython/cantera/test/__init__.py @@ -1,3 +1,8 @@ +import os +import cantera + +cantera.addDirectory(os.path.dirname(__file__)) + from .test_thermo import * from .test_purefluid import * from .test_kinetics import * diff --git a/interfaces/cython/cantera/test/data/__init__.py b/interfaces/cython/cantera/test/data/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/interfaces/cython/cantera/test/test_purefluid.py b/interfaces/cython/cantera/test/test_purefluid.py index 8c8a08ca6..2f9dba0dd 100644 --- a/interfaces/cython/cantera/test/test_purefluid.py +++ b/interfaces/cython/cantera/test/test_purefluid.py @@ -11,10 +11,10 @@ class TestPureFluid(utilities.CanteraTest): self.assertNear(self.water.critDensity, 317.0) def test_setState(self): - self.water._setState_Psat(101325, 0.5) - self.assertNear(self.water.pressure, 101325) - self.assertNear(self.water.vaporFraction, 0.5) + self.water.PX = 101325, 0.5 + self.assertNear(self.water.P, 101325) + self.assertNear(self.water.X, 0.5) - self.water._setState_Tsat(500, 0.8) - self.assertNear(self.water.temperature, 500) - self.assertNear(self.water.vaporFraction, 0.8) + self.water.TX = 500, 0.8 + self.assertNear(self.water.T, 500) + self.assertNear(self.water.X, 0.8) diff --git a/interfaces/cython/cantera/test/test_reactor.py b/interfaces/cython/cantera/test/test_reactor.py index 31036360e..e80718535 100644 --- a/interfaces/cython/cantera/test/test_reactor.py +++ b/interfaces/cython/cantera/test/test_reactor.py @@ -10,16 +10,14 @@ class TestReactor(utilities.CanteraTest): self.gas2 = ct.Solution('h2o2.xml') X = np.zeros(self.gas1.nSpecies) X[3] = 1.0 - self.gas2.setMoleFractions(X) + self.gas2.X = X self.r1 = ct.Reactor(self.gas1) self.r2 = ct.Reactor(self.gas2) def test_disjoint(self): - T1 = self.gas1.temperature - T2 = self.gas2.temperature - P1 = self.gas1.pressure - P2 = self.gas2.pressure + T1,P1 = self.gas1.TP + T2,P2 = self.gas2.TP net = ct.ReactorNet() net.addReactor(self.r1) @@ -27,10 +25,10 @@ class TestReactor(utilities.CanteraTest): net.advance(1.0) # Nothing should change from the initial condition - self.assertNear(T1, self.gas1.temperature) - self.assertNear(T2, self.gas2.temperature) - self.assertNear(P1, self.gas1.pressure) - self.assertNear(P2, self.gas2.pressure) + self.assertNear(T1, self.gas1.T) + self.assertNear(T2, self.gas2.T) + self.assertNear(P1, self.gas1.P) + self.assertNear(P2, self.gas2.P) def test_equalizePressure(self): w = ct.Wall() @@ -43,4 +41,4 @@ class TestReactor(utilities.CanteraTest): net.addReactor(self.r2) net.advance(1.0) - self.assertNear(self.gas1.pressure, self.gas2.pressure) + self.assertNear(self.gas1.P, self.gas2.P) diff --git a/interfaces/cython/cantera/test/test_thermo.py b/interfaces/cython/cantera/test/test_thermo.py index 215a8afc8..bac82a407 100644 --- a/interfaces/cython/cantera/test/test_thermo.py +++ b/interfaces/cython/cantera/test/test_thermo.py @@ -14,19 +14,20 @@ class TestThermoPhase(utilities.CanteraTest): def test_setComposition(self): X = np.zeros(self.phase.nSpecies) X[2] = 1.0 - self.phase.setMoleFractions(X) - Y = self.phase.massFractions + self.phase.X = X + Y = self.phase.Y self.assertEqual(list(X), list(Y)) def test_badLength(self): X = np.zeros(5) with self.assertRaises(ValueError): - self.phase.setMoleFractions(X) + self.phase.X = X + def test_getState(self): - self.assertNear(self.phase.pressure, ct.OneAtm) - self.assertNear(self.phase.temperature, 300) + self.assertNear(self.phase.P, ct.OneAtm) + self.assertNear(self.phase.T, 300) class TestInterfacePhase(utilities.CanteraTest): @@ -38,4 +39,4 @@ class TestInterfacePhase(utilities.CanteraTest): def test_properties(self): self.interface.siteDensity = 100 - self.assertEqual(self.interface.siteDensity, 100) \ No newline at end of file + self.assertEqual(self.interface.siteDensity, 100) diff --git a/interfaces/cython/setup.py.in b/interfaces/cython/setup.py.in index 9bc9ea7ce..a43896e3d 100644 --- a/interfaces/cython/setup.py.in +++ b/interfaces/cython/setup.py.in @@ -22,4 +22,5 @@ setup(name="Cantera", packages = find_packages(), cmdclass = {'build_ext': build_ext}, ext_modules = exts, - package_data = {'cantera.data': ['*.xml', '*.cti']}) + package_data = {'cantera.data': ['*.*'], + 'cantera.test.data': ['*.*']}) diff --git a/test/SConscript b/test/SConscript index e4bd48ce6..67fd227aa 100644 --- a/test/SConscript +++ b/test/SConscript @@ -51,7 +51,7 @@ def addTestProgram(subdir, progName): [], [Delete(passedFile.abspath)])) -def addTestScript(subdir, script, interpreter, dependencies): +def addTestScript(testname, subdir, script, interpreter, dependencies=(), env_vars={}): """ Create targets for running and resetting a test script. """ @@ -63,8 +63,12 @@ def addTestScript(subdir, script, interpreter, dependencies): if not os.path.isdir(workDir): os.mkdir(workDir) - code = subprocess.call([interpreter, source[0].abspath], - env=env['ENV'], + environ = dict(env['ENV']) + for k,v in env_vars.iteritems(): + print k,v + environ[k] = v + code = subprocess.call([env.subst(interpreter), source[0].abspath], + env=environ, cwd=workDir) if not code: # Test was successful @@ -75,7 +79,7 @@ def addTestScript(subdir, script, interpreter, dependencies): testenv = localenv.Clone() - passedFile = File(pjoin(subdir, '%s.passed' % (script))) + passedFile = File(pjoin(subdir, '%s.passed' % testname)) testResults.tests[passedFile.name] = True run_program = testenv.Command(passedFile, pjoin(subdir, script), scriptRunner) for dep in dependencies: @@ -84,7 +88,7 @@ def addTestScript(subdir, script, interpreter, dependencies): testenv.Depends(run_program, dep) Alias('test', run_program) if os.path.exists(passedFile.abspath): - Alias('test-reset', testenv.Command('reset-%s%s' % (subdir, script), + Alias('test-reset', testenv.Command('reset-%s%s' % (subdir, testname), [], [Delete(passedFile.abspath)])) return run_program @@ -144,12 +148,30 @@ addTestProgram('thermo', 'thermo') addTestProgram('kinetics', 'kinetics') if localenv['python_package'] == 'full': - pyTest = addTestScript('python', 'runTests.py', - interpreter=sys.executable, + pyTest = addTestScript('python2-old', 'python', 'runTests.py', + interpreter='$python_cmd', dependencies=(mglob(localenv, 'python', 'py') + localenv['python_module'])) localenv.Alias('test-python', pyTest) env['testNames'].append('python') +elif localenv['python_package'] == 'new': + pyTest = addTestScript('python2-new', 'python', 'runCythonTests.py', + interpreter='$python_cmd', + dependencies=(localenv['python2_module'] + + mglob(localenv, '#interfaces/cython/cantera/test', 'py')), + env_vars={'PYTHONPATH':Dir('#build/python2').abspath}) + localenv.Alias('test-cython2', pyTest) + env['testNames'].append('cython2') + +if localenv['python3_package'] == 'y': + pyTest = addTestScript('python3-new', 'python', 'runCythonTests.py', + interpreter='$python3_cmd', + dependencies=(localenv['python3_module'] + + mglob(localenv, '#interfaces/cython/cantera/test', 'py')), + env_vars={'PYTHONPATH':Dir('#build/python3').abspath}) + localenv.Alias('test-cython3', pyTest) + env['testNames'].append('cython3') + if localenv['matlab_toolbox'] == 'y': matlabTest = addMatlabTest('runCanteraTests.m', diff --git a/test/python/runCythonTests.py b/test/python/runCythonTests.py new file mode 100644 index 000000000..b342a16eb --- /dev/null +++ b/test/python/runCythonTests.py @@ -0,0 +1,31 @@ +""" +Unit tests for Cantera's Cython-based Python module. + +This script gathers all the tests defined 'cantera.test' module, runs them, +and prints a report. +""" +from __future__ import print_function + +import sys +import os + +cantera_root = os.getcwd().split(os.sep)[:-2] +if sys.version_info.major == 3: + sys.path.insert(0, os.sep.join(cantera_root + ['build', 'python3'])) +else: + sys.path.insert(0, os.sep.join(cantera_root + ['build', 'python2'])) + +import unittest +import cantera + +if __name__ == '__main__': + print('\n* INFO: using Cantera module found at this location:') + print('* ', repr(cantera.__file__), '\n') + sys.stdout.flush() + + loader = unittest.TestLoader() + runner = unittest.TextTestRunner(verbosity=2) + suite = loader.loadTestsFromName('cantera.test') + + results = runner.run(suite) + sys.exit(len(results.errors) + len(results.failures))