Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collect build/test timing information and fix some bugs #1020

Merged
merged 15 commits into from
Apr 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 27 additions & 16 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,14 @@ jobs:
- name: Upgrade pip
run: python3 -m pip install -U pip setuptools wheel
- name: Install Python dependencies
run: python3 -m pip install ruamel.yaml scons numpy cython h5py pandas
run: python3 -m pip install ruamel.yaml scons numpy cython h5py pandas pytest
pytest-github-actions-annotate-failures
- name: Build Cantera
run: python3 `which scons` build -j2 debug=n
run: python3 `which scons` build env_vars=all -j2 debug=n --debug=time
- name: Test Cantera
run: python3 `which scons` test
run: python3 `which scons` test --debug=time
env:
GITHUB_ACTIONS: "true"

macos-multiple-pythons:
name: macOS with Python ${{ matrix.python-version }}
Expand Down Expand Up @@ -75,11 +78,14 @@ jobs:
- name: Upgrade pip
run: python3 -m pip install -U pip 'setuptools>=47.0.0,<48' wheel
- name: Install Python dependencies
run: python3 -m pip install ruamel.yaml scons numpy cython h5py pandas
run: python3 -m pip install ruamel.yaml scons numpy cython h5py pandas pytest
pytest-github-actions-annotate-failures
- name: Build Cantera
run: python3 `which scons` build -j2 debug=n
run: python3 `which scons` build env_vars=all -j3 debug=n --debug=time
- name: Test Cantera
run: python3 `which scons` test
run: python3 `which scons` test --debug=time
env:
GITHUB_ACTIONS: "true"

