diff --git a/README.md b/README.md index 6a5d513..10c0133 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,16 @@ -# SPOC +# SPOC Specific Preprocessing of Observations Configuration -This repository holds template configuration files, supporting scripts, and any other infrastructure needed to both convert observations to the JEDI IODA format offline as well as read them directly in JEDI applications. \ No newline at end of file +This repository holds template configuration files, supporting scripts, +and other infrastructure needed to convert observations to the JEDI IODA +format offline as well as read them directly in JEDI applications. + +## Testing + +PyTest based regression tests reside in the `tests/` directory. Sample +BUFR inputs and reference NetCDF outputs are required to execute the +tests. Place the files in `tests/data` and `tests/baseline` and run: + +``` +pytest -v +``` diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..af0690d --- /dev/null +++ b/tests/README.md @@ -0,0 +1,14 @@ +The `tests` directory contains regression tests for SPOC mapping modules +using the `pytest` framework. + +Sample BUFR inputs and reference NetCDF outputs are not provided in the +repository. They must be placed under `tests/data` and `tests/baseline` +respectively before the tests can be executed. The tests will be skipped +if the required files are not found or if the necessary dependencies +(e.g. `numpy`, `bufr`, `pyioda`, and the `nccmp` utility) are missing. + +Run all tests with: + +``` +pytest -v +``` diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/baseline/README.md b/tests/baseline/README.md new file mode 100644 index 0000000..088dda3 --- /dev/null +++ b/tests/baseline/README.md @@ -0,0 +1 @@ +Place reference NetCDF files here diff --git a/tests/data/README.md b/tests/data/README.md new file mode 100644 index 0000000..d00760d --- /dev/null +++ b/tests/data/README.md @@ -0,0 +1 @@ +Place BUFR sample files here diff --git a/tests/test_interfaces.py b/tests/test_interfaces.py new file mode 100644 index 0000000..1afef96 --- /dev/null +++ b/tests/test_interfaces.py @@ -0,0 +1,52 @@ +import importlib +import os +import subprocess +import shutil +import pytest + +# Define mapping specifications: module path, input BUFR, mapping yaml, baseline NetCDF +MAPPING_SPECS = [ + { + 'module': 'dump.mapping.bufr_adpupa_prepbufr', + 'input': os.path.join('tests', 'data', 'adpupa.bufr'), + 'mapping': os.path.join('dump', 'mapping', 'bufr_adpupa_prepbufr_mapping.yaml'), + 'baseline': os.path.join('tests', 'baseline', 'adpupa.nc'), + 'cycle': '2021010100', + }, +] + +required_packages = ['numpy', 'bufr', 'pyioda'] + + +def require_dependencies(): + """Skip tests if required packages or tools are missing.""" + for pkg in required_packages: + pytest.importorskip(pkg) + if shutil.which('nccmp') is None: + pytest.skip('nccmp utility not available') + + +@pytest.mark.parametrize('spec', MAPPING_SPECS, ids=[spec['module'] for spec in MAPPING_SPECS]) +def test_create_obs_file(spec, tmp_path): + require_dependencies() + if not os.path.exists(spec['input']) or not os.path.exists(spec['baseline']): + pytest.skip('Sample data not available') + + mod = importlib.import_module(spec['module']) + output = tmp_path / 'out.nc' + + mod.create_obs_file(spec['input'], spec['mapping'], str(output), spec['cycle']) + result = subprocess.run(['nccmp', '-d', str(output), spec['baseline']]) + assert result.returncode == 0 + + +@pytest.mark.parametrize('spec', MAPPING_SPECS, ids=[spec['module'] for spec in MAPPING_SPECS]) +def test_create_obs_group(spec): + require_dependencies() + if not os.path.exists(spec['input']): + pytest.skip('Sample data not available') + + mod = importlib.import_module(spec['module']) + env = {'comm_name': 'world'} + group = mod.create_obs_group(spec['input'], spec['mapping'], spec['cycle'], env) + assert group is not None