fix(qa): the instance tests could pass an image they never exercised (L082-L086) - #263
Open
robballantyne wants to merge 1 commit into
Open
fix(qa): the instance tests could pass an image they never exercised (L082-L086)#263robballantyne wants to merge 1 commit into
robballantyne wants to merge 1 commit into
Conversation
…(L082-L086) An audit of all 47 shipped instance tests (~8,750 lines) found 23 verified defects across 16 files, collapsing to 8 root causes. These run on rented GPUs, so each one costs a full rebuild cycle to discover the slow way. They are fixed here in one batch, and the shapes that produced them are codified so the next instance is a red diff rather than a red cell. THE FALSE GREENS — an image that ships broken and reports fine — come first. `service_running` reports a supervisord STATE, but seven call sites used it as an `if` guard: `if service_running x && wait_for_port p; then … else skip; fi`. That collapses "not configured", "RUNNING but never bound its port" and "supervisord has never heard of it" into one silent pass. A jupyter that hangs without exiting binds nothing and the suite reported ALL TESTS PASSED; autorestart catches CRASHES, so the hang is exactly the state nothing else covers. New `assert_service_serving NAME PORT` fails on either half. The first version of that fix decided "expected" from /etc/supervisor/conf.d/NAME.conf alone, and a pre-build review caught that it would have BROKEN THE BUILD. syncthing.conf and tensorboard.conf ship unconditionally in base, but 5 of the 7 QA templates carry no portal entry for them, so exit_portal.sh correctly exits 0 and the service sits EXITED by design — a 60s wait and a hard fail on a healthy image. runner.sh skips the whole derivative phase on any base/* failure, so it would have reddened every derivative QA cell. base-qa and pytorch-qa list every entry, which is precisely why it looked safe when only base was considered. The predicate is now configured AND routed AND not-serverless — the same one 65-conditional-services already used, which also resolves base/67 and base/85 asserting opposite verdicts about the same six programs. Also false-green: `wait_for_caddy_ports || echo WARN` then falling through to test_skip, in the two files whose own comments say that wait is what makes the skip trustworthy — and which use `|| test_fail` at six other call sites. A check named `bind-loopback` that passed 172.17.0.2 (the docker bridge, reachable by co-tenant containers) because it enumerated the bad forms instead of requiring the good ones. runner.sh reporting "passed" when discovery found zero tests, upstream of the required-tests check. And runner.sh's OPEN_BUTTON_TOKEN guard running AFTER wait_for_client, so the results server sat unauthenticated on a mapped port for exactly the window the guard exists to close. CHECKS THAT COULD NOT FIRE. runner.sh's zero-test guard was unreachable: `printf '%s\n'` on an empty array emits one BLANK LINE, so mapfile yielded len=1 and the runner would log "Discovered 1 tests" and exec `bash ""`. 12-provisioning's stall detector word-matched cmdlines including `provisioner`, which matches the provisioner ITSELF — pinning activity true for the whole of a hang, the one state it exists to detect (and matching 11 unrelated processes on this host). 15-boot-markers' `grep -q "PATH="` was satisfied by TCLLIBPATH=. 27-caddy-tls grepped lowercase for openssl's capital-V "Verify return code", so the cert ALWAYS reported untrusted. FALSE REDS, which cost redraws and block promotes. `pidof caddy` matches transient `caddy hash-password` (cost-14 bcrypt, 43s measured) and returns "P1 P2", a string that can never appear in an ss row — a healthy image failing with "no listening sockets". llama.d/10's health-wait had a terminal catch-all, so a failed supervisorctl invocation and normal in-flight BACKOFF both hard-failed, partly defeating the file's own restart tolerance. 56-cpu-thread-limits wrote without pinning $WORKSPACE, so a user thread var in the real workspace made it report a WIRING failure. The sglang and vllm serving tests hardcoded port 18000 while their sibling contract tests derive it from *_ARGS — a moved port meant polling a dead socket for an hour. llama.d/11 declared TEST_TIMEOUT=1800 and then waited 3600s, so it could only ever be killed and reported as a bare timeout naming no check. FIVE RULES, so the classes stop recurring: L083 (fail_later arity), L084 (curl status fallback), L085 (TEST_TIMEOUT covers its waits), L086 (RUNNING is not serving), and L082 TIGHTENED to reject a bare `$4` — which is exactly how 67's awk passed lint while reporting the first listener on the box after shell quoting destroyed its program. Two of those rules shipped BROKEN and were caught before merge, which is the argument for running a rule against real input rather than reasoning about it. L084 was INERT against the two-line form it was written from — capture and fallback sit either side of a line continuation — while FIRING on correct code where `|| echo WARN` belonged to a later statement. The arity counter ran past `;`, ignored single quotes, and my first rebuild broke `$( )` inside double quotes. A rule that cannot fire is decoration; one that fires on correct code is worse than none. Scope: base ROOT plus the shared derivative suites. The unsloth-studio work and its image-specific rules (L081, the amended L056) are deliberately NOT here — both depend on a Dockerfile that is not on this branch and would red-light the two studio images. Evidence: 1032 passed, 9 skipped; baseline CLEAN across 27 images; every fix verified against the real defect (the ss peer column, the empty-array printf, the 000000 capture, the promiscuous pgrep) rather than reasoned about.
robballantyne
requested a deployment
to
production
August 28, 2026 18:00 — with
GitHub Actions
Waiting
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.
An audit of all 47 shipped instance tests (~8,750 lines) found 23 verified defects across 16 files, collapsing to 8 root causes. These run on rented GPUs, so each costs a rebuild cycle to find the slow way. Fixed here in one batch, with the shapes codified so the next instance is a red diff rather than a red cell.
Base ROOT + the shared derivative suites only. The unsloth-studio work is deliberately not here.
False greens — an image ships broken and reports fine
service_runningused as anifguard, 7 sites. It reports a supervisord state, soif service_running x && wait_for_port p; then … else skip; ficollapses "not configured", "RUNNING but never bound its port" and "supervisord has never heard of it" into one silent pass. A jupyter that hangs without exiting binds nothing and the suite reported ALL TESTS PASSED —autorestartcatches crashes, so the hang is exactly the state nothing else covers.The predicate is now configured AND routed AND not-serverless, which
65-conditional-servicesalready used — and which also resolvesbase/67andbase/85asserting opposite verdicts about the same six programs.Others:
wait_for_caddy_ports || echo WARNfalling through totest_skip, in the two files whose own comments say that wait is what makes the skip trustworthy (and which use|| test_failat six other call sites). A check namedbind-loopbackpassing172.17.0.2— the docker bridge, reachable by co-tenants — because it enumerated the bad forms instead of requiring the good ones.runner.shreportingpassedon zero discovered tests, upstream of the required-tests check. And itsOPEN_BUTTON_TOKENguard running afterwait_for_client, leaving the results server unauthenticated on a mapped port for exactly the window the guard exists to close.Checks that could not fire
runner.shzero-test guardprintf '%s\n'on an empty array emits one blank line →mapfilelen=1 → "Discovered 1 tests" →bash ""12-provisioningstall detectorprovisioner, matching the provisioner itself — pinned true for the whole of a hang, the one state it exists to detect (and 11 unrelated processes on this host)15-boot-markersgrep -q "PATH="satisfied byTCLLIBPATH=27-caddy-tlsVerify return code— the cert always reported untrustedFalse reds — these cost redraws and block promotes
pidof caddymatches transientcaddy hash-password(cost-14 bcrypt, 43s measured) and returns"P1 P2", a string that can never appear in anssrow — a healthy image failing "no listening sockets".llama.d/10's health-wait had a terminal catch-all, so a failedsupervisorctland normal in-flightBACKOFFboth hard-failed, partly defeating the file's own restart tolerance.56-cpu-thread-limitswrote without pinning$WORKSPACE. The sglang/vllm serving tests hardcoded 18000 while their sibling contract tests derive it from*_ARGS.llama.d/11declaredTEST_TIMEOUT=1800then waited 3600s — it could only ever be killed and reported as a bare timeout naming no check.Five rules
L083fail_later arity ·L084curl status fallback ·L085TEST_TIMEOUT covers its waits ·L086RUNNING is not serving ·L082tightened to reject a bare$4— which is exactly how67's awk passed lint while reporting the first listener on the box after shell quoting destroyed its program.Two of these shipped broken and were caught before merge, which is the argument for running a rule against real input rather than reasoning about it.
L084was inert against the two-line form it was written from while firing on correct code. The arity counter ran past;, ignored single quotes, and my first rebuild broke$( )inside double quotes.Evidence
1032 passed, 9 skipped;baseline CLEAN ✓across 27 images. Every fix verified against the real defect — thesspeer column, the empty-arrayprintf, the000000capture, the promiscuouspgrep— rather than reasoned about.Note for the reviewer
Group 1 is the change that could turn currently-green base cells red on real hardware. It wants a live base + pytorch promote from this branch before merge, not a merge first.