Skip to content

runner: tests check the Runner's order and the ends it counts (P1R-C04 follow-up) - #106

Merged
novelKR merged 1 commit into
mainfrom
claude/p1r-c04-reconcile-barrier-bodbv6
Oct 15, 2026
Merged

novelKR merged 1 commit into
mainfrom
claude/p1r-c04-reconcile-barrier-bodbv6

Conversation

@novelKR

@novelKR novelKR commented Oct 15, 2026 •

Copy link
Copy Markdown
Owner

Issue

Part of #101: a follow-up to #105 (P1R-C04). This PR does not close an issue.

Item Value
Base main at 385e177, with P1R-C04 merged
Head 41db94c
Pins Codex gitlink with its recorded patch, and DevGuard 6e7e065; both unchanged

Summary

Before: after #105 merged, main CI run 38708302887 failed once in the macOS stage, in cargo test -p codespace-runner --features devguard --lib -- registration wire admission launch independent lifecycle. Its one re-run passed. The job log does not name the failing test (the stage's output is only in the run's artifact).

After: the two kinds of test that can fail that way now check what the Runner actually orders and counts. Only tests change.

  • Registration before the next Claim. Looping that command here failed once in 25 runs, in wire::tests::registration::an_independent_runner_answers_registration_before_the_next_claim (registered_at <= claimed_at). With 8 copies at a time it failed 43 of 120 runs. The test compared the moments two test tasks read two answers on two connections. The Runner orders only its writes: it answers the registration, lets go of control, then grants the next Claim. The test now reads the Claim's answer first and checks, with FIONREAD, that the registration's answer already waits on the first connection.
  • A process's end. Five tests that runner, server, store: reconcile the independent Runner per workspace (P1R-C04) #105 added or changed waited for a process's root to exit, then asserted what the Runner does once the process ended. The Runner counts a process as ended once its output ended too: that starts its retention, makes an acknowledgement count and numbers its exit event. The output can end later, when a child that another test spawns holds the pipe until its exec, which is slow on macOS for a new executable (see descriptors.rs). The retention tests now wait for the end of the output, and the two Claim tests wait until the Runner numbered the exit.

Which test failed on macOS is not known. Of these, only the registration test failed in the loops here.

Contract changes

None. Only tests change.

Tests

Case Result
Registration test, 8 at a time 160 of 160 passed (on main: 43 of 120 failed)
Registration test with the Runner changed to let go of control before the registration ends (not committed) Fails: "the Claim was granted before the registration was answered"
Output held 0.5 to 1 s past the exit by a background sleep (not committed), main's tests 4 fail: drops_the_oldest… (3 slots occupied), keeps_an_ended_process… (1 slot occupied), evicts_an_acknowledged… (still found after the retention time), a_lost_connection… (events_through 0, not 1)
Same delay, this PR's tests All pass

Verified here (Linux, root, cloud):

  • cargo fmt --check; clippy -D warnings on the root workspace, and on codespace-runner with and without devguard, all targets.
  • codespace-runner --lib with the worker, patch and Linux sandbox helpers: 152 passed in 5 runs. A first run right after the build failed once in process::tests::a_failing_observer_does_not_hold_the_child (its 1 s bound); this PR does not touch that test.
  • codespace-runner --features devguard --lib: 193 passed, with the known root-only launch::tests::nothing_is_committed_when_the_owner_cannot_launch skipped.
  • The macOS stage's filtered command: 12 of 12 runs passed.

Not verified here: hosted macOS (this PR's CI runs it).

Security scenarios

No product code changes. The new test helper reads a socket's unread byte count with ioctl(FIONREAD) in the test process only.

Out of scope

  • Product behavior stays as merged. The Runner still ignores an acknowledgement for a process whose root exited but whose output has not ended. The gateway acknowledges again on the exit event, or the next Claim does, so that process stays at most until then.
  • The 1 s bound in process::tests::a_failing_observer_does_not_hold_the_child.
  • Printing a failed stage's log in the CI job log, which would name the test next time: a CI change for the owner to decide.

The macOS stage of main CI after #105 failed once in the Runner's
DevGuard tests, and its re-run passed. Looping those tests here found
one that fails about 1 run in 25, and 43 runs in 120 with 8 at a time:
an_independent_runner_answers_registration_before_the_next_claim
compared the moments two test tasks read the registration's answer and
the next Claim's answer, while the Runner only orders its writes. It
now takes the Claim's answer first and checks that the registration's
answer is already waiting on the first connection.

Five tests that #105 added or changed took a process's exit for its
end. The Runner counts a process as ended once its output ended too:
that starts its retention, makes an acknowledgement count and numbers
its exit event. The output can end later, when a child that another
test spawns holds the pipe until its exec, which is slow on macOS for
a new executable. The retention tests now wait for the end of the
output, and the two Claim tests wait until the Runner numbered the
exit.

Only tests change.

Co-Authored-By: Claude Opus 5.5 (1M context) <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.

2 participants