Skip to content

Test/round 3 test health - #11

Open
Squazz wants to merge 14 commits into
mainfrom
test/round-3-test-health
Open

Squazz wants to merge 14 commits into
mainfrom
test/round-3-test-health

Conversation

@Squazz

@Squazz Squazz commented Oct 21, 2026

Copy link
Copy Markdown
Owner

No description provided.

Squazz and others added 14 commits October 21, 2026 12:13
The build job now builds the image once, with the final VERSION build
arg, smoke-tests it, and pushes that image by docker tag + docker push
instead of rebuilding with build-push-action. The unit-test stage gets
the same VERSION so it shares the cached runtime layers (VERSION is in
the apk RUN's environment, so a different value re-ran apk). After the
push, each tag is pulled back and must have the smoke-tested image's ID,
so on a tag `latest` and `<version>` are the same image. A
workflow_dispatch trigger gives a dry run that never pushes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
run() called _check_old_releases() unguarded, so a bad
FETCH_TORRENTS_OLD_RELEASE_* value or an OSError saving the check state
skipped ratio logging, cleanup, the disk-usage limit and the run summary
on every daily run. Wrap it like the later steps. Counts set before a
part-way failure stay in the summary; a failure before any counts leaves
them None ("check not run").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DeriveScrapeUrlTests gains https cases and an 'announce' in a non-final
path segment; HTTP failure reasons and UDP action-3 errors with invalid
UTF-8 must still come back as readable errors. Each new case kills its
surviving mutmut mutant; no production change was needed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CONTRIBUTING.md and tasks/README.md now exempt only literals inside log
calls and exception messages; other literal survivors are triaged like
behavioural ones. Record the safe="" and configure_transmission ""
default survivors as accepted equivalents.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…k 42)

block_network() now also refuses socket.sendto, getaddrinfo and
gethostbyname, so a UDP tracker scrape or a DNS lookup can't leave the
machine. The guard tests close their sockets (clean under
-W error::ResourceWarning), and the logging timestamp test points its
stream handler at a StringIO instead of the real stderr.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
check_old_releases_for_demand() takes discovery= and run() takes
old_release_discovery=, so tests pass a mapping instead of patch.dict on
OLD_RELEASE_DISCOVERY. The old-release tests that patched our own
evaluate_old_release_demand()/_write_watch_file() are gone; each one's
behaviour is covered with only the network faked (OldReleaseTracker):

- evaluate: 404, download failure -> EvaluateOldReleaseDemandBoundaryTests;
  below threshold, kept, well-seeded -> sociable every-outcome test
  (thin/wanted) and HasUnmetDemandTests
- adds only unmet demand, distro without discovery, already present,
  unsafe name, recently checked, previously removed, due/no-demand
  recorded -> CheckOldReleasesSociableTests every-outcome test
- low-demand variant filtered -> OldReleaseRunTests (netinst)
- today defaults -> test_today_and_saved_state_default_to_now_and_empty
- failed writes -> CheckOldReleasesAtomicWriteTests over the real path,
  failing at the leaf via helpers.disk_full_open(only=)

The remaining scrape_torrent doubles carry a boundary-double comment.
Dropped test_fallback_applies_the_config_credential_rule (patched the pure
Config.rpc_auth) and the LOW_VALUE test_passes_configured_credentials;
folded the two no-credential cases into one table test.

Scoped mutmut (fetch_torrents.py lines covered by the three touched test
modules, full suite per mutant): 21 survivors of 442, a subset of HEAD's
23 of 443.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
auth is now a required keyword argument and None means "send no
credentials" instead of re-reading TRANSMISSION_RPC_* from os.environ;
both callers already pass config.rpc_auth. Drop the five tests that
only covered the env fallback; the run-level credential tests stay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- helpers.FakeHttp is the one routes-dict requests.get fake (404 default,
  records each request); RecordedPages and the moved OldReleaseTracker
  (plus swarm()) build on it. FakeWorld, the live_check tracker tests and
  the scrape fall-through test use it; the latter's expected requests now
  live in its cases table instead of an if.
- OldReleaseRunTests: one wiring test per old-release Config field (each
  with a swarm the default would decide the other way), plus saved state
  and the log/summary, instead of one 7-candidate scenario.
- route_ubuntu() is gone: test_counts_each_download_outcome sets up each
  outcome (and the pre-existing watch file) itself.
- MainWiringTests uses enterContext/addCleanup and drops the facts
  RunTests pins (RPC auth, keep-only-latest cleanup).
- New public fetch_torrents.reset_logging() (test-first) replaces the
  hand save/restore of _configured_handlers.
- Deleted 11 mid-range/duplicate twins in test_cleanup.py and 7
  hand-written page tests in test_fetchers.py that RecordedSnapshotTests
  covers; their naming rationale moved to RecordedSnapshotTests.

Coverage unchanged (99.13%). Scoped mutmut on fetch_torrents.py with the
three affected modules (test_cleanup, test_fetchers, test_scrapers) as
runner: identical survivor set before and after the deletions (592/1101
under that subset runner).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
scrape_torrent takes keyword-only resolve= (DNS) and udp_scrape= (the
BEP 15 round trip), defaulting to the real functions, and passes resolve
on to _is_safe_scrape_host, which now requires it. The tests inject fakes
instead of patching ts._resolve_addresses / ts.scrape_udp_tracker and
assert the returned outcome rather than call counts. Two wire tests run
the real defaults down to getaddrinfo and an autospec'd socket: a public
UDP tracker gets both BEP 15 requests, a private one gets no packet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
record() takes get= and out_dir=, main() takes now=, and wait_for() takes
clock=/sleep=/timeout= (monotonic, like wait_for_transmission_rpc). New
tests check ENDPOINTS against the recorded fixtures, record()'s output and
error pass-through, main()'s distro filter, wait_for()'s success/timeout
paths and make_torrent()'s structure. helpers.load_script() and
helpers.FakeClock are shared with test_live_check and test_daily_run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
drift.yml's setup-python steps use a workflow-level PYTHON_VERSION of
3.14, the test job's minor, with comments in both files to bump them
together. The test job runs a pinned rhysd/actionlint:1.7.12 image over
.github/workflows/ (no ignores); CONTRIBUTING.md and .claude/CLAUDE.md
list the command.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Full mutmut runs under task 41's narrowed rule (only log and exception
  message literals excluded):
  - fetch_torrents.py 99.0% (1063/1074), critical set 99.2% (259/261)
  - torrent_scrape.py 99.2% (252/254)
  - configure_transmission.py 91.8% (90/98)
  Every counted survivor is an accepted equivalent.
- Killed 14 fetch_torrents survivors the wider rule had hidden: distro to
  fetcher and old-release discovery wiring, the field each invalid number
  is reported and enforced under, no warning for an unset
  FETCH_TORRENTS_DISTROS, the /logs default and the logger name.
- Removed two equivalents by simplifying the code (an unused temp-file
  suffix, a download_path default that run() always overrides). Accepted
  four new ones with reasons.
- 522 tests, 100% branch coverage (fail_under stays 99), Farley 8.40.
- Add docs/seeding-policy.md: when an ISO is fetched, kept, removed or
  re-seeded, each rule naming its tests. A hygiene test checks that the
  named tests exist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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