From 6078309724b620d13dbc73976c3998da6885c312 Mon Sep 17 00:00:00 2001 From: Tobias Gesellchen Date: Thu, 14 May 2026 16:26:46 +0200 Subject: [PATCH] test(datastore): compare MAC lookup to update by ratio, not wall clock The lookup branch of AccountDeviceDir does up to two Stat() syscalls, so its wall-clock cost is dominated by filesystem latency. On shared CI runners that latency varies enough that the existing 70 ms absolute threshold has been tripped repeatedly -- the previous bump from 50 ms to 70 ms in d97cd45 was the same story. Incrementally relaxing an absolute bound to track CI noise is a treadmill. Replace the lookup-time wall-clock check with a ratio against the in-memory update cost (currently ~8x on dev machines, ~12x on CI). The 30x threshold leaves comfortable headroom for noise while still catching an algorithmic regression in the lookup path, where the ratio would explode well past 30 (an O(n^2) walk over 1000 entries would push it into the hundreds). The update path's absolute cap stays in place as a backstop against catastrophic regressions in that hot in-memory path. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../datastore/upnp_integration_test.go | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/pkg/service/datastore/upnp_integration_test.go b/pkg/service/datastore/upnp_integration_test.go index d8b09fe..975318d 100644 --- a/pkg/service/datastore/upnp_integration_test.go +++ b/pkg/service/datastore/upnp_integration_test.go @@ -381,10 +381,28 @@ func TestMACMappingPerformance(t *testing.T) { t.Logf(" Total mappings stored: %d (includes normalized versions)", totalMappings) + // Update is a pure in-memory map write; keep an absolute cap as a backstop + // against catastrophic regressions in that hot path. if updateDuration > time.Millisecond*100 { t.Errorf("Update performance too slow: %v", updateDuration) } - if lookupDuration > time.Millisecond*70 { - t.Errorf("Lookup performance too slow: %v", lookupDuration) + + // Lookup does up to two Stat() syscalls and is dominated by filesystem + // latency, which varies wildly on shared CI runners. Compare it to the + // in-memory update cost instead of an absolute bound: the ratio captures + // "lookup got disproportionately slower" (an algorithmic regression in the + // lookup path) while staying stable under uniform host slowdown. + if updateDuration <= 0 { + t.Fatalf("Update duration is non-positive (%v); cannot compute lookup/update ratio", updateDuration) + } + + const maxLookupUpdateRatio = 30.0 + + ratio := float64(lookupDuration) / float64(updateDuration) + t.Logf(" Lookup/Update ratio: %.2fx (threshold %.0fx)", ratio, maxLookupUpdateRatio) + + if ratio > maxLookupUpdateRatio { + t.Errorf("Lookup is %.2fx slower than update (>%.0fx threshold) — possible regression in AccountDeviceDir lookup path. Update=%v Lookup=%v", + ratio, maxLookupUpdateRatio, updateDuration, lookupDuration) } }