diff --git a/.github/workflows/run_system_tests.yaml b/.github/workflows/run_system_tests.yaml new file mode 100644 index 00000000..9ca38c8c --- /dev/null +++ b/.github/workflows/run_system_tests.yaml @@ -0,0 +1,30 @@ +name: Run SpatialPy System Tests + +on: + push: + branches: [staging, develop] + +jobs: + run-tests: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ ubuntu-latest ] + + steps: + - name: Initialize environment + uses: actions/checkout@v2 + + - name: Install Python + uses: actions/setup-python@v2 + with: + python-version: '3.7' + + - name: Install Python dependencies + run: | + python3 -m pip install --upgrade pip + python3 -m pip install -r requirements.txt + python3 -m pip install coverage + + - name: Run tests + run: coverage run --source=spatialpy test/run_system_tests.py diff --git a/run_coverage.sh b/run_coverage.sh index b566b0e3..718b4211 100755 --- a/run_coverage.sh +++ b/run_coverage.sh @@ -4,4 +4,5 @@ coverage run --source=spatialpy test/run_unit_tests.py -m develop coverage run --source=spatialpy test/run_integration_tests.py -m develop +coverage run --source=spatialpy test/run_system_tests.py -m develop coverage html diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/test/integration_tests/__init__.py b/test/integration_tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/test/test_mincde.py b/test/integration_tests/test_mincde.py similarity index 100% rename from test/test_mincde.py rename to test/integration_tests/test_mincde.py diff --git a/test/test_model.py b/test/integration_tests/test_model.py similarity index 100% rename from test/test_model.py rename to test/integration_tests/test_model.py diff --git a/test/test_solver.py b/test/integration_tests/test_solver.py similarity index 99% rename from test/test_solver.py rename to test/integration_tests/test_solver.py index 01a72455..e3f3cfd1 100644 --- a/test/test_solver.py +++ b/test/integration_tests/test_solver.py @@ -204,7 +204,7 @@ def test_solver_expressions(self): Ensure that expression conversions to C++ result in (roughly) equivalent values as Python. """ tmpdir = tempfile.mkdtemp() - src_path = os.path.join(os.path.dirname(__file__), "assets", "evaluate.c") + src_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "assets", "evaluate.c") exe_path = os.path.join(tmpdir, "test") def build(expr_args: "list[str]", expr_str: "str", use_bool=False): diff --git a/test/test_threads.py b/test/integration_tests/test_threads.py similarity index 100% rename from test/test_threads.py rename to test/integration_tests/test_threads.py diff --git a/test/models/birth_death.py b/test/models/birth_death.py new file mode 100644 index 00000000..c30ca4f1 --- /dev/null +++ b/test/models/birth_death.py @@ -0,0 +1,50 @@ +# SpatialPy is a Python 3 package for simulation of +# spatial deterministic/stochastic reaction-diffusion-advection problems +# Copyright (C) 2019 - 2023 SpatialPy developers. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU GENERAL PUBLIC LICENSE Version 3 as +# published by the Free Software Foundation. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU GENERAL PUBLIC LICENSE Version 3 for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +''' spatialpy model file for the spatial birth death example. ''' +import spatialpy + +def create_birth_death(): + ''' Create the spatial birth death model. ''' + model = spatialpy.Model(name='Spatial Birth-Death') + + model.HABITAT = "Habitat" + + domain = spatialpy.Domain.create_2D_domain( + xlim=(0, 1), ylim=(0, 1), numx=10, numy=10, type_id=model.HABITAT, fixed=True + ) + model.add_domain(domain) + + rabbits = spatialpy.Species(name='Rabbits', diffusion_coefficient=0.1) + model.add_species(rabbits) + + init_rabbit_pop = spatialpy.ScatterInitialCondition(species='Rabbits', count=100) + model.add_initial_condition(init_rabbit_pop) + + k_birth = spatialpy.Parameter(name='k_birth', expression=10) + k_death = spatialpy.Parameter(name='k_death', expression=0.1) + model.add_parameter([k_birth, k_death]) + + birth = spatialpy.Reaction( + name='birth', reactants={}, products={"Rabbits":1}, rate="k_birth" + ) + death = spatialpy.Reaction( + name='death', reactants={"Rabbits":1}, products={}, rate="k_death" + ) + model.add_reaction([birth, death]) + + tspan = spatialpy.TimeSpan.linspace(t=10, num_points=11, timestep_size=1) + model.timespan(tspan) + return model diff --git a/test/run_integration_tests.py b/test/run_integration_tests.py index ed430f1f..0360b12f 100644 --- a/test/run_integration_tests.py +++ b/test/run_integration_tests.py @@ -14,8 +14,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . - -import unittest, sys, os +''' Testing suite for integration tests. ''' +import os +import sys +import unittest import argparse parser = argparse.ArgumentParser() @@ -28,9 +30,9 @@ print('Running tests in develop mode. Appending repository directory to system path.') sys.path.append(os.path.join(os.path.dirname(__file__), '..')) - import test_model - import test_solver - #import test_mincde + from test.integration_tests import test_model + from test.integration_tests import test_solver + #from test.integration_tests import test_mincde modules = [ test_model, @@ -42,7 +44,7 @@ suite = unittest.TestLoader().loadTestsFromModule(module) runner = unittest.TextTestRunner(failfast=args.mode == 'develop') - print("Executing: {}".format(module)) + print(f"Executing: {module}") result = runner.run(suite) print('=' * 70) if not result.wasSuccessful(): diff --git a/test/run_system_tests.py b/test/run_system_tests.py new file mode 100644 index 00000000..fbbee335 --- /dev/null +++ b/test/run_system_tests.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +# SpatialPy is a Python 3 package for simulation of +# spatial deterministic/stochastic reaction-diffusion-advection problems +# Copyright (C) 2019 - 2023 SpatialPy developers. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU GENERAL PUBLIC LICENSE Version 3 as +# published by the Free Software Foundation. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU GENERAL PUBLIC LICENSE Version 3 for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +''' Testing suite for system tests. ''' +import os +import sys +import unittest +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument('-m', '--mode', default='develop', choices=['develop', 'release'], + help='Run system tests in develop mode or release mode.') + +if __name__ == '__main__': + args = parser.parse_args() + if args.mode == 'develop': + print('Running system tests in develop mode. Appending repository directory to system path.') + sys.path.append(os.path.join(os.path.dirname(__file__), '..')) + + from test.system_tests import test_compiler + + modules = [ + test_compiler + ] + + for module in modules: + suite = unittest.TestLoader().loadTestsFromModule(module) + runner = unittest.TextTestRunner(failfast=args.mode == 'develop') + + print(f"Executing: {module}") + result = runner.run(suite) + print('=' * 70) + if not result.wasSuccessful(): + sys.exit(not result.wasSuccessful()) diff --git a/test/system_tests/__init__.py b/test/system_tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/test/system_tests/test_compiler.py b/test/system_tests/test_compiler.py new file mode 100755 index 00000000..3e6bdf78 --- /dev/null +++ b/test/system_tests/test_compiler.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +# SpatialPy is a Python 3 package for simulation of +# spatial deterministic/stochastic reaction-diffusion-advection problems +# Copyright (C) 2019 - 2023 SpatialPy developers. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU GENERAL PUBLIC LICENSE Version 3 as +# published by the Free Software Foundation. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU GENERAL PUBLIC LICENSE Version 3 for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +''' Tests from the compiler. ''' +import os +import sys +import unittest + +sys.path.insert(1, os.path.abspath(os.getcwd())) +from test.models.birth_death import create_birth_death # pylint: disable=wrong-import-position + +class TestCompiler(unittest.TestCase): + ''' + ################################################################################################ + System test for compiler. + ################################################################################################ + ''' + def setUp(self): + self.model = create_birth_death() + + def test_constructor(self): + """ Test the compiler. """ + _ = self.model.run() + +if __name__ == '__main__': + unittest.main()