Repository navigation
Release each YAML case's simulation and its file's reformed systems - #2742
Conversation
policyengine-core's YAML runner keeps every case's simulation, and a full system clone for each combination of dotted parameter inputs, until the process ends. On main the 5,235 YAML cases peaked at 16.5 GB and took 107 s to exit; on CI's 16 GB runners the job swaps and runs into its time limit after its tests pass (#2741, #2698). The conftest's teardown hook now drops each case's simulation and system, and a file's dotted-input systems after its last case. The same local run peaks at 1.7 GB and takes 188 s in all instead of 277. Remove it once policyengine-core releases the same (PolicyEngine/policyengine-core#569). Fixes #2741 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of fe22375: the peak files hold MiB, so the run peaked at 16.1 GiB on main and 1.65 GiB here, not 16.5 GB and 1.7 GB. The CI logs record no memory figures, so the comment now gives a memory shortage as the likely cause of the timeouts rather than a measured one, and adds this PR's CI YAML step (7 min 25 s). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Aggregate impact on certified data: passBase Checks: 0 broken by this change, 1 failing on both sides, 0 fixed. Moves flagged for review: 0 (thresholds in Notes
Moves flagged for reviewNone. Spending by benefit and service
Caseloads
Standard reform costings (change in gov_balance)
Standard reforms: change in each reform's target
Household net income by decileNo household's net income changes in any year. No change in any year: receipts by tax head; government balance, each component counted once; model totals; household income totals; population; poverty rates; people in poverty; inequality; mean household net income in each side's own deciles. Checks failing on both base and head (1)
Counted-once checkEach of 91 components was raised by £1 per unit in 2026-27, and every head of its totals was read household by household: its own head must rise by exactly £1, no other tax head may move, no other benefit may rise, and the model's own total must move by what its heads moved. A head that breaks a rule is measured again twice: with every other head held at its baseline value, and with every other head held at its value after the first £1 while the component rises again. It fails where either still shows the response. 0 failed; 0 were skipped.
Provenance
Dataset: Receipts by tax head: head levels
Spending by benefit and service: head levels
Caseloads: head levels
Government balance, each component counted once: head levels
Model totals: head levels
Household income totals: head levels
Population: head levels
Poverty rates: head levels
People in poverty: head levels
Inequality: head levels
Mean household net income in each side's own deciles: head levels
Standard reform costings (change in gov_balance): head levels
Standard reforms: change in each reform's target: head levels
|
|
This would help the queue running now. In merge-queue run 41082735340, the YAML job's runner received a shutdown signal at 16:07Z. No test failed, but The log stopped after This PR changes test infrastructure only: no model code, parameters or expected values. Its checks pass at |
|
Thanks for getting #2723, #2726 and #2545 through today. The merge queue ran #2700 left the queue at 23:09Z with no failed case. Its YAML job printed On current main ( This PR merges cleanly with main. @juaristi22, could it go into the queue ahead of #2700 and #2727? 🤖 Generated with Claude Code |
Fixes #2741
CI's
Test / YAMLjob takes 30 to 45 minutes on its 16 GB arm64 runner and often runs into its 45-minute limit after every test has passed. Memory is the likely cause: locally the run grows to 16.1 GiB, though the CI logs record no memory figures. This PR changes test infrastructure only: no model code, parameters or test expectations.Cause
policyengine-core's YAML runner (
policyengine_core/tools/test_runner.py, 3.33.12) keeps every case's state until the process ends:YamlItemkeepssimulationandtax_benefit_systemafter its case has run;_tax_benefit_system_cachekeeps a full clone of the system for each combination of dotted parameter inputs (gov.x.y: value) and never evicts one.PolicyEngine/policyengine-core#569 fixes both in core but is still a draft (open since 2 October; last update 15 October).
Change
The existing
pytest_runtest_teardownhook inpolicyengine_uk/tests/conftest.pynow callsrelease_yaml_case, which:simulationandtax_benefit_systemonce it has run;It touches nothing for other tests.
test_yaml_case_release.pychecks each of these. Its first test skips with a note to remove the workaround once core'sYamlItemgets its own teardown, and its last fails if core keeps the cache but changes its keys, since the release would then do nothing.Measured
Each row is one
policyengine-core test policyengine_uk/tests/policy -c policyengine_ukprocess on a Mac with memory to spare. The UK hub ran one pair back to back and the Sol review ran another. Peak RSS is the process group's, fromrun_capped.py's monitor, which samples every 0.25 s:In the review's pair, the whole-process times come out equal: subtracting pytest and post-summary time leaves about 82 s on main and 146 s on this PR, which the buffered logs do not attribute further. Memory and exit time move the same way in both pairs.
In CI, on the 16 GB arm64 runners, from the timestamps in each job's log:
Test / YAMLjob#2234's job ran the same morning; its 12 extra cases are its own Housing Benefit tests. On that job, pytest's timer covers under a third of the time between session start and summary, and where the rest goes is still open. Of 38 YAML jobs (first attempts) that started between 23:05Z on 28 Oct and 08:33Z on 29 Oct, 19 passed in 30 to 44 minutes and 7 hit the 45-minute limit; 12 more ended early (#2741).
Invariants
Checks run
test_yaml_case_release.py(5) andtest_variable_module_release.py(7): 12 passed.git diff --check: passed.Test / YAMLjob: 5,235 passed.test_yaml_case_release.py(5 passed), Ruff andgit diff --checkpass.axiom: n/a: test infrastructure only.
🤖 Generated with Claude Code