test(patterndetector): cover SetDoubleValue + reverse-order cross-stream#467
Conversation
Closes #463. Two reviewer-flagged gaps from #461 (#437): 1. projectFBMemoryFromMetrics SetDoubleValue branch (metrics.go:344) was reachable but uncovered — all ten existing projection tests used SetIntValue. A regression that swapped truncation for rounding (or returned 0) would have shipped silently. New test pins 42.7 -> int64(42) truncate-toward-zero. 2. Cross-stream reverse-order: TestMetricsProcessor_CrossStreamJoin* fed FB-then-OOM. The reverse path (OOM arrives before the next dcgm scrape lands) was implicit. New test feeds OOM first (asserts partial verdict kind=unknown), then FB metric + retry OOM (asserts the buffer survives across ConsumeLogs/Metrics calls and the retry correlates to a full fragmentation verdict). Test-only. Mutation-verified: - numberDataPointIntValue Double branch returning 0 -> caught - ...+0.5 rounding -> caught - buffer-drain skip in runCUDAOOMDetector -> caught - partial-verdict suppression -> caught Signed-off-by: Tri Lam <tree@lumalabs.ai>
Review: PR #467 (SetDoubleValue + reverse-order cross-stream tests)Grade: A+ B/A/A+ Criteria✓ Scope: Test-only, 2 new tests for reachable-but-uncovered branches in PR #461 metrics-path consumer. ✓ Risk assessment: Low. No production code changes. Branches already exist; tests lock them against regression. ✓ Test proportionality: 2 tests for 2 orthogonal branches.
✓ Mutation coverage: All 4 claimed mutations verified reachable and would be caught:
✓ Exhaustiveness audit (A+ defensible):
✓ Production code untouched: Diff shows only Simplification SweepTest 1 (DoubleValue): No bloat.
Test 2 (ReverseOrder): No bloat.
Test ExecutionRelease notesFenced ```release-notes block, concise, test-only, closes #463. ✓ VerdictShip. A+. Tests are minimal, well-commented, mutation-verified, and lock reachable-but-uncovered branches. No simplification needed. No auto-merge required (manual sign-off fine). |
Summary
Closes #463. Adds two test cases flagged by the reviewer of #461 (#437) as reachable-but-uncovered branches in the metrics-path consumer.
Root cause
PR #461 shipped the metrics-path consumer + cross-stream join for cuda_oom with 10 projection tests. Two branches were reachable but unexercised:
projectFBMemoryFromMetricsusesint64(dp.DoubleValue())atmetrics.go:344— theSetDoubleValuetruncation path. All 10 existing tests usedSetIntValue. A regression that swapped truncation for rounding (or returned 0) would have shipped silently.TestMetricsProcessor_CrossStreamJoinFragmentationVerdictfed FB-then-OOM only. The reverse order (OOM arrives before the next dcgm scrape) was an implicit assumption — the detector's empty-buffer branch + the buffer-survives-across-calls invariant were both uncovered for the metrics-path wiring.Changes
Two new tests in
module/processor/patterndetectorprocessor/metrics_test.go:TestProjectFBMemoryFromMetrics_DoubleValueTruncatesToInt64— feeds aSetDoubleValue(42.7)free +SetDoubleValue(80 GiB)total; assertsFreeBytes == 42(truncate, not round to 43; not zero).TestMetricsProcessor_CrossStreamReverseOrderPartialThenJoin— OOM log first (buffer empty) → asserts partial verdictkind=unknown,Confidence=Partial. Then FB metric arrives, retry OOM log → asserts full verdictkind=fragmentation(locks the buffer-survives-across-calls invariant).Test-only; no production-code changes.
Mutation results
Each test verified to fail when its target code is broken (then restored):
numberDataPointIntValueDouble branch ->return 0expected: 42, actual: 0)numberDataPointIntValueDouble branch -> rounding(x + 0.5)expected: 42, actual: 43)runCUDAOOMDetectorbuffer-drain skipped (if false && buffer != nil)unknowninstead offragmentation)runCUDAOOMDetectorA+ exhaustiveness audit (non-blocking notes)
Other projection branches checked:
HappyPathGaugeAndSum,DropsNonNumericDataPoints,IgnoresNonFBMetrics).gpu.id(resource + DP) — covered (DropsRecordsMissingGPUID).DropsNonNumericDataPoints).gpu.idoverriding resource — covered (MultiGPUSplit).hw.gpu.memory.*(thedefaultbranch innumberDataPoints) — technically untested but the customer-stable scrape format pins these to Gauge/Sum; not load-bearing enough to file.Test plan
go test -race -count=1 ./processor/patterndetectorprocessor/...— green