Skip to content

[RT-E6] test: characterize the launcher's spawn request and Windows strategy - #407

Merged
Blind-Striker merged 1 commit into
masterfrom
feat/rt-e6-char-launcher
Oct 17, 2026
Merged

Blind-Striker merged 1 commit into
masterfrom
feat/rt-e6-char-launcher

Conversation

@Blind-Striker

@Blind-Striker Blind-Striker commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

What

Characterization tests for the launcher behaviour that RT-E6 (one child-process core for Hosting) moves or rewrites. Test-only. They pin today's observable behaviour, so that RT-E6 can show "no behaviour change" (operating rule: characterization before a refactor where coverage is thin, Hosting/Platform).

Pinned

  • OpenCodeServerSpawnRequestTests (new). Through StartWithSeamsAsync, with a recording spawn on each platform's strategy and a rooted command:
    • the NUL refusals for command entries and environment entries, with their exact messages, before any spawn;
    • the argv tail --stdio --port 0 after the supplied arguments (on Windows, the command line, the application path and the suspended start);
    • a fresh 43-character base64url OPENCODE_PASSWORD on every start, which replaces a caller's entry;
    • stderr inherited only for the host's OPENCODE_PRINT_LOGS=1, with stdin and stdout piped;
    • the spawn-failure text with and without the working directory (a blank directory is passed as null).
  • WindowsServerChildTests (new):
    • the Windows strategy's spawn-failure text, with and without the resolution and the directory (U3-11), carrying the same inner exception;
    • on Windows, an exit-watch failure: it ends the real child with code 1, closes the offered handle, and reports the exact adoption-failure text. This is a new proof beside the existing TreeKill = null! test; no existing method moves (U3-24's placement stays with TST-E4).
  • WindowsExitWatchTests: one more row. Exit code 259 is reported as 259. RT-E6 step 4 moves the contender onto this watch to fix U4-01.
  • PosixSignalNamesTests: the host's signal table (NameOf(10) is SIGBUS on macOS and SIGUSR1 elsewhere). Step 6's single OS owner rewrites that selection.

Not pinned, on purpose

  • Known defects: Launcher NUL refusal reports ParamName 'start' instead of the public 'options' #401 (the NUL refusal's ParamName is "start"; the message is pinned and the parameter name is not) and A NUL in a bare launcher command name reports 'not found on PATH' instead of ArgumentException #400 (a NUL in a bare command name; the tests use rooted commands). RT-E6 fixes both, red to green.
  • Intended RT-E6 changes: the U3-16 signal spelling and U4-01/02/09/12/13/14.
  • C9, the Windows handle census on three more start paths, was dropped with evidence. The path where stdout closes before readiness needs a stand-in that really closes its stdout. Bun keeps its own stdout handle on Windows (tests/OpenCode.Sdk.ServiceFixture/WindowsLauncherProbe.cs:23-25), so bun -e stand-ins cannot reach it. RT-E6 step 3 owns those census paths and uses the native fixture mode (internal record: RT-E6 characterization inventory, "C9 outcome").

Placement

  • Every test lives in a Hosting/** test class whose file does not move in TST-E7.
  • Only NSubstitute, private nested fakes and root helpers are used; none is an E7-3a mover.
  • Each new class builds its seams in one private factory, so RT-E6's diff touches only the factories.
  • The seam clock is a ManualTimeProvider; nothing arms a timer before the spawn fails. Real-clock sites in the tests do not grow.

Proof

  • Mutation. 15 product mutants, each of which builds, and each turns exactly its own test or row red on net10.0:
    • C1: the NUL texts (executable, argument, environment name, environment value), the dropped --port, a 31-byte password, both print-logs inversions, and the directory suffix with its blank-directory rule;
    • C2: both spawn-failure texts and the adoption text;
    • C7: 259 mapped to 258;
    • C8: the table selection swapped.
  • Runs: every class passes on net10.0 and net472 (75/75 each). The POSIX arms of C1 and C8 run on CI's Linux and macOS legs.
  • Build and checks: the full build is 0/0 on every TFM; both format passes; verify-clones 0 new; the repository guards pass; slopwatch is clean.
  • Local check: stacked with the contender characterization at 70eef249, both branches on master 78d47a16 with E7-3a in. Every step passed for this branch: slopwatch, build, both format passes, clone-detector, verify-clones and election. The tests step ran 10,146 tests. Its only failure was the collapsed-assertion guard on two sites in the contender PR's new file, which that PR fixes; nothing failed in this branch's files.
  • Reviews: the Runtime coordinator, who changed the two seam clocks to ManualTimeProvider and removed a racy before/after compare of the process-global WindowsExitWatch.LiveWatches (the session leak guard covers it); then a fresh read-only Sol review.
    • Sol found one blocker: the Windows command-line expectation was computed with the same ProcessArgumentComposer that production uses. It is now a fixed literal.
    • Sol's should-fix: C2's fake now terminates the real child and closes its thread, pipes and process if observation setup throws after the spawn.
    • Both are fixed, and both classes pass again on net10.0 and net472.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

…ahead of RT-E6

Pins today's observable behaviour that RT-E6 moves: the door's NUL refusals
(message only; #401's ParamName and #400's bare-name path stay unpinned), the
argv tail, the per-start password, the print-logs stderr route, the spawn
failure and working-directory text, the Windows strategy's spawn and adoption
failures, exit code 259 through the Windows watch, and the host signal table.
@Blind-Striker
Blind-Striker added this pull request to the merge queue Oct 16, 2026
Merged via the queue into master with commit 9af91d1 Oct 17, 2026
12 checks passed
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