fix(relay): deflake TestSMTPInboundMetric_RejectedLineTooLong - #799
Merged
Conversation
The test writes a single 160KiB line to exercise the 128KiB MaxLineLength cap. The server aborts the connection partway through the transfer, so whether the client's Write finishes before the RST arrives depends on socket buffering and scheduling — under CI contention (make cover runs packages at -p 4) the Write intermittently observes 'connection reset by peer' and the old t.Fatalf fired before the real assertion ever ran (~1 in 4 on recent main; e.g. fddf0ed). A mid-write reset is itself evidence the server aborted, so treat it as such instead of fatal: fail only if both Write and Close succeed (the genuine 'server accepted a 160KiB line' condition), assert the 554 too-long-line text only when the write completed cleanly, and rely on the rejected_line_too_long metric — which is the actual behavior under test and independent of wire timing — on every path. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
TestSMTPInboundMetric_RejectedLineTooLong(added in #773) intermittently reds the Go coverage gate and blocks unrelated PRs:Seen on main
fddf0edf(job). It is flaky, not broken — the same test on recent main:25356292pass,bfeec71epass,81e8ce87pass,fddf0edffail (~1 in 4 in that sample).Root cause
The test writes a single 160KiB line to exercise the 128KiB
MaxLineLengthcap. The server hits the cap partway through and resets the connection. Whether the client finishes itsWritebefore the RST arrives depends on socket buffering and scheduling —make coverruns packages at-p 4on a loaded runner, which is exactly when it loses. The old comment even conceded the assumption ('small enough that the unread remainder … fits in loopback socket buffers'). When the write lost the race,t.Fatalf("write body: …")fired before the real assertion was ever reached.Fix
Remove the timing dependency instead of re-tuning the body size (a bigger/smaller buffer just moves the threshold and stays racy):
w.Writeerror is no longer fatal — a mid-write reset is itself evidence the server aborted the transaction. It's captured instead.w.Close()succeed — the genuine 'server wrongly accepted a 160KiB line' condition.Closemay surface a bare connection error rather than the SMTP text.assertSingleOutcome(t, metrics, "rejected_line_too_long", false)— the actual thing under test, independent of wire timing, and it runs on every path.Verification
go test ./internal/relay -run TestSMTPInboundMetric_RejectedLineTooLong -count=30— ok (30/30)go test ./internal/relay -run TestSMTPInboundMetric -count=10 -p 4— okgo test ./internal/relay -count=1(whole package) — okMaxLineLengthto 512KiB inserver.go→ test fails withDATA with a 160KiB line succeeded; want 554 too-long-line rejection; restored → passes. The flake is fixed without neutering the assertion.gofmt -lclean,go vetclean.🤖 Generated with Claude Code