Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
55b1e61
created filesystem
Dec 10, 2025
bed774d
updated template writing
Dec 10, 2025
9fae481
updates for better abstraction
Dec 11, 2025
1095dbb
bug fix for relative path
Dec 11, 2025
73d4572
update class template
Dec 11, 2025
ebe84e1
refactor build
Dec 12, 2025
487308d
rename builder file
Dec 12, 2025
05fc451
updates to cime_setup
Dec 15, 2025
79cc9f3
more updates for cime config
Dec 15, 2025
91d9a4a
get rid of file_system.py
Dec 15, 2025
12d4893
rename file
Dec 16, 2025
a4fb778
merge in json params update
Dec 16, 2025
d7d6134
fix typo
Dec 16, 2025
e615581
updates
Dec 17, 2025
71aa830
Merge branch 'json-params' into testing_update
Dec 17, 2025
0d30da3
fixing issues
Dec 17, 2025
2f7beb0
fixing import statement
Dec 17, 2025
15389e1
fix
Dec 17, 2025
989ce86
should work now
Dec 17, 2025
1946d25
fix logging level
Dec 17, 2025
3b3ae23
move tests into a new directory
Dec 17, 2025
7cfd933
update test protocol
Dec 17, 2025
a4fca2c
move testing_shr and data
Dec 17, 2025
fc6a91b
move configs into config dir
Dec 17, 2025
c8bd9ef
renamed some files
Dec 17, 2025
b3b0871
created framework dir
Dec 17, 2025
fef6cd2
trying to fix paths
Dec 18, 2025
b868194
runs
Dec 18, 2025
7a59aed
updates
Dec 18, 2025
5a4ab05
create run class
Dec 19, 2025
0781cc2
move cime path into module
Dec 19, 2025
e8c9ae1
unit test class
Dec 19, 2025
38025df
updated templates
Dec 19, 2025
52b2292
pylint updates
Dec 19, 2025
a9e5d42
updates for generator
Dec 19, 2025
71e8a71
remove print
Dec 19, 2025
6af4ed8
trying to fix
Dec 19, 2025
f89de9f
fixing generators
Dec 20, 2025
628d27b
fixing issues
Dec 20, 2025
cc5baec
black updates
Dec 20, 2025
3d2a5e3
updated docs
Dec 21, 2025
c6c693b
typos
Dec 21, 2025
75868ff
updates
Dec 22, 2025
d7fea2d
no longer need extra class
Dec 22, 2025
63594a8
fix loader
Dec 22, 2025
df370b1
adding init
Dec 22, 2025
d411dd1
adding init
Dec 22, 2025
f7c71e7
adding great circle functional tests
Dec 22, 2025
b0f287c
added quadratic unit test
Dec 23, 2025
9a8efdf
update cmakelists
Dec 23, 2025
c7df592
adding great circle unit tests
Dec 23, 2025
215c463
great circle test update
Dec 23, 2025
d4d5b93
add environment check
Dec 31, 2025
24b0277
fix error message
Dec 31, 2025
19d0b9a
update
Jan 14, 2026
a8dad79
moved data to .cdl
Jan 16, 2026
3237507
add BONA netcdf data
glemieux Feb 5, 2026
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
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ add_subdirectory(${HLM_ROOT}/src/fates/fire fates_fire)
add_subdirectory(${HLM_ROOT}/src/fates/radiation fates_radiation)

# Testing directories
add_subdirectory(${HLM_ROOT}/src/fates/testing/testing_shr test_share)
add_subdirectory(${HLM_ROOT}/src/fates/testing/functional_testing/fire/shr fire_share)
add_subdirectory(${HLM_ROOT}/src/fates/testing/tests/fortran_shr test_share)
add_subdirectory(${HLM_ROOT}/src/fates/testing/tests/functional/fire/shr fire_share)

# Remove shr_mpi_mod from share_sources.
# This is needed because we want to use the mock shr_mpi_mod in place of the real one
Expand Down
4 changes: 2 additions & 2 deletions main/FatesUtilsMod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,9 @@ subroutine QuadraticRootsNSWC(a,b,c,root1,root2,err)
endif
if ( e<0.0_r8 ) then
! complex conjugate zeros
write (fates_log(),*)'error, imaginary roots detected in quadratic solve'
err = .true.
call endrun(msg=errMsg(sourcefile, __LINE__))
call endrun(msg="imaginary roots detected in quadratic solve", &
additional_msg=errMsg(sourcefile, __LINE__))
else
! real zeros
if ( b1>=0.0_r8 ) d = -d
Expand Down
27 changes: 14 additions & 13 deletions testing/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
# This is where you add specific test directories

## Functional tests
add_subdirectory(functional_testing/allometry fates_allom_ftest)
add_subdirectory(functional_testing/math_utils fates_math_ftest)
add_subdirectory(functional_testing/fire/fuel fates_fuel_ftest)
add_subdirectory(functional_testing/fire/ros fates_ros_ftest)
add_subdirectory(functional_testing/patch fates_patch_ftest)
add_subdirectory(functional_testing/fire/mortality fates_firemort_ftest)
add_subdirectory(tests/functional/allometry fates_allom_ftest)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

add_subdirectory(tests/functional/fire/fuel fates_fuel_ftest)
add_subdirectory(tests/functional/fire/ros fates_ros_ftest)
add_subdirectory(tests/functional/patch fates_patch_ftest)
add_subdirectory(tests/functional/fire/mortality fates_firemort_ftest)

