Skip to content

Commit 75c0e99

Browse files
aksOpsclaude
andcommitted
test(ingest): extract shared helper for failure-skip pipeline tests
SonarCloud quality gate failed PR #74 on new_duplicated_lines_density=3.5% (threshold 3%). The duplication is between TestPipeline_FailedSpansSkipsLogs and TestPipeline_FailedTracesAbortsBatch — same boilerplate, same waitFor, same assertion shape. The waitFor 2s→5s bump made those lines "new code", so Sonar recounted the existing duplication against the PR's new-code budget. Extract runFailureSkipsCheck(t, writer, forbidden...) — single helper takes the configured fakeWriter and the BatchCreate* names that must not fire after the seeded upstream failure. Each failing-path test collapses to a single line. Verification * go test -race -count=3 -run 'TestPipeline_Failed*' — pass × 3 * go vet ./... clean Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent b51869b commit 75c0e99

1 file changed

Lines changed: 20 additions & 27 deletions

File tree

internal/ingest/pipeline_test.go

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -281,12 +281,13 @@ func TestPipeline_CallbacksFireAfterPersistence(t *testing.T) {
281281
}
282282
}
283283

284-
func TestPipeline_FailedSpansSkipsLogs(t *testing.T) {
285-
// When BatchCreateSpans fails, BatchCreateLogs must NOT run for that
286-
// batch — preserves the invariant that orphan logs aren't persisted
287-
// without their span. Mirrors the synchronous path's behavior of
288-
// returning the span error before log insert.
289-
w := &fakeWriter{spanErr: errors.New("span db down")}
284+
// runFailureSkipsCheck wires up a 1-worker pipeline with the configured
285+
// fakeWriter, submits a healthy batch, waits for the failure to surface,
286+
// then asserts that none of the forbidden BatchCreate* calls fired.
287+
// Shared by the trace-fails and span-fails skip tests so the boilerplate
288+
// (pipeline lifecycle + waitFor) lives in one place.
289+
func runFailureSkipsCheck(t *testing.T, w *fakeWriter, forbidden ...string) {
290+
t.Helper()
290291
p := NewPipeline(w, nil, PipelineConfig{Capacity: 2, Workers: 1})
291292
ctx, cancel := context.WithCancel(context.Background())
292293
t.Cleanup(cancel)
@@ -301,36 +302,28 @@ func TestPipeline_FailedSpansSkipsLogs(t *testing.T) {
301302
}
302303
calls := w.snapshotOrder()
303304
for _, c := range calls {
304-
if c == "logs" {
305-
t.Fatalf("BatchCreateLogs ran after spans failed — order=%v", calls)
305+
for _, f := range forbidden {
306+
if c == f {
307+
t.Fatalf("%s ran after upstream failure — order=%v", f, calls)
308+
}
306309
}
307310
}
308311
}
309312

313+
func TestPipeline_FailedSpansSkipsLogs(t *testing.T) {
314+
// When BatchCreateSpans fails, BatchCreateLogs must NOT run for that
315+
// batch — preserves the invariant that orphan logs aren't persisted
316+
// without their span. Mirrors the synchronous path's behavior of
317+
// returning the span error before log insert.
318+
runFailureSkipsCheck(t, &fakeWriter{spanErr: errors.New("span db down")}, "logs")
319+
}
320+
310321
func TestPipeline_FailedTracesAbortsBatch(t *testing.T) {
311322
// Trace failures roll the entire batch back — atomic batches are the
312323
// fix for orphan FK rows when a worker crashes between BatchCreate*
313324
// calls. Spans and logs must NOT be persisted when the trace insert
314325
// fails. Counterpart of TestPipeline_FailedSpansSkipsLogs.
315-
w := &fakeWriter{traceErr: errors.New("transient")}
316-
p := NewPipeline(w, nil, PipelineConfig{Capacity: 2, Workers: 1})
317-
ctx, cancel := context.WithCancel(context.Background())
318-
t.Cleanup(cancel)
319-
p.Start(ctx)
320-
t.Cleanup(p.Stop)
321-
322-
if err := p.Submit(healthyBatch()); err != nil {
323-
t.Fatalf("submit: %v", err)
324-
}
325-
if !waitFor(t, 5*time.Second, func() bool { return p.Stats().ProcessFailures > 0 }) {
326-
t.Fatalf("expected ProcessFailures > 0, got %d", p.Stats().ProcessFailures)
327-
}
328-
calls := w.snapshotOrder()
329-
for _, c := range calls {
330-
if c == "spans" || c == "logs" {
331-
t.Fatalf("spans/logs ran after trace failure — order=%v", calls)
332-
}
333-
}
326+
runFailureSkipsCheck(t, &fakeWriter{traceErr: errors.New("transient")}, "spans", "logs")
334327
}
335328

336329
func TestPipeline_DrainsOnStop(t *testing.T) {

0 commit comments

Comments
 (0)