Skip to content

test(CM0001): observe a cancelled request's disconnect off the thread pool; overwrite test-result artifacts on re-run - #573

Merged
Arthurvdv merged 2 commits into
mainfrom
fix/cm0001-cancellation-test-disconnect-observation
Sep 28, 2026
Merged

Arthurvdv merged 2 commits into
mainfrom
fix/cm0001-cancellation-test-disconnect-observation

Conversation

@Arthurvdv

Copy link
Copy Markdown
Member

Summary

Fixes the flaky CancelledCompilation_ClosesHttpRequestPromptly_AndNextCompilationRecovers test in ALCops.Common.Test and the stale "Test results" check after a single-leg re-run. Both surfaced on #571 (run 36340330338), which does not touch Common; the failure is unrelated to that PR.

What happened

  • Attempt 1, leg 12.1.13.35966: the test took exactly 2 s and only closedPromptly failed. next was empty and RequestCount == 2 passed, so cancellation had propagated and nothing was cached. The 2 s Task.Delay race won on a slow shared runner.
  • The re-run (attempt 2) passed the test in 10 ms, yet the check still showed the failure and listed every trx twice: the run held two test-results-12.1.13.35966 and two test-results artifacts (one per attempt). download-artifact picked up the attempt-1 per-version artifact, so even the attempt-2 unified artifact contained the failing trx, and dorny downloaded both unified artifacts.

Mechanism

Cancel() runs the linked-token registrations inline (test token → SDK linked CTS → HttpClient linked CTS → HttpConnection.Dispose), so the client socket is closed before Cancel() returns. The fake server observed that with ReadAsync plus a RunContinuationsAsynchronously completion feeding Task.WhenAny, which needs more thread-pool hops than the timer it raced. On a saturated pool the timer wins although the close was immediate.

Changes

  • Test: the stalled request's disconnect is observed with a blocking NetworkStream.Read on a LongRunning task that sets a ManualResetEventSlim; the test waits on that signal. The 2 s window and every assertion are unchanged. The blocking read is bounded by the server's shutdown budget because the shutdown token cannot interrupt it.
  • CI: overwrite: true on the per-version and unified test-result uploads in build-test.yml, so a re-run replaces the same-named artifact.
  • Docs: testing.md (Concurrent synchronous HTTP tests), the CM0001 rule doc test notes, and release-strategy.md (Test report gate) record the why.

Verification

  • Best-effort local repro of the original test under DOTNET_ThreadPool_MinThreads=2 / MaxThreads=3: 20/20 passed, so the flake did not reproduce on this Windows machine. The fix rests on the mechanism above and the attempt-1 log evidence.
  • Fixed test under the same pressure: 20/20 passed. Whole ALCopsSettingsRemoteRecoveryTests fixture without pressure: 10/10 runs passed. Full ALCops.Common.Test suite: 159 passed.
  • dotnet format ALCops.sln --verify-no-changes clean; Validate-Rules.ps1 OK.
  • The re-run path can be checked on this PR's own run: re-run one test leg and confirm the artifact list holds one artifact per name and the check lists each trx once.

🤖 Generated with Claude Code

Arthurvdv and others added 2 commits September 28, 2026 13:35
… pool

The cancellation test raced the fake server's ReadAsync-based disconnect
observation against a two-second Task.Delay. The client closes its socket
synchronously inside Cancel(), but observing that through task continuations
needs more thread-pool hops than the timer, so a saturated CI runner let the
timer win and reported a false "not prompt" while the later assertions still
proved cancellation had propagated.

Observe the disconnect with a blocking read on a dedicated thread that sets a
ManualResetEventSlim, and wait on that signal. The window and every assertion
are unchanged; the blocking read is bounded by the server's shutdown budget
because the shutdown token cannot interrupt it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Artifacts are stored per run attempt. Re-running a single test leg left two
test-results-<version> artifacts and two unified test-results artifacts, so
the merge job picked up the stale attempt-1 trx and the Test Report check
listed every trx twice with the already-fixed failure still red.

Set overwrite: true on both uploads so a re-run replaces the same-named
artifact and the report reflects the latest attempt.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@Arthurvdv
Arthurvdv merged commit 2f13e3e into main Sep 28, 2026
40 checks passed
@Arthurvdv
Arthurvdv deleted the fix/cm0001-cancellation-test-disconnect-observation branch September 28, 2026 12:17
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