## Unit tests
add_subdirectory(unit_testing/fire_weather_test fates_fire_weather_utest)
add_subdirectory(unit_testing/fire_fuel_test fates_fire_fuel_utest)
add_subdirectory(unit_testing/sort_cohorts_test fates_sort_cohorts_utest)
add_subdirectory(unit_testing/insert_cohort_test fates_insert_cohort_utest)
add_subdirectory(unit_testing/validate_cohorts_test fates_validate_cohorts_utest)
add_subdirectory(unit_testing/count_cohorts_test fates_count_cohorts_utest)
add_subdirectory(unit_testing/fire_equations_test fates_fire_equations_utest)
add_subdirectory(tests/unit/fire_weather_test fates_fire_weather_utest)
add_subdirectory(tests/unit/fire_fuel_test fates_fire_fuel_utest)
add_subdirectory(tests/unit/sort_cohorts_test fates_sort_cohorts_utest)
add_subdirectory(tests/unit/insert_cohort_test fates_insert_cohort_utest)
add_subdirectory(tests/unit/validate_cohorts_test fates_validate_cohorts_utest)
add_subdirectory(tests/unit/count_cohorts_test fates_count_cohorts_utest)
add_subdirectory(tests/unit/fire_equations_test fates_fire_equations_utest)
add_subdirectory(tests/unit/quadratic_roots_test fates_quadratic_roots_utest)
add_subdirectory(tests/unit/great_circle_test fates_great_circle_utest)
116 changes: 116 additions & 0 deletions testing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# FATES Testing Framework

This directory contains the infratstructure to set up, build, and execute FATES functional
and unit tests.

## Test Definitions

* **Functional Tests**: Standalone Fortran programs that exercse specific modules of the
FATES production code. They often output NetCDF data and include a Python class for
automated plotting and science validation. These are "hands-on" tests for developers.

* **Unit Tests**: Discrete tests with a clear Pass/Fail status, utilizing **pfUnit** or
**CTest**. These are best for testing edge cases, error handling, and logical branches
within individual subroutines.

## Environment Setup

### Python Requirements

The framework requires Python 3.12+ with `xarray`, `pandas`, `scipy`, `netCDF`, `numpy`,
and `matplotlib`. You can create a compatible environment using the provided file:

```bash
conda env create --file=environment.yml
conda activate fates_testing
```

### System Requirements

While these tests do not require a host land model (e.g., CTSM/ELM), they require:

* **CIME and shr**: These must be present in your source tree.
* **Libraries**: NetCDF (C and Fortran), ESMF, and pfUnit.
* **Machine Tags**: Valid machine and compiler configurations (e.g., NCAR Derecho/Izumi).
If FATES is already running on your machine, these scripts should work out of the box.

See `docs/cime_setup.md` for a step-by-step guide to setting up the environment on your
own machine (Mac/Linux).

## Execution

### Running Functional Tests

```bash
# Run all functional tests using default parameters
./run_functional_tests.py

# Run specific tests with a custom parameter file
./run_functional_tests.py --test-list allometry,fire --param-file my_params.json
```

### Running Unit Tests

```bash
# Run all unit tests
./run_unit_tests.py
```

*Note: Use the `--help` flag on either script to see full options for build directories,
skipping runs, and saving figures.*

## Creating New Tests

To maintain consistency, always use the boilerplate generator to start a new test.

### Step 1. Generate Scaffolding

Run the generator script. This updates the CMake system, adds config entries, and creates
your test directory.

```bash
# Example: Create a new functional test named 'hydro_stress'
./generate_empty_test.py functional --test-name hydro_stress
```

### Step 2: Implement the Fortran Logic

Navigate to `tests/[unit|functional]/[test_name]` and edit the generated `.F90` or `.pf`
file.

* **Functional**: Write a standard Fortran program.
* **Unit**: Write a pfUnit-compatible test module.

### Step 3: Configure Metadata

Edit `config/functional.cfg` or `config/unit.cfg`. The generator provides defaults, but
you may need to update:

* `out_file`: The name of the NetCDF file your Fortran code generates.
* `use_param_file`: Set to `True` to pass the FATES JSON parameter file to your binary.
* `datm_file`: (Optional) Driver file name. All driver data should be placed in `testing/tests/data`

### Step 4: Python Analysis (Functional Only)

The generator creates a Python file (`[test_name]_test.py`) in your test directory. Edit
the `plot_output` method to define how your test results should be visualized or validated.

## Directory Structure

* `framework/`: Core logic for loading, building, and executing tests.
* `config/`: Registry of all active tests and their arguments.
* `tests/`: The source code for individual test cases.
* `templates/`: Boilerplate files used by the generator.

## Troubleshooting

* **Missing Drivers**: If a functional tests requires a `datm_file`, ensure the file name0 in
the `.cfg` is correct and the data is in `testing/tests/data`.
The script will perform a pre-flight check and fail if the file is missing.

* **Build Failures**: Ensure your environment modules (compiler, netcdf, esmf) match the
configuration in your CIME machine tags. Also, if you are using a Fortran module that is
in a file that is not currently listed in one of the `CMakeLists.txt` files, you will
need to add it. There should be a `CMakeLists.txt` file in each subdirectory of the FATES
source code. Add the file to the corresponding `CMakeLists.txt` inside the `fates_sources`
list.
97 changes: 0 additions & 97 deletions testing/README.testing.md

This file was deleted.

Loading