diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 8fd6dde..64a97f6 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -13,13 +13,14 @@ env: CLAW: ${{ github.workspace }} jobs: - build: + test: runs-on: ubuntu-latest steps: - name: Set up Python 3.10 uses: actions/setup-python@v5 with: python-version: "3.10" + - name: Install dependencies run: | sudo apt-get update @@ -32,15 +33,16 @@ jobs: with: repository: clawpack/clawpack submodules: true + - name: Checkout classic branch uses: actions/checkout@v4.1.5 with: - repository: clawpack/classic path: classic + - name: Install clawpack run: | - pip install --no-build-isolation --editable $CLAW - # pip install --user -e $CLAW + cd ${CLAW} + pip install --no-build-isolation --editable . - name: Lint with flake8 run: | @@ -49,7 +51,16 @@ jobs: flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Test with pytest run: | cd ${CLAW}/classic - pytest + pytest --basetemp=./test_output + + - name: Upload test results + # if: failure() - Always upload artifacts now + uses: actions/upload-artifact@v4 + with: + name: test_results + path: ${{ env.CLAW }}/classic/test_output + if-no-files-found: ignore diff --git a/examples/acoustics_1d_heterogeneous/regression_data/regression_data_test2.txt b/examples/acoustics_1d_heterogeneous/regression_data/frame0001.txt similarity index 100% rename from examples/acoustics_1d_heterogeneous/regression_data/regression_data_test2.txt rename to examples/acoustics_1d_heterogeneous/regression_data/frame0001.txt diff --git a/examples/acoustics_1d_heterogeneous/regression_data/regression_data_test3.txt b/examples/acoustics_1d_heterogeneous/regression_data/frame0002.txt similarity index 100% rename from examples/acoustics_1d_heterogeneous/regression_data/regression_data_test3.txt rename to examples/acoustics_1d_heterogeneous/regression_data/frame0002.txt diff --git a/examples/acoustics_1d_heterogeneous/setrun.py b/examples/acoustics_1d_heterogeneous/setrun.py index c0c4bc4..02b7c07 100644 --- a/examples/acoustics_1d_heterogeneous/setrun.py +++ b/examples/acoustics_1d_heterogeneous/setrun.py @@ -6,7 +6,6 @@ """ -from __future__ import absolute_import import os import numpy as np diff --git a/examples/acoustics_1d_heterogeneous/test_acoustics_1d_heterogeneous.py b/examples/acoustics_1d_heterogeneous/test_acoustics_1d_heterogeneous.py index dd43352..c20a187 100644 --- a/examples/acoustics_1d_heterogeneous/test_acoustics_1d_heterogeneous.py +++ b/examples/acoustics_1d_heterogeneous/test_acoustics_1d_heterogeneous.py @@ -2,49 +2,27 @@ Regression tests for a 1D heterogeneous acoustics test """ -from __future__ import absolute_import -import sys -import unittest - +from pathlib import Path +import pytest import clawpack.classic.test as test +def test_acoustics_1d_heterogeneous(tmp_path: Path, save: bool): -class Acoustics1DHeterogeneousTest(test.ClassicRegressionTest): - r"""Basic test for an 1D heterogeneous acoustics test case""" - - def runTest(self, save=False): - - # Write out data files - self.load_rundata() - - # Modify data for test run - self.rundata.clawdata.num_output_times = 2 - self.rundata.clawdata.tfinal = 5.0 - self.rundata.clawdata.output_t0 = False - self.write_rundata_objects() - - # Run code - self.run_code() + ctr = test.ClassicTestRunner(tmp_path) - # Perform tests - self.check_frame(indices=[0, 1], save=save, frame_num=1, - file_name='regression_data_test2.txt') - self.check_frame(indices=[0, 1], save=save, frame_num=2, - file_name='regression_data_test3.txt') + ctr.set_data() + ctr.rundata.clawdata.num_output_times = 2 + ctr.rundata.clawdata.tfinal = 5.0 + ctr.rundata.clawdata.output_t0 = False + ctr.write_data() - self.success = True + ctr.executable_name = 'xclaw' + ctr.build_executable() + ctr.run_code() + ctr.check_frame(1, indices=(0, 1), save=save) + ctr.check_frame(2, indices=(0, 1), save=save) if __name__=="__main__": - if len(sys.argv) > 1: - if bool(sys.argv[1]): - # Fake the setup and save out output - test = Acoustics1DHeterogeneousTest() - try: - test.setUp() - test.runTest(save=True) - finally: - test.tearDown() - sys.exit(0) - unittest.main() \ No newline at end of file + pytest.main([__file__]) diff --git a/examples/acoustics_3d_heterogeneous/regression_data/regression_data_test2.txt b/examples/acoustics_3d_heterogeneous/regression_data/frame0001.txt similarity index 100% rename from examples/acoustics_3d_heterogeneous/regression_data/regression_data_test2.txt rename to examples/acoustics_3d_heterogeneous/regression_data/frame0001.txt diff --git a/examples/acoustics_3d_heterogeneous/regression_data/regression_data_test3.txt b/examples/acoustics_3d_heterogeneous/regression_data/frame0002.txt similarity index 100% rename from examples/acoustics_3d_heterogeneous/regression_data/regression_data_test3.txt rename to examples/acoustics_3d_heterogeneous/regression_data/frame0002.txt diff --git a/examples/acoustics_3d_heterogeneous/test_acoustics_3d_heterogeneous.py b/examples/acoustics_3d_heterogeneous/test_acoustics_3d_heterogeneous.py index 4409ca0..cd62911 100644 --- a/examples/acoustics_3d_heterogeneous/test_acoustics_3d_heterogeneous.py +++ b/examples/acoustics_3d_heterogeneous/test_acoustics_3d_heterogeneous.py @@ -2,49 +2,28 @@ Regression tests for 3D heterogeneous acoustics problem. """ -import sys -import unittest - +from pathlib import Path +import pytest import clawpack.classic.test as test - -class Acoustics3DHeterogeneousTest(test.ClassicRegressionTest): +def test_acoustics_3d_heterogeneous(tmp_path: Path, save: bool): r"""Basic test for a 3D heterogeneous acoustics test.""" + ctr = test.ClassicTestRunner(tmp_path) - def runTest(self, save=False): - - # Write out data files - self.load_rundata() - - self.rundata.clawdata.num_cells = [20, 20, 20] - self.rundata.clawdata.num_output_times = 2 - self.rundata.clawdata.tfinal = 1.0 - - self.write_rundata_objects() - - # Run code - self.run_code() - - # Perform tests - self.check_frame(save=save, indices=[0, 1, 2], frame_num=1, - file_name='regression_data_test2.txt') - self.check_frame(save=save, indices=[0, 1, 2], frame_num=2, - file_name='regression_data_test3.txt') + ctr.set_data() + ctr.rundata.clawdata.num_cells = [20, 20, 20] + ctr.rundata.clawdata.num_output_times = 2 + ctr.rundata.clawdata.tfinal = 1.0 + ctr.write_data() - self.success = True + ctr.executable_name = 'xclaw' + ctr.build_executable() + ctr.run_code() + ctr.check_frame(1, indices=(0, 1, 2), save=save) + ctr.check_frame(2, indices=(0, 1, 2), save=save) -if __name__=="__main__": - if len(sys.argv) > 1: - if bool(sys.argv[1]): - # Fake the setup and save out output - test = Acoustics3DHeterogeneousTest() - try: - test.setUp() - test.runTest(save=True) - finally: - test.tearDown() - sys.exit(0) - unittest.main() \ No newline at end of file +if __name__ == "__main__": + pytest.main([__file__]) diff --git a/examples/advection_2d_annulus/regression_data/regression_data_test2.txt b/examples/advection_2d_annulus/regression_data/frame0001.txt similarity index 100% rename from examples/advection_2d_annulus/regression_data/regression_data_test2.txt rename to examples/advection_2d_annulus/regression_data/frame0001.txt diff --git a/examples/advection_2d_annulus/regression_data/regression_data_test3.txt b/examples/advection_2d_annulus/regression_data/frame0002.txt similarity index 100% rename from examples/advection_2d_annulus/regression_data/regression_data_test3.txt rename to examples/advection_2d_annulus/regression_data/frame0002.txt diff --git a/examples/advection_2d_annulus/test_advection_2d_annulus.py b/examples/advection_2d_annulus/test_advection_2d_annulus.py index 8edde85..49a8191 100644 --- a/examples/advection_2d_annulus/test_advection_2d_annulus.py +++ b/examples/advection_2d_annulus/test_advection_2d_annulus.py @@ -2,49 +2,26 @@ Regression tests for 2D advection on an annulus. """ -from __future__ import absolute_import -import sys -import unittest - +from pathlib import Path +import pytest import clawpack.classic.test as test +def test_advection_2d_annulus(tmp_path: Path, save: bool): -class Advection2DAnnulusTest(test.ClassicRegressionTest): - r"""Basic test for a 2D advection test case""" - - - def runTest(self, save=False): - - # Write out data files - self.load_rundata() - - self.rundata.clawdata.num_output_times = 2 - self.rundata.clawdata.tfinal = 0.5 - - self.write_rundata_objects() - - # Run code - self.run_code() + ctr = test.ClassicTestRunner(tmp_path) - # Perform tests - self.check_frame(save=save, frame_num=1, - file_name='regression_data_test2.txt') - self.check_frame(save=save, frame_num=2, - file_name='regression_data_test3.txt') + ctr.set_data() + ctr.rundata.clawdata.num_output_times = 2 + ctr.rundata.clawdata.tfinal = 0.5 + ctr.write_data() - self.success = True + ctr.executable_name = 'xclaw' + ctr.build_executable() + ctr.run_code() + ctr.check_frame(1, save=save) + ctr.check_frame(2, save=save) if __name__=="__main__": - if len(sys.argv) > 1: - if bool(sys.argv[1]): - # Fake the setup and save out output - test = Advection2DAnnulusTest() - try: - test.setUp() - test.runTest(save=True) - finally: - test.tearDown() - sys.exit(0) - unittest.main() \ No newline at end of file + pytest.main([__file__]) diff --git a/examples/conftest.py b/examples/conftest.py new file mode 100644 index 0000000..1795428 --- /dev/null +++ b/examples/conftest.py @@ -0,0 +1,10 @@ +"""Configuration for PyTest""" + +import pytest + +def pytest_addoption(parser): + parser.addoption('--save', action='store_true') + +@pytest.fixture +def save(request): + return request.config.getoption("--save", False) diff --git a/src/python/classic/test.py b/src/python/classic/test.py index 21bbae1..c037c75 100644 --- a/src/python/classic/test.py +++ b/src/python/classic/test.py @@ -1,37 +1,30 @@ r""" -Execute nosetests in all subdirectories, to run a series of quick -regression tests. +Defines the Classic Clawpack Test Runner class for running PyTest based +regression tests in classic clawpack. -Sends output and result/errors to separate files to simplify checking -results and looking for errors. +Refer to the documentation for PyTest to manage output and reporting. """ +from pathlib import Path import os -import glob +from typing import Optional -import clawpack.clawutil.test -import clawpack.pyclaw.util +import clawpack.clawutil.test as test # Clean library files whenever this module is used if "CLAW" in os.environ: - CLAW = os.environ["CLAW"] + CLAW = Path(os.environ["CLAW"]) else: raise ValueError("Need to set CLAW environment variable.") -for lib_path in [os.path.join(CLAW,"classic","src","1d"), - os.path.join(CLAW,"classic","src","2d"), - os.path.join(CLAW,"classic","src","3d")]: - for path in glob.glob(os.path.join(lib_path,"*.o")): - os.remove(path) - for path in glob.glob(os.path.join(lib_path,"*.mod")): - os.remove(path) +for lib_path in (CLAW / "classic" / "src" / "1d").glob("*.o"): + lib_path.unlink() +for lib_path in (CLAW / "classic" / "src" / "2d").glob("*.o"): + lib_path.unlink() +for lib_path in (CLAW / "classic" / "src" / "3d").glob("*.o"): + lib_path.unlink() +class ClassicTestRunner(test.ClawpackTestRunner): -class ClassicRegressionTest(clawpack.clawutil.test.ClawpackRegressionTest): - - r"""Base Classic regression test setup derived from ClawpackRegressionTest - - """ - - __doc__ += clawpack.pyclaw.util.add_parent_doc( - clawpack.clawutil.test.ClawpackRegressionTest) + def __init__(self, path: Path, test_path: Optional[Path]=None): + super(ClassicTestRunner, self).__init__(path, test_path=test_path)