Conversation
Add 6 new test files covering the Go driver beyond the happy path: - helpers_test.go (115 LOC) — shared connectOrSkip, setupFreshQueue with unique random suffixes per test, retryQueueCount, dlqCount helpers - integration_test.go (231 LOC) — multi-event batches, max-batch limits, empty-queue receive, payload round-trip, default event type, DLQ-at-limit - errors_test.go (208 LOC) — bad DSN, unreachable host, missing queue, missing consumer, after-close panic-safety on Send/Receive/Ack/Nack, context cancellation, unmarshalable payload (chan) - consumer_test.go (239 LOC) — clean Start/Stop, poll-interval respected, unregistered-event nack, context propagation to handler, single-ack- per-batch, documents current handler-panic behavior (kills goroutine) - concurrency_test.go (272 LOC) — concurrent Send under -race, full send/receive/ack loop, handler-nack-under-load, two consumers same queue, double-Start safety - edge_test.go (262 LOC) — empty payload, 1 MiB payload, unicode (CJK + emoji), special-char event types, timestamp sanity, retry_count initial state, string + array payload shapes - bench_test.go (169 LOC) — BenchmarkSend, BenchmarkReceive_Empty, BenchmarkSendReceiveAck, BenchmarkConsumer_DispatchThroughput All integration tests env-gated via PGQUE_TEST_DSN; t.Skip when unreachable. Each test uses a uniquely-named queue + consumer with t.Cleanup so parallel runs cannot collide. Verified: go build ./... clean, go vet ./... clean, gofmt -l clean. Live integration runs require PGQUE_TEST_DSN; not exercised in this commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Remove TestConnect_UnreachableHost and TestConsumer_HandlerPanicKillsLoop; both document pre-#115 behavior (lazy Connect, panic kills loop) that the bugfix PR corrected and re-tested with TestConnect_UnreachableHostFailsImmediately and TestConsumer_HandlerPanicRecoversAndContinues. Keeping them would cause test failures and misrepresent current semantics. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
c188ea6 to
c7130ee
Compare
REV — PR #81 (Go driver thorough test coverage)Verdict: REQUEST_CHANGES (non-blocking on scope, but several test-correctness fixes needed before this PR earns the "production-grade coverage" label it advertises). Stats: +1,420 / -0 across 7 files; 8/8 CI green; 2 pre-fix tests dropped via rebase. Test analyzer (the headliner)Coverage breadth — strong. Every exported method on But several tests claim more than they prove. Concrete instances:
Bug hunter (test correctness)
Bug hunter (concurrency / -race)
SecurityN/A for tests. DSN default Guidelines / style
Docs
Anti-leakClean. ConfidenceHigh on the critique of the 6 weak assertions and the stale comments (1, 2, 3, 4, 5, 7, 8, 9, 12). Medium on (6, 11) — both depend on backend semantics and pool-close ordering that I'd want to confirm by running the suite, but the reasoning stands from reading the code. Suggested next stepTighten the 6 assertions (1–5, 12), correct the two doc inaccuracies (7, 8), and consider the cleanup ordering fix (11) and |
- TestSend_MissingQueue: t.Logf → t.Errorf for queue/not-found check - TestSend_ContextCancelled: t.Logf → t.Errorf for context.Canceled wrap - TestRace_HandlerNackUnderLoad: t.Logf → t.Errorf on failed==0 - TestNack_ToDLQAtRetryLimit: remove Ack-after-Nack (mutually exclusive on same batch); raise cycles to 5; t.Skipf → t.Fatalf on dlqCount==0 - TestSend_AfterClose / TestReceive_AfterClose: use a second live client for cleanup so t.Cleanup does not run on a closed pool
- TestConsumer_AckOnlyOnceForBatch → TestConsumer_AllMessagesDispatched (body counts handler calls, not Ack invocations) - TestConsumer_PollIntervalRespected → TestConsumer_LivenessUnderEmptyQueue (body tests liveness, not measured cadence) - TestConsumer_StartTwiceFromSameInstance → TestConsumer_DoubleStart_DoesNotPanic (scope is limited to no-panic guarantee) - TestConcurrent_TwoConsumersSameQueue → TestConcurrent_TwoConsumersDistinctNames using distinct consumer registrations; assert each sees all messages - benchSuffix: replace time+name suffix with crypto/rand (collision-safe) - helpers_test.go: correct stale comment about Connect laziness - Remove PR-number references from source comments
REV r1 fixes applied (2 commits,
|
| Finding | Test | Change |
|---|---|---|
| #1 | TestSend_MissingQueue |
t.Logf → t.Errorf for queue/not-found string check |
| #12 | TestSend_ContextCancelled |
t.Logf → t.Errorf for context.Canceled wrap check |
| #4 | TestRace_HandlerNackUnderLoad |
t.Logf → t.Errorf on failed == 0 |
| #5 | TestNack_ToDLQAtRetryLimit |
Removed Ack after Nack (mutually exclusive per-batch); raised cycle cap to 5; t.Skipf → t.Fatalf on dlqCount == 0 |
| #11 | TestSend_AfterClose |
Second live cleaner client handles t.Cleanup so queue teardown does not run on a closed pool |
| #11 | TestReceive_AfterClose |
Same cleanup-ordering fix |
Renames and helper fixes (commit c67f840)
| Finding | Change |
|---|---|
| #2 | TestConsumer_AckOnlyOnceForBatch → TestConsumer_AllMessagesDispatched (body counts handler calls, not Ack invocations) |
| #3 | TestConsumer_PollIntervalRespected → TestConsumer_LivenessUnderEmptyQueue (body tests liveness, not measured cadence) |
| #6 | TestConcurrent_TwoConsumersSameQueue → TestConcurrent_TwoConsumersDistinctNames; uses two distinct consumer registrations; asserts each sees all messages exactly total times |
| #9 | benchSuffix: replaced time.Now().Format + b.Name()[last4] with crypto/rand (collision-safe, no panic on short names) |
| #10 | TestConsumer_StartTwiceFromSameInstance → TestConsumer_DoubleStart_DoesNotPanic (scope made explicit) |
| #7 | helpers_test.go: corrected stale comment — Connect now pings eagerly, not lazily |
PR body updates (finding #8, #7)
- Removed "Consumer.Start does not recover from handler panics" claim —
dispatchWithRecoverexists and catches panics. - Removed "pgxpool.New is lazy" claim —
Connectcallspool.Pingbefore returning. - Removed all PR-number references (
#75,#79) from source comments and PR description.
Generated by Claude Code
REV r2 — verification of r1 fixes + fresh scanVerdict: PASS (with two minor non-blocking nits below). All 12 r1 findings are correctly addressed at HEAD r1 fix verification
Fresh r2 findingsNon-blocking (consider for follow-up):
SecurityN/A — test-only diff; no auth/injection/secret surface introduced. Default DSN matches existing test fixture. Bugs / -raceConcurrent tests use Test analyzerRenames in r2 align names to behavior (the original sin r1 flagged). All r2 names match what the body proves. No tests pass for the wrong reason after r1 fixes. Guidelines / anti-leak
Docs
Bottom liner2 successfully closes all 12 r1 findings. The three remaining nits are cosmetic and can be addressed in a follow-up or ignored. This PR is ready to merge. Generated by Claude Code |
Summary
Take the Go driver from happy-path smoke tests to production-grade test coverage. Adds 1,420 LOC of new tests across 6 files; covers every exported symbol's error paths, concurrency properties, and edge cases; adds 4 benchmarks for ongoing perf tracking.
Files added
clients/go/helpers_test.goconnectOrSkip,setupFreshQueue(random suffix, t.Cleanup),retryQueueCount,dlqCountclients/go/integration_test.goclients/go/errors_test.goclients/go/consumer_test.goclients/go/concurrency_test.go-race-friendly concurrent Send, full send/receive/ack loop, handler-nack under load, two independent consumers on same queue, double-Start no-panicclients/go/edge_test.goclients/go/bench_test.goBenchmarkSend,BenchmarkReceive_Empty,BenchmarkSendReceiveAck,BenchmarkConsumer_DispatchThroughputCoverage gaps closed (vs prior)
Before this PR the only tests were happy-path send → tick → receive → ack, plus two consumer-dispatch tests. Symbols with zero prior coverage of their error paths:
Connect(bad/unreachable DSN),Close(idempotency / panic-safety after close),Pool(basic accessor),Send/Receive/Ack/Nackafter Close, context cancellation on every method,Consumer.Startshutdown semantics, poll-interval liveness, panic-from-handler behavior, concurrent producers, multiple consumers on same queue. All now covered.Test infrastructure
PGQUE_TEST_DSN. When unreachable,t.Skiprather than fail.gotest_q_/gotest_c_), registered for cleanup viat.Cleanup. Parallel runs and re-runs cannot collide.helpers_test.go.Behavior notes surfaced while writing
Consumer.Startrecovers from handler panics.dispatchWithRecovercatches any panic, converts it to an error, and nacks the message. The loop continues.Connectpings eagerly.Connectcallspool.Ping(ctx)before returning; a bad DSN or unreachable host surfaces as an error fromConnectitself, not deferred to the first query.pgque.senderrors on non-existent queue.insert_event_rawraises an explicit exception when the named queue does not exist.TestSend_MissingQueueexercises this path.No production-code changes in this PR — all test additions only.
How to run
Test plan
go build ./...cleango vet ./...cleangofmt -l .cleango test -count=1 -run='Nothing^' ./...(compile-check) cleango test -race -count=1 ./...against a live PG with PgQue installed — needs reviewer with a test DBgo test -cover ./...to confirm ≥80% line coverage onclients/go/Notes
dlqCounthelper queriespgque.dead_letterdirectly for reliable DLQ inspection.b.Skipotherwise.TestExtraColumns_RoundTripdeferred — Extra1..Extra4 are receive-only on the current Send API; will land when a future release wrapspgque.send_batchwith extras.Co-Authored-By: Claude Opus 4.7 (1M context)