Skip to content

ci: a hung test module fails inside its pass under a session timeout (#447) - #449

Merged
Blind-Striker merged 1 commit into
masterfrom
ci/test-session-timeout
Oct 17, 2026
Merged

Blind-Striker merged 1 commit into
masterfrom
ci/test-session-timeout

Conversation

@Blind-Striker

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

Copy link
Copy Markdown
Collaborator

What

Every CI test pass now runs under a 25-minute session --timeout, so a hung test module fails inside its step instead of at the job timeout. A failed main pass also writes its test listing, which narrows the rows that were still in flight. For #447.

Why

In #442's run 39031358513, the Linux OpenCode.Sdk.Tests net11.0 module hung for about 50 minutes. Without a TRX, nothing named the row, and it did not reproduce in four configurations on dev-01 (#447).

What it does, and what it does not

What it does. The guard fails inside the step and narrows the search.

What it does not do. It does not name the row in flight. Measured locally with --timeout 8s on OpenCode.Sdk.Tools.Tests:

  • The step exits 7, with "Test session was aborted; recovered 856 test result(s) from the TRX streaming sidecar (additional results that were in flight at termination time may be missing)".
  • The TRX keeps the 856 finished rows plus a RunInfo saying the host was terminated because the session was aborted.

Hence the listing. When the main pass fails, dotnet test --list-tests with the same filter writes test-results/main/listed-tests.txt, and the existing test-results artifact uploads it. The rows in flight are among those listed but not recorded in the TRX. Rows queued behind a hung NotInParallel key are in that set too, so the listing narrows the search but does not name one row.

Two command-line details, checked locally:

  • --list-tests goes before --. Passed through to the test host, it fails the handshake ("reported execution mode 'discover', but 'dotnet test' expected 'run'").
  • It honours the tree filter: OpenCode.Sdk.Tools.Tests lists 2033 tests, the same count as CI's main pass.

If #447 recurs and the listing does not name the row, the next step is Microsoft.Testing.Extensions.HangDump, which names the tests in flight. It is a test-side package, so it needs a dependency decision; it is noted on #447.

Sizing

The timeout is about four times the slowest measured module. These are the slowest per-module times in two green master runs, 39022831816 and 39025318239:

OS Slowest module Times
Windows OpenCode.Sdk.Tests net472 5m39s, 5m51s
macOS OpenCode.Sdk.Tests net10.0 5m21s, 3m43s
Linux OpenCode.Sdk.Tests 3m37s, 3m46s

5m51s × 4 is about 23 minutes, so 25 minutes. The election and native AOT passes take the same bound. Each runs a single module far shorter than the main pass.

Canon

docs/engineering/quality-gates.md, next to the roster paragraph, now states the bound, its measurement, exit code 7, and that the timeout does not name the rows in flight. The workflow comment points to it.

Proof

  • Local check: GATE PASS on f2e4457f (master cf62b17a): all 8 steps, and 10,482 tests with 0 failed. The local gate does not run ci.yml, so this shows only that nothing else regressed.
  • This PR's CI is the proof that the flag parses on all three OSes. On a green run the listing step is skipped.

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

…447)

Each test pass runs with a 25-minute --timeout, about four times the slowest
measured module, and a failed main pass also writes its test listing, so the
rows still in flight are among those listed but not recorded.
@Blind-Striker
Blind-Striker added this pull request to the merge queue Oct 17, 2026
Merged via the queue into master with commit 695c555 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