climate_ref.cli.test_cases._stages
#
Composable stages behind the ref test-cases verbs.
The verbs run / mint / replay are thin compositions over a small set of stages:
- execute -- run the diagnostic and copy its curated native set into a slot
- materialise -- fetch a committed manifest's native blobs from the store into a slot
- build -- assemble the committed bundle from the native in a slot
- upload -- push changed-digest native blobs to the store
- compare -- diff a slot's rebuilt bundle against the tracked committed baseline
Native produced by a source stage (execute or materialise) lands in a gitignored output slot
(<case>/output/<label>/), flat at manifest-relative paths,
with a regression/ subdirectory holding the rebuilt committed bundle.
latest (the default label) is overwritten on every run.
A custom named slot persists so two runs can be diffed (--label before vs --label after).
See docs/background/regression-baselines.md.
SourceOutputs
#
Bases: NamedTuple
The native a source stage placed in a slot, plus what build needs to consume it.
bundle_output_dir is the absolute output directory the rebuilt bundle's text
contents reference -- the real execution directory for execute (the copied bundle
still points there), or the slot itself for materialise (build_execution_result
rewrote the bundle into the slot).
Source code in packages/climate-ref/src/climate_ref/cli/test_cases/_stages.py
StageError
#
baseline_placeholders(paths, config)
#
Build the run-level baseline placeholder map shared by every ref test-cases verb.
Declares the configuration-stable token set once (<TEST_DATA_DIR> from the test case and
<SOFTWARE_ROOT_DIR> from the configured software root) so run / mint / replay
cannot sanitise against drifting token sets.
The per-execution <OUTPUT_DIR> is bound later by the caller.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
paths
|
TestCasePaths
|
Resolved paths for the test case (provides the test-data root). |
required |
config
|
Config
|
The active configuration (provides the software root). |
required |
Source code in packages/climate-ref/src/climate_ref/cli/test_cases/_stages.py
native_is_stale(fresh, previous)
#
Return True when a previous (mint-owned) native block exists and differs from the fresh snapshot.
Used to warn -- not block -- after a committed-bundle regeneration whose underlying native has drifted, so the author knows to re-mint.
Source code in packages/climate-ref/src/climate_ref/cli/test_cases/_stages.py
prepare_slot(paths, label)
#
Wipe and recreate output/<label>/ and return the slot base directory.
Used by the source stages (execute / materialise), which repopulate the native set.
run --from-slot does not call this, because it reuses the native already in the slot.
Source code in packages/climate-ref/src/climate_ref/cli/test_cases/_stages.py
promote_and_author_manifest(*, paths, diag, slot, source, placeholders, committed, stale_message)
#
Promote a slot's rebuilt bundle to the tracked baseline and author the manifest.
The native block is mint-owned, so this preserves the previous manifest's version and native block,
or seeds an empty set for a never-minted case.
When the freshly snapshotted native differs from the minted one,
stale_message is logged as a warning so the author knows to re-mint.
Source code in packages/climate-ref/src/climate_ref/cli/test_cases/_stages.py
promote_to_baseline(slot, paths)
#
Copy a slot's rebuilt committed bundle into the tracked regression/ baseline.
The slot bundle is already sanitised and float-quantised, so the promoted bytes (and
therefore their digests) match what stage_build returned.
Source code in packages/climate-ref/src/climate_ref/cli/test_cases/_stages.py
slot_native_relpaths(slot)
#
Return the native files in a slot -- everything except the rebuilt bundle.
A slot is populated only by a source stage with the curated output set, so this is
exactly the curated native set (it excludes the regression/ subdirectory written
by :func:stage_build).
Source code in packages/climate-ref/src/climate_ref/cli/test_cases/_stages.py
snapshot_native(slot, *, source, placeholders)
#
Sanitise the slot's native set to portable placeholders, then snapshot it (manifest / upload).
The curated native (and any captured reconstruction inputs) still embed absolute paths to the
output directory of the execution (source.bundle_output_dir),
plus the shared <TEST_DATA_DIR> / <SOFTWARE_ROOT_DIR> roots.
Rewriting those to <TOKEN> placeholders before digesting makes the stored blobs,
and therefore their recorded digests, machine independent,
and replay can hydrate the blobs into any slot.
Binary artefacts (.nc / .png) are never rewritten.
Like :func:stage_build,
the placeholder map is bound to source.bundle_output_dir here rather than by the caller,
so the two stages cannot drift on which output directory they sanitise.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
slot
|
Path
|
The output slot whose native set is sanitised and snapshotted. |
required |
source
|
SourceOutputs
|
The source stage's outputs, carrying the absolute output directory the native text references. |
required |
placeholders
|
PlaceholderMap
|
The (unbound) placeholder map for this run. |
required |
Source code in packages/climate-ref/src/climate_ref/cli/test_cases/_stages.py
stage_build(*, slot, source, placeholders)
#
Assemble the committed bundle into the slot's regression/ directory.
Returns the committed digests {filename: sha256} of the sanitised, float-quantised
bytes just written -- suitable for Manifest.committed and identical to what would be
promoted to the tracked baseline.
The rebuilt bundle's text still references source.bundle_output_dir, so the placeholder
map is bound to it before sanitising.
Source code in packages/climate-ref/src/climate_ref/cli/test_cases/_stages.py
stage_compare(*, slot, paths, slug, expected)
#
Compare a slot's rebuilt bundle against the tracked committed baseline.
expected is the committed bundle's source of truth -- the filenames the manifest
records under committed. Every expected file must be present both in the tracked
regression/ baseline and in the slot's regenerated bundle, and must match within
tolerance; a file missing on either side, or an empty expected set, is a hard failure.
Driving the comparison from the manifest (rather than from whatever happens to exist on
disk) stops a replay reporting success when the committed baseline is absent or incomplete.
Both sides are already placeholder-sanitised, so no replacements are needed.
Returns (failures, compared) -- the drift/missing messages and the filenames compared.
Source code in packages/climate-ref/src/climate_ref/cli/test_cases/_stages.py
stage_execute(*, config, diag, tc, datasets, slot, execution_dir, clean)
#
Run the diagnostic and copy its curated native set (flat) into slot.
Source code in packages/climate-ref/src/climate_ref/cli/test_cases/_stages.py
stage_materialise(*, diag, tc, paths, manifest, store, slot, placeholders)
#
Fetch the manifest's native blobs into slot and rebuild the result from them.
Source code in packages/climate-ref/src/climate_ref/cli/test_cases/_stages.py
stage_rebuild_from_slot(*, diag, tc, paths, slot, placeholders)
#
Rebuild the execution result from native already present in slot.
Hydrates portable placeholders to concrete paths, then re-runs build_execution_result
so the rebuilt bundle is written into the slot (referencing the slot). No execution and
no store access.
This is the shared core of replay (after a fetch) and run --from-slot.
The slot is its own output directory, so the placeholder map is bound to it
(placeholders.with_output(slot)) before hydrating.
Source code in packages/climate-ref/src/climate_ref/cli/test_cases/_stages.py
stage_upload(*, slot, native, store, previous)
#
Upload native blobs to the store, skipping any whose digest is unchanged and present.
A blob is uploaded only when its digest differs from the previous manifest entry or the
store does not already serve it, so a re-mint after a bundle-only change (e.g.
mint --from-replay) uploads nothing. Returns digest-mismatch error messages
(empty on success).