Split the tongs and anvil test modules to mirror their packages - #40
Merged
Conversation
`test_tongs.py` had grown to 1900 lines covering every module in `swarmforge/tongs/`, so a change to one concern meant opening a file mostly about the other eight. It now mirrors the package: one `test_tongs_<module>.py` per source module, so the file that covers a change is the one named after it. Test bodies are unchanged. The only class that moved is the block of `tong_mount_specs` and `workspace_mount_placements` cases that had accumulated inside `DockerArgvTests`; they exercise `mounts`, not `argv`, and are now `MountSpecTests` alongside the rest of the mount grammar. Tong definitions more than one module needs -- and the `def_of` helper that parses them -- move to `tests/tongs_fixtures.py`. The discovery glob is `test_*.py`, so the fixtures module is not collected as a suite of its own; ones used by a single module stay with it.
Same treatment for the launcher's 1900-line `test_run_anvil.py`: one `test_anvil_<module>.py` per module in `swarmforge/anvil/`, so the orchestration tests stop sharing a file with argument parsing and the docker wrapper. Test bodies are unchanged and every class keeps its name. The passthrough invariant -- no tongs discovered means the anvil argv is exec'd byte-for-byte -- now lives in `test_anvil_cli.py`, next to the other cases that drive `bin/run-anvil` as a subprocess. `ANVIL_ARGV` and the `_merged` helper are needed by more than one of the new modules and move to `tests/anvil_fixtures.py`, which the `test_*.py` discovery glob skips. `readiness` gets no file of its own: it is covered through `run_with_tongs`, and an empty module would only claim otherwise.
Two package docstrings named test files that no longer exist, and neither the README nor AGENTS.md said where a given test now lives. Both now state that a test module is named for the source module it covers, and name the fixture modules the discovery glob deliberately skips, so nobody adds a `test_`-prefixed helper and wonders why it runs. The README also names the two anvil modules with no test file of their own -- `readiness`, exercised through `run_with_tongs`, and `errors`, which is one exception class -- so the naming rule does not read as a promise the tree does not keep.
Splitting the suites introduced `tongs_fixtures` / `anvil_fixtures` as sibling modules, imported by name. Discovery and `python3 tests/<file>.py` both put the tests directory on `sys.path`, but `python3 -m unittest tests.<module>` puts only the repo root there -- so running one split file that way failed on the fixture import, while an untouched file like `test_git_guard` still worked. Put the tests directory on the path alongside the repo root in every file that imports a fixture module. Also drop the module-level `import shutil` from the approval tests: the one use it had went to the orchestration tests, and the `tearDown` left behind imports `shutil` locally.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
tests/test_tongs.pyandtests/test_run_anvil.pyhad each grown past 1900 lines, covering every module of the package they tested. A change to one concern meant opening a file mostly about the other eight. Both now mirror the package they cover: a test module is named for the source module it exercises, so the file that covers a change is the one named after it.Two anvil modules get no file of their own, and the README says why rather than leaving the naming rule reading as a promise the tree does not keep:
readinessis exercised throughrun_with_tongs, anderrorsholds one exception class.Nothing about the tests changed
Every test body is byte-identical to what it replaced, verified by comparing the source text of all 423 functions, methods, constants, and fake classes between the old files and the new ones. The suite collects the same 495 tests and passes.
One class did move. The
tong_mount_specsandworkspace_mount_placementscases had accumulated insideDockerArgvTests; they exercisemounts, notargv, and are nowMountSpecTestsalongside the rest of the mount grammar. The bodies are unchanged — only the enclosing class name.The passthrough invariant — no tongs discovered means the anvil argv is exec'd byte-for-byte — is still asserted, now from
tests/test_anvil_cli.pynext to the other cases that drivebin/run-anvilas a subprocess. The docstring inswarmforge/anvil/__init__.pythat points at it was updated to match.Shared fixtures
Tong definitions and stubs that more than one test module needs live in
tests/tongs_fixtures.pyandtests/anvil_fixtures.py. Thetest_*.pydiscovery glob skips them, so they are not collected as suites of their own; fixtures used by a single module stay with it.Because those are sibling modules imported by name, the tests directory has to be on
sys.path. Discovery andpython3 tests/<file>.pyboth put it there;python3 -m unittest tests.<module>does not, so every file that imports a fixture module puts it there itself. All three invocation forms work for all 15 files.No new dependencies — still stdlib only.