-
Notifications
You must be signed in to change notification settings - Fork 129
Regression Testing
Regression tests are comparisons of code output to accepted solutions. They are used to ensure that parts of the code that work are not broken in the course of development. There should ultimately be a suite of stringent tests utilizing different parts of the code. Modifications to the code should not be pushed to the repository if they break regression tests.
This guide will describe how to use regression tests, as well as how to write new ones. See also the condensed presentation.
All regression testing is confined to athena/tst/regression/
; running these tests should have no effect outside this directory.
The regression tests for Athena++ are written in Python. They should be compatible with any Python 2.7 or 3 distribution. If they break in later versions of Python, please file a bug report and we can try to fix any incompatibilities.
From the top-level athena/
directory go to the regression test directory:
cd tst/regression
To run all test scripts that have been written, simply call
python run_tests.py
Instead of running all tests, selected tests can be run with
python run_tests.py <name_1> [<name_2> ...]
where each name is either of a suite of tests or an individual test within a suite. For example, the scripts/tests/gr/
directory contains the general relativity suite, which can be run with
python run_tests.py gr
One specific test in the suite is defined by the file scripts/tests/gr/mhd_shocks_hlld.py
, and this can be run with
python run_tests.py gr/mhd_shocks_hlld
This section is written from the perspective of the athena/tst/regression/
directory.
If a new suite of tests is desired (for example, there should be separate suites for relativity, radiation, AMR, etc.), create a new directory under scripts/tests/
. In order for Python to recognize the directory as containing scripts, it must have a file named __init__.py
. This file can and probably should be left empty.
In order to create a new regression test, start with a new file <test_name>.py
in scripts/tests/<suite_name>/
. At this time, the regression test framework does not support any further nested directories. No other file need be modified; in particular, the test does not need to be enrolled anywhere. In fact, the top-level script that is called, run_tests.py
, should not be modified.
A new test may very well need a new saved dataset to compare against. All such data files are kept in data/
. New files, usually Athena++ outputs, can be added here if need be. Data files in this directory are considered part of the repository: new files should be committed, and other developers' files should not be tampered with. Please refrain from including excessively large and unwieldy files.
Note: Storing reference solutions and comparing them to results of regression tests should only be performed for a limited set of tests. Exact comparison is impossible since that may depend on compiler/processor/library version, and inexact comparison is subjective. Analytic solutions or error convergence are preferred metrics for analyzing the regression test results.
One may want to write common functions for use in other tests. These can be placed in scripts/utils/
as detailed below.
The file <test_name>.py
is a valid test if it defines three valid Python functions, prepare()
, run()
, and analyze()
, that take no inputs, where the last returns either True
or False
depending on whether the test passes or not.
There are no other requirements for a test to work, but of course tests should behave themselves and should not modify/delete anything that could affect the rest of the code.
See a preexisting file, especially example.py
, for a working example.
Running regression tests should leave the files outside the regression directory unchanged. This is tricky, since the configure script overwrites athena/Makefile
and athena/src/defs.hpp
. To work around this, the main regression script run_tests.py
(which should not be modified) saves copies of these files, should they exist, before running any tests. Upon completing tests or encountering an exception, the regression script writes the original files back (or deletes whatever is there if those files did not exist before).
Because calling make
on the Makefile
output by the configure script would overwrite the objects and executable in the main directory, one must be careful in calling make
. Instead of calling it directly, the make()
function in scripts/utils/athena.py
overrides the definitions in the Makefile
to place the executable and all objects inside the regression directory. The executable will then place its outputs in the same location.
Because most regression tests will perform similar actions, a set of common utility functions is provided in scripts/utils/
. This includes for example functionality for taking L1 error norms.
To use these functions in a script, one must import the appropriate file. For example, from the test implementation in scripts/tests/<test_name>.py
, one can call the make()
function in scripts/utils/athena.py
by writing
import scripts.utils.athena as athena
athena.make()
The file scripts/utils/athena.py
defines Python routines for configuring, compiling, and running Athena++. The publicly useful functions are detailed here.
- Inputs:
- Positional: any number of strings, to be prefaced with
-
when callingathena/configure.py
; must go before keywords - Keywords: any number of
key='val'
assignments, to be used as--key=val
when callingathena/configure.py
; must go after positional arguments
- Positional: any number of strings, to be prefaced with
- Outputs: (none)
- Example:
configure('omp', prob='shock_tube')
will result in the code being configured as though one calledpython configure.py -omp --prob=shock_tube
from the home directory.
- Inputs: (none)
- Outputs: (none)
- Example: Simply call
make()
and the code will be compiled intoobj/
and linked intobin/
. Note these are the subdirectories ofathena/tst/regression/
, not those of the same names inathena/
.
- Inputs:
-
input_filename
: string containing the path to the desired input file, relative toathena/inputs/
-
arguments
: list of strings, one for each command-line argument to be fed to Athena++
-
- Outputs: (none)
- Example: The following code snippet runs Athena++ with a relativistic shock tube, ensuring the CFL number, simulation time, and number of grid points are correct:
import scripts.utils.athena as athena
arguments = ['time/cfl_number=0.4', 'time/tlim=0.4', 'mesh/nx1=400']
athena.run('hydro_sr/athinput.mb_1', arguments)
Some utilities for comparing one dataset to another are provided in scripts/utils/comparison.py
. The available functions are documented here.
- Inputs:
-
faces
: 1D array of N+1 interface locations -
vals
: 1D array of N volume-averaged values of a functionf
-
- Outputs: Returns the integral of the absolute value of
f
over the domain.
- Inputs:
-
faces_1
: 1D array of N1+1 interface locations -
vals_1
: 1D array of N1 volume-averaged values of a functionf
-
faces_2
: 1D array of N2+1 interface locations -
vals_2
: 1D array of N2 volume-averaged values of a functiong
-
- Outputs: Returns the integral of the absolute value of
f-g
over the domain. This is calculated by taking the union of all N1+N2+2 interface locations to define a refined grid, pushing each of the N1 cells' values forf
into the corresponding new cells, and doing likewise forg
. The procedure ofl1_norm()
is applied to the refined grid and the unambiguously calculatedf-g
values on that grid. Note no interpolation is involved; the answer is mathematically exact to the extentf
andg
are represented by step functions.
See the documentation on the general-purpose Python scripts for reading Athena++ data.
Getting Started
User Guide
- Configuring
- Compiling
- The Input File
- Problem Generators
- Boundary Conditions
- Coordinate Systems and Meshes
- Running the Code
- Outputs
- Using MPI and OpenMP
- Static Mesh Refinement
- Adaptive Mesh Refinement
- Load Balancing
- Special Relativity
- General Relativity
- Passive Scalars
- Shearing Box
- Diffusion Processes
- General Equation of State
- FFT
- Multigrid
- High-Order Methods
- Super-Time-Stepping
- Orbital Advection
- Rotating System
- Reading Data from External Files
- Non-relativistic Radiation Transport
- Cosmic Ray Transport
- Units and Constants
Programmer Guide