internal/notify shutdown tests: misleading failure diagnostic and an overloaded timing constant #116
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Non-blocking findings from the re-review of PR #113, collected here rather than spent on another review cycle of that PR. None of these affect whether the production code is correct — they affect whether a future failure will be diagnosable.
Applies to
internal/notify/shutdown_test.goandinternal/notify/shutdown.goas they exist after #113 merges.Items
1. A failure message that reports the wrong bound.
internal/notify/shutdown_test.go:496-502compares elapsed time againstidleDrainBound(500ms) but its failure message printsdrainSlack(2s). So a genuine failure at, say, 600ms would print something like "exceeded 2s" while the actual violated bound was 500ms — the message contradicts the assertion, and reads as though the check passed. A test that fails with a misleading diagnostic costs more than one that fails plainly, because it sends whoever is debugging in the wrong direction.2.
drainSlackis overloaded across three distinct meanings. The same constant is doing duty for unrelated timing concepts. Split it into separately named constants, each with a comment stating what it bounds and why that magnitude was chosen. This is what made item 1 easy to write and hard to notice.3.
TestDrainWithCancelledContextDoesNotWarnasserts only an absence. It checks that no WARN was logged — which is also exactly what a trivially-passing or no-op run produces. It was empirically reliable in review (caught the removed guard 10/10 times), so this is latent rather than broken. Strengthen it to assert something positive as well: that the drain returned, and that the expected debug-level line was emitted. An absence-only assertion cannot distinguish "the guard worked" from "nothing ran at all".Definition of done
drainSlackis split into distinctly named constants, one per concept, each commented with what it bounds and the reasoning behind its magnitude.TestDrainWithCancelledContextDoesNotWarnasserts a positive signal in addition to the absence of the warning.idleDrainBound, 500ms) exists specifically because a 50ms cap flaked at 57.5ms under load. Renaming and re-commenting must not become an excuse to widen anything. If you believe a bound is genuinely wrong, say so in the PR description with evidence rather than quietly changing it.git statusis clean before committing — no mutation residue. Report what you mutated and what each mutation produced.make testat least 20 consecutive times with the cache bypassed under-raceand confirm all are clean. This package has produced two separate flakes already; a single green run is not evidence here.make checkgreen;TODO.mdupdated in the same commit.The finishing commit's title must end with
(closes #N)referencing this issue.Scope
Test-quality only. Do not change the drain's structure, its locking, the
sync.Onceonabandon, the outstanding-count accounting, or the three-dispatcher consolidation — all of that passed adversarial review and is not in question here.Deliberately not included, deferred from #113's first review and still deferred: refused notifications are still recorded in
AlertHistory(arguably correct, arguably not — needs a decision, not a patch), andErrDeliveryAbandonedliving inshutdown.gorather than the sentinel block atnotify.go:32-45. Raise them separately if you think they are worth doing.Sequencing
Blocked until PR #113 merges — every line referenced above only exists on that branch.
Hard constraints
httptestservers standing in for webhook endpoints are HTTP and remain fine..golangci.yml; do not change the golangci-lint pin.maketargets andscript/entrypoints only — no directgo test/go clean/golangci-lintinvocations.