test(ingestor): anchor the RF-sample fixtures to now, not to a calendar date (#2034)

The three ClientRfDeltas tests seeded 2026-08-17T10:00:00.000Z and queried that window back. resolveRxTimeCore (cmd/ingestor/main.go:1527) replaces timestamps older than 30 days with the ingest time, so from 2026-09-16T10:00Z the seeds landed at time.Now() and every delta fell outside the queried window. Master and every open PR went red on it.

Fixtures now derive from a package-level base two hours in the past, computed once per test binary so two seeds cannot straddle a second boundary and break the exact WallMillis assertion.

Merged by the interim maintainer without a second human reviewer: CI is the only independent check (run 35222316327, ingestor tests ok in 97.033s, race detector ok, no --- FAIL). Fixed dates elsewhere in the ingestor tests are untouched, they assert row counts rather than querying by the seeded date.
This commit is contained in:
efiten
2026-09-17 16:52:20 +02:00
committed by GitHub
parent b8c8d98e61
commit 5430bc7923
+45 -15
View File
@@ -5,10 +5,40 @@ import (
"time"
)
// rfFixtureTime returns a sample timestamp offset seconds from a base two
// hours in the past, in the layout the handler round-trips.
//
// The times have to be anchored to now, not to a calendar date.
// resolveRxTimeCore (main.go:1527) replaces any timestamp more than 30 days
// old with the ingest time, so a fixed fixture date stops round-tripping 30
// days after it is written: the seeded rows land at time.Now() while the query
// window stays in the past, and every delta disappears. The 2026-08-17
// fixtures this file used to carry did exactly that on 2026-09-16T10:00Z,
// which turned all three delta tests red on master and on every open PR.
// The base is computed once for the whole test binary, not per call: two
// calls straddling a wall-clock second boundary would otherwise sit 16 s
// apart instead of 15 s, and TestRfDeltaBreaksOnReboot asserts the exact
// WallMillis. Truncating to the second keeps the formatted values ending in
// ".000Z", the shape these fixtures have always had.
var rfFixtureBase = time.Now().UTC().Add(-2 * time.Hour).Truncate(time.Second)
func rfFixtureTime(offset time.Duration) string {
return rfFixtureBase.Add(offset).Format(rxTimeMillisLayout)
}
// rfFixtureWindow brackets the rfFixtureTime series. Bounds are compared
// lexicographically against millisecond-precision sampled_at values, so they
// must themselves be in the millisecond layout: a second-resolution
// "...:00:00Z" bound would lexicographically exclude "...:00:00.000Z",
// because `.` sorts before `Z`.
func rfFixtureWindow() (from, to string) {
return rfFixtureTime(-time.Hour), rfFixtureTime(time.Hour)
}
func TestHandleClientRfSample(t *testing.T) {
s := newTestStore(t)
msg := map[string]interface{}{
"type": "RF_SAMPLE", "timestamp": "2026-08-17T10:00:00.000Z",
"type": "RF_SAMPLE", "timestamp": rfFixtureTime(0),
"gps": map[string]interface{}{"lat": 51.2, "lon": 4.4, "acc_m": 8.0},
"stationary": false,
"uptime_secs": 84213.0, "noise_floor": -119.0, "rx_air_secs": 20877.0,
@@ -46,7 +76,7 @@ func TestHandleClientRfSampleRejects(t *testing.T) {
s := newTestStore(t)
base := func() map[string]interface{} {
return map[string]interface{}{
"timestamp": "2026-08-17T10:00:00.000Z",
"timestamp": rfFixtureTime(0),
"gps": map[string]interface{}{"lat": 51.2, "lon": 4.4},
"uptime_secs": 1.0,
}
@@ -89,14 +119,12 @@ func TestRfDeltaBreaksOnReboot(t *testing.T) {
"rx_air_secs": rxAir,
})
}
seed("2026-08-17T10:00:00.000Z", 1000, 500)
seed("2026-08-17T10:00:15.000Z", 1015, 512) // +12 s of RX air over 15 s
seed("2026-08-17T10:00:30.000Z", 10, 3) // rebooted: uptime dropped
seed(rfFixtureTime(0), 1000, 500)
seed(rfFixtureTime(15*time.Second), 1015, 512) // +12 s of RX air over 15 s
seed(rfFixtureTime(30*time.Second), 10, 3) // rebooted: uptime dropped
// Bounds are compared lexicographically against millisecond-precision
// sampled_at values, so they must themselves be in the millisecond layout
// — "10:00:00Z" would lexicographically exclude "10:00:00.000Z" (`.` < `Z`).
deltas, err := s.ClientRfDeltas("aa11", "2026-08-17T00:00:00.000Z", "2026-08-18T00:00:00.000Z")
from, to := rfFixtureWindow()
deltas, err := s.ClientRfDeltas("aa11", from, to)
if err != nil {
t.Fatalf("deltas: %v", err)
}
@@ -126,10 +154,11 @@ func TestRfDeltaNilWhenEitherEndpointMissingCounter(t *testing.T) {
handleClientRfSample(s, "test", "aa11", msg)
}
five := int64(5)
seed("2026-08-17T10:00:00.000Z", 1000, nil) // firmware without the counter
seed("2026-08-17T10:00:15.000Z", 1015, &five)
seed(rfFixtureTime(0), 1000, nil) // firmware without the counter
seed(rfFixtureTime(15*time.Second), 1015, &five)
deltas, err := s.ClientRfDeltas("aa11", "2026-08-17T00:00:00.000Z", "2026-08-18T00:00:00.000Z")
from, to := rfFixtureWindow()
deltas, err := s.ClientRfDeltas("aa11", from, to)
if err != nil {
t.Fatalf("deltas: %v", err)
}
@@ -156,10 +185,11 @@ func TestClientRfDeltasNormalizesPubkeyCase(t *testing.T) {
"rx_air_secs": rxAir,
})
}
seed("2026-08-17T10:00:00.000Z", 1000, 500)
seed("2026-08-17T10:00:15.000Z", 1015, 512)
seed(rfFixtureTime(0), 1000, 500)
seed(rfFixtureTime(15*time.Second), 1015, 512)
deltas, err := s.ClientRfDeltas("AA11", "2026-08-17T00:00:00.000Z", "2026-08-18T00:00:00.000Z")
from, to := rfFixtureWindow()
deltas, err := s.ClientRfDeltas("AA11", from, to)
if err != nil {
t.Fatalf("deltas: %v", err)
}