Skip to content

test: let the auto-read-off replay test accept a chunk delivered before the replay - #2368

Merged
hyperxpro merged 1 commit into
AsyncHttpClient:mainfrom
mkurz:fix/replay-drain-test-race
Nov 4, 2026
Merged

hyperxpro merged 1 commit into
AsyncHttpClient:mainfrom
mkurz:fix/replay-drain-test-race

Conversation

@mkurz

@mkurz mkurz commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Problem

The test's server sends the first response's chunk right after its head. When both arrive in the same read, the handler receives the chunk before the injected I/O error replays the request. That is correct, since a suspension does not hold back what has already been read, but the test took the chunk for part of the replayed body (expected: <replayed> but was: <first>).

Recording the order of events over 50 repetitions on JDK 11: 3 runs had the chunk before onRetry, none after it.

Change

The test records onRetry, allows the first response's chunk only before it, and checks that the replayed body follows it directly. What the test is about is unchanged: with auto-read off, the old connection must still be drained and closed.

AI disclosure

Claude Code on behalf of Matthias Kurz. The commit includes Co-Authored-By per AGENTS.md.

Test plan

  • The test repeated 50 times on JDK 11 and on JDK 25: 0 failures. The previous version failed 7 times on JDK 11 and once on JDK 25.
  • Without fix(netty): detach a replayed request's old channel before completing its body control #2367's change in NettyRequestSender, every one of 50 repetitions still fails, on the drain assertion.
  • ./mvnw -B -ntp -Dgpg.skip=true clean verify on JDK 11, on a tree identical to this branch: 1,821 tests, 0 failures, 0 errors, 11 skipped; Revapi passed. No test-skipping flags were used.
  • ResponseBodyControlTest and Http2ResponseBodyControlTest, compiled on JDK 11 and run on JDK 17, 21 and 25 (Maven Surefire's -Djvm): 20 tests each, 0 failures.

ioExceptionReplayDrainsTheOldConnectionWithAutoReadDisabled failed in
about one run in ten, as on macOS with JDK 21 in CI. The server sends
the first response's chunk right after its head; when both arrive in
the same read, the handler receives the chunk before the I/O error
replays the request. That is correct, but the test took the chunk for
part of the replayed body.

Record onRetry, allow the first chunk only before it, and check that
the replayed body follows it directly. Over 50 repetitions, the old
assertion failed 7 times on JDK 11 and once on JDK 25, the new one
never, and every failure had the chunk before onRetry. Without the fix
in NettyRequestSender, the test still fails every time.

Claude Code on behalf of Matthias Kurz

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mkurz

mkurz commented Nov 4, 2026

Copy link
Copy Markdown
Contributor Author

Green 😉

@hyperxpro
hyperxpro merged commit 05624c4 into AsyncHttpClient:main Nov 4, 2026
13 checks passed
@mkurz
mkurz deleted the fix/replay-drain-test-race branch November 4, 2026 19:54
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