# Coverage is its own job because macOS builds of the samples
# use Homebrew gfortran which is not compatible for coverage
Expand All @@ -88,7 +94,6 @@ jobs:
coverage:
name: Coverage
runs-on: ubuntu-latest
needs: [ubuntu-multiple-pythons]
steps:
- uses: actions/checkout@v2
name: Checkout the repository
Expand All @@ -105,13 +110,16 @@ jobs:
- name: Upgrade pip
run: python3 -m pip install -U pip setuptools wheel
- name: Install Python dependencies
run: python3 -m pip install ruamel.yaml scons numpy cython h5py pandas
run: python3 -m pip install ruamel.yaml scons numpy cython h5py pandas pytest
pytest-github-actions-annotate-failures
- name: Build Cantera
run: |
python3 `which scons` build blas_lapack_libs=lapack,blas coverage=y \
optimize=n no_optimize_flags=-DNDEBUG -j2
optimize=n no_optimize_flags=-DNDEBUG env_vars=all -j2 --debug=time
- name: Test Cantera
run: python3 `which scons` test
run: python3 `which scons` test --debug=time
env:
GITHUB_ACTIONS: "true"
- name: Upload Coverage to Codecov
run: bash <(curl -s https://codecov.io/bash)
env:
Expand Down Expand Up @@ -180,7 +188,8 @@ jobs:
python3-ruamel.yaml python-numpy cython3 libsundials-dev liblapack-dev \
libblas-dev
- name: Build Cantera
run: scons build python_cmd=/usr/bin/python3 blas_lapack_libs=lapack,blas -j2 debug=n
run: scons build python_cmd=/usr/bin/python3 blas_lapack_libs=lapack,blas -j2
debug=n --debug=time
- name: Test Cantera
run: scons test

Expand Down Expand Up @@ -326,7 +335,7 @@ jobs:
- name: Install Python dependencies
run: |
python -m pip install -U pip 'setuptools>=47.0.0,<48'
python -m pip install scons pypiwin32 numpy ruamel.yaml cython h5py pandas
python -m pip install scons pypiwin32 numpy ruamel.yaml cython h5py pandas pytest pytest-github-actions-annotate-failures
- name: Restore Boost cache
uses: actions/cache@v2
id: cache-boost
Expand All @@ -345,9 +354,11 @@ jobs:
rm $BOOST_ROOT/download.7z
shell: bash
- name: Build Cantera
run: |
scons build -j2 boost_inc_dir=%BOOST_ROOT% debug=n VERBOSE=y python_package=full ^
msvc_version=${{ matrix.vs-toolset }} f90_interface=n
run: scons build -j2 boost_inc_dir=%BOOST_ROOT% debug=n VERBOSE=y
python_package=full env_vars=PYTHONPATH,GITHUB_ACTIONS
msvc_version=${{ matrix.vs-toolset }} f90_interface=n --debug=time
shell: cmd
- name: Test Cantera
run: scons test
run: scons test --debug=time
env:
GITHUB_ACTIONS: "true"
2 changes: 2 additions & 0 deletions interfaces/cython/cantera/onedim.py
Original file line number Diff line number Diff line change
Expand Up @@ -1613,6 +1613,8 @@ def set_initial_guess(self, data=None, group=None):
`FlameBase.set_initial_guess`).
"""
super().set_initial_guess(data=data, group=group)
if data:
return

Yu = self.reactants.Y
Tu = self.reactants.T
Expand Down
2 changes: 1 addition & 1 deletion interfaces/cython/cantera/test/test_onedim.py
Original file line number Diff line number Diff line change
Expand Up @@ -823,7 +823,7 @@ def time_step_func(dt):

def run_extinction(self, mdot_fuel, mdot_ox, T_ox, width, P):
self.create_sim(fuel='H2:1.0', oxidizer='O2:1.0', p=ct.one_atm*P,
mdot_fuel=mdot_fuel, mdot_ox=mdot_ox, width=width)
mdot_fuel=mdot_fuel, mdot_ox=mdot_ox, T_ox=T_ox, width=width)
self.sim.solve(loglevel=0, auto=True)
self.assertFalse(self.sim.extinct())

Expand Down
2 changes: 2 additions & 0 deletions interfaces/cython/cantera/test/test_reactor.py
Original file line number Diff line number Diff line change
Expand Up @@ -1442,6 +1442,8 @@ def calc_dtdh(self, species):
dtdp = ((t[-1] - tig)*S[-1,:]*Tf - np.trapz(S*T[:,None], t, axis=0))/(Tf-To)
return dtdp

# See https://github.com/Cantera/enhancements/issues/55
@unittest.skip("Integration of sensitivity ODEs is unreliable")
def test_ignition_delay_sensitivity(self):
species = ('H2', 'H', 'O2', 'H2O2', 'H2O', 'OH', 'HO2')
dtigdh_cvodes = self.calc_dtdh(species)
Expand Down
4 changes: 3 additions & 1 deletion interfaces/cython/cantera/test/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def setUpClass(cls):
'..', '..', '..', '..'))
if os.path.exists(os.path.join(root_dir, 'SConstruct')):
cls.test_work_dir = os.path.join(root_dir, 'test', 'work', 'python')
cls.using_tempfile = False
try:
os.makedirs(cls.test_work_dir)
except OSError as e:
Expand All @@ -31,6 +32,7 @@ def setUpClass(cls):
raise
else:
cls.test_work_dir = tempfile.mkdtemp()
cls.using_tempfile = True

cantera.make_deprecation_warnings_fatal()
cantera.add_directory(cls.test_work_dir)
Expand All @@ -41,7 +43,7 @@ def setUpClass(cls):
@classmethod
def tearDownClass(cls):
# Remove the working directory after testing, but only if its a temp directory
if tempfile.tempdir is not None:
if getattr(cls, "using_tempfile", False):
try:
shutil.rmtree(cls.test_work_dir)
except OSError:
Expand Down
4 changes: 3 additions & 1 deletion src/base/AnyMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ bool isFloat(const std::string& val)
int numDot = 0;
int numExp = 0;
int istart = 0;
int numDigit = 0;
char ch = str[0];
if (ch == '+' || ch == '-') {
istart = 1;
Expand All @@ -49,6 +50,7 @@ bool isFloat(const std::string& val)
for (size_t i = istart; i < str.size(); i++) {
ch = str[i];
if (isdigit(ch)) {
numDigit++;
} else if (ch == '.') {
numDot++;
if (numDot > 1) {
Expand All @@ -59,7 +61,7 @@ bool isFloat(const std::string& val)
}
} else if (ch == 'e' || ch == 'E') {
numExp++;
if (numExp > 1 || i == str.size() - 1) {
if (numExp > 1 || numDigit == 0 || i == str.size() - 1) {
return false;
}
ch = str[i+1];
Expand Down
6 changes: 2 additions & 4 deletions src/base/units.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@
* Header for units conversion utilities, which are used to translate
* user input from input files (See \ref inputfiles and
* class \link Cantera::Unit Unit\endlink).
*
* This header is included only by file misc.cpp.
*/

// This file is part of Cantera. See License.txt in the top-level directory or
// at https://cantera.org/license.txt for license and copyright information.

#ifndef CT_UNITS_H
#define CT_UNITS_H
#ifndef CT_LEGACY_UNITS_H
#define CT_LEGACY_UNITS_H

#include "cantera/base/ct_defs.h"
#include "cantera/base/ctexceptions.h"
Expand Down
1 change: 1 addition & 0 deletions src/pch/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@

#include <boost/algorithm/string.hpp>
#include "cantera/base/fmt.h"
#include "cantera/base/AnyMap.h"

#endif
22 changes: 19 additions & 3 deletions test/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,18 @@ def addPythonTest(testname, subdir, script, interpreter, outfile,
Create targets for running and resetting a test script.
"""
def scriptRunner(target, source, env):
unittest_outfile = File("#test/work/python-results.txt").abspath
pytest_outfile = File("#test/work/pytest.xml").abspath
"""Scons Action to run a test script using the specified interpreter"""
workDir = Dir('#test/work').abspath
passedFile = target[0]
testResults.tests.pop(passedFile.name, None)
if not os.path.isdir(workDir):
os.mkdir(workDir)
if os.path.exists(outfile):
os.remove(outfile)
if os.path.exists(unittest_outfile):
os.remove(unittest_outfile)
if os.path.exists(pytest_outfile):
os.remove(pytest_outfile)

