tests.test_runner_sync module

sync-runner-images proposes the right change, and only when there is one.

Every case runs against a hand-built catalog rather than the live table, so the suite never reaches the network and a GitHub restyle cannot turn these red for a reason unrelated to the logic under test.

tests.test_runner_sync.test_deprecated_label_moves_to_a_released_successor()[source]

A dying image moves onto released ground, and says where it is used.

Return type:

None

tests.test_runner_sync.test_a_same_version_flavour_is_never_an_upgrade()[source]

windows-11-vs2026-arm is a different toolchain, not a newer image.

The distinction is the whole reason the upgrade rule keys on version: both rows are “Windows 11 Arm64”, so novelty alone would propose a migration that buys nothing.

Return type:

None

tests.test_runner_sync.test_a_strictly_newer_version_is_proposed_as_a_probe()[source]

An upgrade joins the matrix without anything being bet on it.

Return type:

None

tests.test_runner_sync.test_an_upgrade_moves_the_jobs_naming_the_old_image()[source]

A literal is the one runs-on: no probe reaches, so the upgrade moves it.

Return type:

None

tests.test_runner_sync.test_a_successor_already_in_the_fleet_is_moved_onto_but_never_probed(tmp_path)[source]

One job left behind still moves, without un-gating the current image.

A repository whose matrix already runs ubuntu-26.04, and which keeps a single job on ubuntu-24.04, gets that job moved: it is the half no probe can do. The probe half is dropped, since writing an unstable entry for an image already in the matrix marks every ubuntu-26.04 cell continue-on-error, turning the repository’s own gating column advisory.

Return type:

None

tests.test_runner_sync.test_running_the_newest_proposes_nothing()[source]

The quiet steady state: nothing to say about a current fleet.

Return type:

None

tests.test_runner_sync.test_ignored_labels_are_never_proposed()[source]

A declined proposal stays declined across regenerations.

Return type:

None

tests.test_runner_sync.test_an_unreadable_catalog_proposes_nothing()[source]

Fail closed: no table means no successor can be trusted.

Return type:

None

tests.test_runner_sync.test_a_withdrawn_label_is_left_to_actionlint()[source]

A label the table no longer carries is not reported here.

actionlint already fails the Lint workflow on an unknown runner label, at the matrix axis as well as at a literal runs-on:, so a second report would duplicate a stronger check. Nothing here can name a replacement anyway: the row is gone, and its family and architecture with it.

Return type:

None

tests.test_runner_sync.test_apply_literal_rewrite_touches_literals_only(tmp_path)[source]

Quoting survives, expressions are left alone, and a re-run is a no-op.

Return type:

None

tests.test_runner_sync.test_apply_upgrade_writes_sections_not_inline_tables(tmp_path)[source]

The probe lands as real sections and re-applies as a no-op.

Return type:

None

tests.test_runner_sync.test_apply_upgrade_is_idempotent_against_the_formatter_shape(tmp_path)[source]

Re-reading what format-pyproject leaves behind finds the probe present.

The applier writes sections; the formatter normalizes them into dotted keys under [tool.repomatic], and tomlrt cannot emit that form itself. What stops the two rewriting each other on every push is that the dotted shape reads back as the same nested value, so a second apply writes nothing.

The fixture is the formatter’s real output.

Return type:

None

tests.test_runner_sync.test_apply_axes_retirement_moves_the_curated_tuple(tmp_path)[source]

The axes move as text, keeping their comments and their ordering.

Return type:

None

tests.test_runner_sync.test_change_table_carries_the_reasoning()[source]

The body says why, not just what, and names what was passed over.

Return type:

None

tests.test_runner_sync.test_change_table_names_both_halves_of_an_upgrade()[source]

A reviewer sees the jobs that move and the cell that joins the matrix.

Return type:

None

tests.test_runner_sync.test_every_change_explains_itself(kind)[source]

No proposal is made without a reason a reviewer can act on.

Return type:

None