-
Notifications
You must be signed in to change notification settings - Fork 119
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.
All regression testing is confined to athena/test/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 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 test/regressionTo run all test scripts that have been written, simply call
python run_tests.pyInstead of running all tests, a single test can be run with
python run_tests.py -s <test_name>where the desired test is implemented in scripts/tests/<test_name>.py.
This section is written from the perspective of the athena/test/regression/ directory.
In order to create a new regression test, start with a new file <test_name>.py in scripts/tests/. 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.
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 a valid Python function run_tests() that takes no inputs and 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, such as gr_shock_tube.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/.
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++, as well as reading in certain output files. 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=valwhen 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_tubefrom 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/test/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)- Inputs:
-
filename: string containing the path to the desired Athena++ 1D tab output file to be read, relative toathena/test/regression -
headings(optional, defaultNone): list of strings to name columns of output file, excluding first column (zone number)
-
- Outputs: If
headingsisNone, a 2D numpy array containing the data from the file, excluding the first column. Otherwise a dictionary whose keywords are the elements inheadingsand whose values are the corresponding 1D arrays read from the file. - Example: Suppose one wants to read
athena/test/regression/data/my_output.tab. The following code snippet does this, printing the values from the third column in the file:
import scripts.utils.athena as athena
data = athena.read('data/my_output.tab', ['x', 'rho', 'pgas', 'v1', 'v2', 'v3'])
print(data['rho'])TODO: write
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
- High-Order Methods
- Super-Time-Stepping
- Orbital Advection
- Rotating System
- Reading Data from External Files
Programmer Guide