environ = dict(env['ENV'])
for k,v in env_vars.items():
Expand All @@ -145,7 +149,7 @@ def addPythonTest(testname, subdir, script, interpreter, outfile,
sys.exit(1)

failures = 0
if os.path.exists(outfile):
if os.path.exists(unittest_outfile):
# Determine individual test status
for line in open(outfile):
status, name = line.strip().split(': ', 1)
Expand All @@ -154,6 +158,18 @@ def addPythonTest(testname, subdir, script, interpreter, outfile,
elif status in ('FAIL', 'ERROR'):
testResults.failed[':'.join((testname,name))] = 1
failures += 1
elif os.path.exists(pytest_outfile):
results = ElementTree.parse(pytest_outfile)
for test in results.findall('.//testcase'):
class_name = test.get('classname')
if class_name.startswith("build.python.cantera.test."):
class_name = class_name[26:]
test_name = "python: {}.{}".format(class_name, test.get('name'))
if test.findall('failure'):
testResults.failed[test_name] = 1
failures += 1
else:
testResults.passed[test_name] = 1

if code and failures == 0:
# Failure, but unable to determine status of individual tests. This
Expand Down
64 changes: 39 additions & 25 deletions test/python/runCythonTests.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,16 @@

import sys
import os
from pathlib import Path

cantera_root = os.path.relpath(__file__).split(os.sep)[:-1] + ['..', '..']
module_path = os.path.abspath(os.sep.join(cantera_root + ['build']))

if 'PYTHONPATH' in os.environ:
os.environ['PYTHONPATH'] = module_path + os.path.pathsep + os.environ['PYTHONPATH']
else:
os.environ['PYTHONPATH'] = module_path

sys.path.insert(0, module_path)
os.chdir(os.sep.join(cantera_root + ['test', 'work']))

from cantera.test.utilities import unittest
import unittest
try:
import pytest
except ImportError:
pytest = None
import cantera
import cantera.test

Expand Down Expand Up @@ -77,19 +74,36 @@ def addError(self, test, err):
else:
fast_fail = False
subset_start = 1
loader = unittest.TestLoader()
runner = unittest.TextTestRunner(
verbosity=2, resultclass=TestResult, failfast=fast_fail
)
suite = unittest.TestSuite()
subsets = []
for name in sys.argv[subset_start:]:
subsets.append('cantera.test.test_' + name)

if not subsets:
subsets.append('cantera.test')

suite = loader.loadTestsFromNames(subsets)

results = runner.run(suite)
sys.exit(len(results.errors) + len(results.failures))

if pytest is not None:
base = Path(cantera.__file__).parent.joinpath('test')
subsets = []
for name in sys.argv[subset_start:]:
subsets.append(str(base.joinpath(f"test_{name}.py")))

if not subsets:
subsets.append(str(base))

pytest_args = ["-raP", "--durations=50", "--junitxml=pytest.xml"]
if fast_fail:
pytest_args.insert(0, "-x")

ret_code = pytest.main(pytest_args + subsets)
sys.exit(ret_code)
else:
loader = unittest.TestLoader()
runner = unittest.TextTestRunner(
verbosity=2, resultclass=TestResult, failfast=fast_fail
)
suite = unittest.TestSuite()
subsets = []
for name in sys.argv[subset_start:]:
subsets.append('cantera.test.test_' + name)

if not subsets:
subsets.append('cantera.test')

suite = loader.loadTestsFromNames(subsets)

results = runner.run(suite)
sys.exit(len(results.errors) + len(results.failures))