Skip to content

Commit 28824ef

Browse files
authored
Add dedicated test entry points for CMIP6, CMIP6Plus, and CMIP7 in full CMORisation tests (#472)
1 parent 0ac9b4f commit 28824ef

2 files changed

Lines changed: 149 additions & 16 deletions

File tree

tests/README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,49 @@ pytest tests/integration/test_full_cmorisation.py --validation-tool=wcrp
6767
pytest tests/integration/test_full_cmorisation.py --validation-tool=prepare
6868
```
6969

70+
### Full CMORisation test selection (CMIP6, CMIP6Plus, CMIP7)
71+
72+
The full integration suite now has dedicated test entry points:
73+
74+
- `test_cmorisation_variable_cmip6`
75+
- `test_cmorisation_variable_cmip6plus`
76+
- `test_cmorisation_variable_cmip7`
77+
78+
Using pixi (recommended in this repository):
79+
80+
```bash
81+
# CMIP6 only
82+
pixi run -e dev python -m pytest \
83+
tests/integration/test_full_cmorisation.py::TestFullCMORIntegration::test_cmorisation_variable_cmip6 -q
84+
85+
# CMIP6Plus only
86+
pixi run -e dev python -m pytest \
87+
tests/integration/test_full_cmorisation.py::TestFullCMORIntegration::test_cmorisation_variable_cmip6plus -q
88+
89+
# CMIP7 only
90+
pixi run -e dev python -m pytest \
91+
tests/integration/test_full_cmorisation.py::TestFullCMORIntegration::test_cmorisation_variable_cmip7 -q
92+
```
93+
94+
Run only CMIP6 Amon variables:
95+
96+
```bash
97+
pixi run -e dev python -m pytest \
98+
tests/integration/test_full_cmorisation.py::TestFullCMORIntegration::test_cmorisation_variable_cmip6 \
99+
-k Amon -q
100+
```
101+
102+
Run one exact CMIP6 Amon variable case (example `tas`):
103+
104+
```bash
105+
pixi run -e dev python -m pytest \
106+
"tests/integration/test_full_cmorisation.py::TestFullCMORIntegration::test_cmorisation_variable_cmip6[Amon-ACCESS-ESM1-6-CMIP6_Amon.json-CMIP6-tas]" \
107+
-vv
108+
```
109+
110+
Note: avoid filtering with `-k CMIP6` by itself because it can also match
111+
`CMIP6Plus` node ids.
112+
70113
The `--validation-tool` option is defined in `tests/conftest.py`.
71114
`wcrp` is the default backend. It will skip if the WCRP compliance-checker
72115
suite is not available in the current environment, or if the local `esgvoc`

tests/integration/test_full_cmorisation.py

Lines changed: 106 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747

4848
CMOR_TABLE_PACKAGES = {
4949
"CMIP6": "access_moppy.vocabularies.cmip6_cmor_tables.Tables",
50+
"CMIP6Plus": "access_moppy.vocabularies.cmip6_cmor_tables.Tables",
5051
"CMIP7": "access_moppy.vocabularies.cmip7-cmor-tables.tables",
5152
}
5253

@@ -82,10 +83,9 @@ def _available_compliance_suites() -> set[str]:
8283
return suites
8384

8485

85-
# Define table configurations to avoid code duplication
86-
# Using model-specific mapping files with the new structure
86+
# Define table configurations to avoid code duplication.
8787
# Each tuple: (table_name, model_id, cmor_table_file, cmip_version)
88-
CMOR_TABLES = [
88+
CMOR_TABLES_CMIP6 = [
8989
# CMIP6 tables
9090
("Amon", "ACCESS-ESM1-6", "CMIP6_Amon.json", "CMIP6"),
9191
("AERmon", "ACCESS-ESM1-6", "CMIP6_AERmon.json", "CMIP6"),
@@ -100,6 +100,14 @@ def _available_compliance_suites() -> set[str]:
100100
("CFday", "ACCESS-ESM1-6", "CMIP6_CFday.json", "CMIP6"),
101101
("SImon", "ACCESS-ESM1-6", "CMIP6_SImon.json", "CMIP6"),
102102
("Ofx", "ACCESS-ESM1-6", "CMIP6_Ofx.json", "CMIP6"),
103+
]
104+
105+
CMOR_TABLES_CMIP6PLUS = [
106+
(table_name, model_id, cmor_table_file, "CMIP6Plus")
107+
for table_name, model_id, cmor_table_file, _ in CMOR_TABLES_CMIP6
108+
]
109+
110+
CMOR_TABLES_CMIP7 = [
103111
# CMIP7 tables (via mapping to CMIP6 equivalents)
104112
("atmos", "ACCESS-ESM1-6", "CMIP7_atmos.json", "CMIP7"),
105113
("ocean", "ACCESS-ESM1-6", "CMIP7_ocean.json", "CMIP7"),
@@ -108,8 +116,10 @@ def _available_compliance_suites() -> set[str]:
108116
]
109117

110118

111-
@lru_cache(maxsize=1)
112-
def _generate_variable_test_params() -> list[tuple[str, str, str, str, str]]:
119+
@lru_cache(maxsize=None)
120+
def _generate_variable_test_params(
121+
table_configs: tuple[tuple[str, str, str, str], ...],
122+
) -> list[tuple[str, str, str, str, str]]:
113123
"""Generate all (table, model_id, cmor_table_file, cmip_version, variable) test parameters.
114124
115125
This function generates individual test parameters for each variable in each table,
@@ -120,7 +130,7 @@ def _generate_variable_test_params() -> list[tuple[str, str, str, str, str]]:
120130
"""
121131
params = []
122132

123-
for table_name, model_id, cmor_table_file, cmip_version in CMOR_TABLES:
133+
for table_name, model_id, cmor_table_file, cmip_version in table_configs:
124134
try:
125135
# For CMIP7 tables, map to CMIP6 equivalents for loading variables
126136
mapping_table_name = table_name
@@ -157,7 +167,11 @@ def _generate_variable_test_params() -> list[tuple[str, str, str, str, str]]:
157167

158168

159169
# Generate variable-level test parameters for granular control
160-
VARIABLE_TEST_PARAMS = _generate_variable_test_params()
170+
VARIABLE_TEST_PARAMS_CMIP6 = _generate_variable_test_params(tuple(CMOR_TABLES_CMIP6))
171+
VARIABLE_TEST_PARAMS_CMIP6PLUS = _generate_variable_test_params(
172+
tuple(CMOR_TABLES_CMIP6PLUS)
173+
)
174+
VARIABLE_TEST_PARAMS_CMIP7 = _generate_variable_test_params(tuple(CMOR_TABLES_CMIP7))
161175

162176

163177
def _parametrize_test_ids(param_set: tuple) -> str:
@@ -173,7 +187,11 @@ def _parametrize_test_ids(param_set: tuple) -> str:
173187
return str(param_set)
174188

175189
table, model_id, cmor_table, cmip_version, variable = param_set
176-
suffix = "-cmip7" if cmip_version == "CMIP7" else ""
190+
suffix = ""
191+
if cmip_version == "CMIP7":
192+
suffix = "-cmip7"
193+
elif cmip_version == "CMIP6Plus":
194+
suffix = "-cmip6plus"
177195
return f"{table}-{variable}{suffix}"
178196

179197

@@ -288,10 +306,87 @@ def _get_input_files_for_compound(
288306
@pytest.mark.integration
289307
@pytest.mark.parametrize(
290308
"table_name,model_id,cmor_table_file,cmip_version,variable_name",
291-
VARIABLE_TEST_PARAMS,
309+
VARIABLE_TEST_PARAMS_CMIP6,
310+
ids=_parametrize_test_ids,
311+
)
312+
def test_cmorisation_variable_cmip6(
313+
self,
314+
parent_experiment_config,
315+
compliance_validation_tool,
316+
table_name,
317+
model_id,
318+
cmor_table_file,
319+
cmip_version,
320+
variable_name,
321+
):
322+
"""Test CMORisation for a specific CMIP6 variable in a table."""
323+
self._run_cmorisation_variable(
324+
parent_experiment_config=parent_experiment_config,
325+
compliance_validation_tool=compliance_validation_tool,
326+
table_name=table_name,
327+
model_id=model_id,
328+
cmor_table_file=cmor_table_file,
329+
cmip_version=cmip_version,
330+
variable_name=variable_name,
331+
)
332+
333+
@pytest.mark.slow
334+
@pytest.mark.integration
335+
@pytest.mark.parametrize(
336+
"table_name,model_id,cmor_table_file,cmip_version,variable_name",
337+
VARIABLE_TEST_PARAMS_CMIP6PLUS,
292338
ids=_parametrize_test_ids,
293339
)
294-
def test_cmorisation_variable(
340+
def test_cmorisation_variable_cmip6plus(
341+
self,
342+
parent_experiment_config,
343+
compliance_validation_tool,
344+
table_name,
345+
model_id,
346+
cmor_table_file,
347+
cmip_version,
348+
variable_name,
349+
):
350+
"""Test CMORisation for a specific CMIP6Plus variable in a table."""
351+
self._run_cmorisation_variable(
352+
parent_experiment_config=parent_experiment_config,
353+
compliance_validation_tool=compliance_validation_tool,
354+
table_name=table_name,
355+
model_id=model_id,
356+
cmor_table_file=cmor_table_file,
357+
cmip_version=cmip_version,
358+
variable_name=variable_name,
359+
)
360+
361+
@pytest.mark.slow
362+
@pytest.mark.integration
363+
@pytest.mark.parametrize(
364+
"table_name,model_id,cmor_table_file,cmip_version,variable_name",
365+
VARIABLE_TEST_PARAMS_CMIP7,
366+
ids=_parametrize_test_ids,
367+
)
368+
def test_cmorisation_variable_cmip7(
369+
self,
370+
parent_experiment_config,
371+
compliance_validation_tool,
372+
table_name,
373+
model_id,
374+
cmor_table_file,
375+
cmip_version,
376+
variable_name,
377+
):
378+
"""Test CMORisation for a specific CMIP7 variable in a table."""
379+
self._run_cmorisation_variable(
380+
parent_experiment_config=parent_experiment_config,
381+
compliance_validation_tool=compliance_validation_tool,
382+
table_name=table_name,
383+
model_id=model_id,
384+
cmor_table_file=cmor_table_file,
385+
cmip_version=cmip_version,
386+
variable_name=variable_name,
387+
)
388+
389+
def _run_cmorisation_variable(
295390
self,
296391
parent_experiment_config,
297392
compliance_validation_tool,
@@ -306,12 +401,7 @@ def test_cmorisation_variable(
306401
This is a granular integration test that processes individual variables,
307402
enabling fine-grained control via pytest -k filtering.
308403
309-
Tests are parametrized by individual (table, variable) pairs, so you can:
310-
- Run all tests: pytest tests/integration/test_full_cmorisation.py
311-
- Run specific variable: pytest tests/integration/test_full_cmorisation.py -k "Amon-tas"
312-
- Run specific table: pytest tests/integration/test_full_cmorisation.py -k "Omon"
313-
- Run CMIP7 only: pytest tests/integration/test_full_cmorisation.py -k "cmip7"
314-
- Run CMIP6 only: pytest tests/integration/test_full_cmorisation.py -k "not cmip7"
404+
Tests are parametrized by individual (table, variable) pairs.
315405
316406
For ocean variables (Omon), uses ocean data files instead of atmosphere files.
317407
Uses appropriate input files based on table frequency requirements.

0 commit comments

Comments
 (0)