Skip to content

test: repair two stale tests and run the Python suites in CI - #455

Merged
theGreatHerrLebert merged 1 commit into
mainfrom
fix/python-tests-and-ci
Sep 11, 2026
Merged

theGreatHerrLebert merged 1 commit into
mainfrom
fix/python-tests-and-ci

Conversation

@theGreatHerrLebert

Copy link
Copy Markdown
Owner

Why

Two Python tests were failing on main. Neither was a real defect — both asserted contracts that deliberate changes had already replaced. They survived because no CI workflow runs the Python suites: only rust.yml runs, and only for the crates. That same blind spot is why imspy-connector drifted 108 commits past its published version without anyone noticing.

The two tests

test_rt_cycle_length_raises_on_single_ms1 built its fixture by calling build_frame_tables_from_schedule with a single-MS1 schedule. The build-from-template schedule gate (f465dbc6) now rejects that at ingestion, so the setup line raised and the test never reached its assertion:

tests/test_template_acquisition_common.py:170: in test_rt_cycle_length_raises_on_single_ms1
    ft, *_ = C.build_frame_tables_from_schedule(...)
E   ValueError: template schedule has 1 MS1 survey(s); a valid DIA acquisition has >= 2

The gate is correct and already covered by test_schedule_gate_rejects_single_ms1. What this test exists for is the helper's own guard in rt_cycle_length_from_ms1, which the gate does not replace — that guard was silently untested. The frame table is now built directly so the guard is actually exercised, plus a second case for MS1 surveys sharing a timestamp, where every diff is zero and the cycle interval is equally undefined.

test_get_model_path called get_model_path('test_model') and asserted the returned path contained that name. True when the function merely joined a resource path; since models moved to lazy download (#381) it falls through to the hub, which resolves against a fixed registry and correctly refuses an unknown name. The test now asserts that refusal, plus a registry-membership check that every model the predictors ask for is present with a pinned hash.

Membership is asserted rather than resolution deliberately: on a wheel install, resolving a real model name downloads ~21 MB, which does not belong in a unit test.

The CI workflow

.github/workflows/python-tests.yml runs imspy-core, imspy-predictors and imspy-simulation on Python 3.11 and 3.12. It builds the connector from source first with default features — mirroring what the published wheels contain, and avoiding the vendor extractors' extra repositories — and installs CPU-only torch so the runner doesn't pull ~2 GB of CUDA wheels it has no GPU for.

It also carries a version-consistency job. The connector declares its version in both Cargo.toml and pyproject.toml, and maturin takes the wheel version from pyproject.toml. Bumping only Cargo.toml compiles the new version but emits a wheel labelled with the old one — PyPI rejects it as a duplicate, so the release publishes nothing while reporting success. That trap was hit during the v0.4.2 preparation and caught by hand; this job catches it automatically:

::error::imspy_connector version mismatch: Cargo.toml=0.4.2 but pyproject.toml=0.4.1
         (maturin uses pyproject.toml for the wheel version)

Verification

Green locally against the installed v0.4.2 artifacts:

Package Result
imspy-core 8 passed
imspy-predictors 287 passed, 6 skipped
imspy-simulation 148 passed, 15 skipped

The workflow YAML parses and the version guard was checked against both the current (passing) and the pre-fix (failing) state. The first run on this PR is what proves the runner steps themselves — if the install sequence needs adjusting, it'll show up there.

https://claude.ai/code/session_01532ckxwR1fUorKF7CN66uA

Both failures were tests asserting contracts that deliberate changes had
already replaced, left standing because no CI workflow runs the Python suites
— only rust.yml runs, and only for the crates.

test_rt_cycle_length_raises_on_single_ms1 built its fixture by calling
build_frame_tables_from_schedule with a single-MS1 schedule. The
build-from-template schedule gate (f465dbc) now rejects that at ingestion, so
the setup line raised and the helper's own guard — the thing the test exists to
cover, and which the gate does not replace — was never reached. The frame table
is now constructed directly. A second case covers MS1 surveys sharing a
timestamp, where every diff is zero and the cycle interval is equally
undefined.

test_get_model_path called get_model_path('test_model') and asserted the
returned path contained that name. That held when the function merely joined a
resource path; since models moved to lazy download (#381) it falls through to
the hub, which resolves against a fixed registry and correctly refuses an
unknown name. The test now asserts that refusal, plus a registry-membership
check that every model the predictors ask for is present with a pinned hash.
Membership is asserted rather than resolution: on a wheel install, resolving a
real name downloads ~21 MB per model, which does not belong in a unit test.

Adds .github/workflows/python-tests.yml running imspy-core, imspy-predictors
and imspy-simulation on 3.11 and 3.12, building the connector from source
first (default features, as the published wheels are built) and installing
CPU-only torch so the runner does not pull ~2 GB of CUDA wheels.

It also carries a version-consistency job. The connector declares its version
in both Cargo.toml and pyproject.toml, and maturin takes the wheel version from
pyproject.toml: bumping only Cargo.toml compiles the new version but emits a
wheel labelled with the old one, which PyPI rejects as a duplicate, so the
release publishes nothing while reporting success. That trap was hit during the
v0.4.2 preparation and caught by hand; this job catches it automatically.

Suites are green locally against the installed v0.4.2 artifacts: imspy-core 8
passed, imspy-predictors 287 passed / 6 skipped, imspy-simulation 148 passed /
15 skipped.

Claude-Session: https://claude.ai/code/session_01532ckxwR1fUorKF7CN66uA
@theGreatHerrLebert
theGreatHerrLebert merged commit 29ae3b8 into main Sep 11, 2026
5 checks passed
@theGreatHerrLebert
theGreatHerrLebert deleted the fix/python-tests-and-ci branch September 11, 2026 09:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant