@@ -1148,215 +1148,6 @@ func TestSQLiteStore_Migration_AddsClusterContext(t *testing.T) {
11481148 }
11491149}
11501150
1151- // A relist re-emits the same informer id; INSERT ... ON CONFLICT must leave the
1152- // original row untouched (no k8s_event mutation path) instead of duplicating it.
1153- // Mirrors TestMemoryStore_DedupesIdenticalInformerID.
1154- func TestSQLiteStore_DedupesIdenticalInformerID (t * testing.T ) {
1155- store , cleanup := createTestSQLiteStore (t )
1156- defer cleanup ()
1157- ctx := context .Background ()
1158-
1159- rv := "100"
1160- add := NewInformerEvent ("Deployment" , "apps/v1" , "team-a" , "web" , "uid-1" , rv , EventTypeAdd , HealthHealthy , nil , nil , nil , nil )
1161- relistUpdate := NewInformerEvent ("Deployment" , "apps/v1" , "team-a" , "web" , "uid-1" , rv , EventTypeUpdate , HealthHealthy , nil , nil , nil , nil )
1162- if add .ID != relistUpdate .ID {
1163- t .Fatalf ("relist add/update must share an id: %q vs %q" , add .ID , relistUpdate .ID )
1164- }
1165-
1166- if err := store .Append (ctx , add ); err != nil {
1167- t .Fatalf ("Append add: %v" , err )
1168- }
1169- if err := store .Append (ctx , relistUpdate ); err != nil {
1170- t .Fatalf ("Append relistUpdate: %v" , err )
1171- }
1172-
1173- got , err := store .Query (ctx , QueryOptions {Limit : 10 , IncludeManaged : true })
1174- if err != nil {
1175- t .Fatalf ("Query: %v" , err )
1176- }
1177- if len (got ) != 1 {
1178- t .Fatalf ("expected 1 deduped row, got %d: %+v" , len (got ), got )
1179- }
1180- // The original add is kept — the relist did NOT overwrite it into an update.
1181- if got [0 ].EventType != EventTypeAdd {
1182- t .Fatalf ("informer relist must not mutate the row, got event_type %q want %q" , got [0 ].EventType , EventTypeAdd )
1183- }
1184-
1185- del := NewInformerEvent ("Deployment" , "apps/v1" , "team-a" , "web" , "uid-1" , rv , EventTypeDelete , HealthUnknown , nil , nil , nil , nil )
1186- if del .ID == add .ID {
1187- t .Fatalf ("delete must get a distinct id, got %q for both" , del .ID )
1188- }
1189- if err := store .Append (ctx , del ); err != nil {
1190- t .Fatalf ("Append del: %v" , err )
1191- }
1192- got , err = store .Query (ctx , QueryOptions {Limit : 10 , IncludeManaged : true })
1193- if err != nil {
1194- t .Fatalf ("Query: %v" , err )
1195- }
1196- if len (got ) != 2 {
1197- t .Fatalf ("expected add + delete = 2 rows, got %d" , len (got ))
1198- }
1199- }
1200-
1201- // A K8s Event's count bump reuses the uid-based id; the store must upsert the
1202- // mutable fields (count/message/timestamp) in place, not drop the bump or append
1203- // a duplicate. Mirrors TestMemoryStore_K8sEventCountBumpUpserts.
1204- func TestSQLiteStore_K8sEventCountBumpUpserts (t * testing.T ) {
1205- store , cleanup := createTestSQLiteStore (t )
1206- defer cleanup ()
1207- ctx := context .Background ()
1208-
1209- base := time .Now ()
1210- mk := func (count int32 , message string , ts time.Time ) TimelineEvent {
1211- return TimelineEvent {
1212- ID : "k8s-uid-1" , Timestamp : ts , Source : SourceK8sEvent ,
1213- Kind : "Pod" , Namespace : "team-a" , Name : "web-abc" ,
1214- EventType : EventTypeWarning , Reason : "BackOff" , Message : message , Count : count ,
1215- }
1216- }
1217- if err := store .Append (ctx , mk (1 , "back-off 10s" , base )); err != nil {
1218- t .Fatalf ("Append first: %v" , err )
1219- }
1220- if err := store .Append (ctx , mk (5 , "back-off 40s" , base .Add (30 * time .Second ))); err != nil {
1221- t .Fatalf ("Append bump: %v" , err )
1222- }
1223-
1224- got , err := store .Query (ctx , QueryOptions {Limit : 10 , IncludeManaged : true , IncludeK8sEvents : true })
1225- if err != nil {
1226- t .Fatalf ("Query: %v" , err )
1227- }
1228- if len (got ) != 1 {
1229- t .Fatalf ("expected 1 upserted row, got %d: %+v" , len (got ), got )
1230- }
1231- if got [0 ].Count != 5 {
1232- t .Fatalf ("expected refreshed count 5, got %d" , got [0 ].Count )
1233- }
1234- if got [0 ].Message != "back-off 40s" {
1235- t .Fatalf ("expected refreshed message, got %q" , got [0 ].Message )
1236- }
1237- if ! got [0 ].Timestamp .Equal (base .Add (30 * time .Second )) {
1238- t .Fatalf ("expected refreshed timestamp %v, got %v" , base .Add (30 * time .Second ), got [0 ].Timestamp )
1239- }
1240- }
1241-
1242- // An out-of-order older revision of the same K8s Event uid must NOT clobber the
1243- // newer row already stored. Mirrors the recency guard in
1244- // TestMemoryStore_K8sEventBumpMovesToRecency.
1245- func TestSQLiteStore_K8sEventStaleBumpIgnored (t * testing.T ) {
1246- store , cleanup := createTestSQLiteStore (t )
1247- defer cleanup ()
1248- ctx := context .Background ()
1249-
1250- base := time .Now ()
1251- mk := func (count int32 , ts time.Time ) TimelineEvent {
1252- return TimelineEvent {
1253- ID : "k8s-uid-1" , Timestamp : ts , Source : SourceK8sEvent ,
1254- Kind : "Pod" , Namespace : "team-a" , Name : "web-abc" ,
1255- EventType : EventTypeWarning , Reason : "BackOff" , Count : count ,
1256- }
1257- }
1258- // Newest revision arrives first, then a stale older relay of the same uid.
1259- if err := store .Append (ctx , mk (5 , base .Add (30 * time .Second ))); err != nil {
1260- t .Fatalf ("Append newer: %v" , err )
1261- }
1262- if err := store .Append (ctx , mk (1 , base )); err != nil {
1263- t .Fatalf ("Append stale: %v" , err )
1264- }
1265-
1266- got , err := store .Query (ctx , QueryOptions {Limit : 10 , IncludeManaged : true , IncludeK8sEvents : true })
1267- if err != nil {
1268- t .Fatalf ("Query: %v" , err )
1269- }
1270- if len (got ) != 1 {
1271- t .Fatalf ("expected 1 row, got %d: %+v" , len (got ), got )
1272- }
1273- if got [0 ].Count != 5 {
1274- t .Fatalf ("stale relay must not clobber newer row, got count %d want 5" , got [0 ].Count )
1275- }
1276- if ! got [0 ].Timestamp .Equal (base .Add (30 * time .Second )) {
1277- t .Fatalf ("stale relay must not roll back timestamp, got %v" , got [0 ].Timestamp )
1278- }
1279- }
1280-
1281- // Seq is the delta cursor: SinceSeq must return exactly what arrived after the
1282- // cursor, keyed on arrival order — a late event with an older timestamp still
1283- // lands ahead of the cursor. Mirrors TestMemoryStore_SeqCursor.
1284- func TestSQLiteStore_SeqCursor (t * testing.T ) {
1285- store , cleanup := createTestSQLiteStore (t )
1286- defer cleanup ()
1287- ctx := context .Background ()
1288-
1289- base := time .Now ()
1290- mk := func (id string , ts time.Time ) TimelineEvent {
1291- return TimelineEvent {
1292- ID : id , Timestamp : ts , Source : SourceInformer ,
1293- Kind : "Pod" , Namespace : "default" , Name : id , EventType : EventTypeUpdate ,
1294- }
1295- }
1296- if err := store .AppendBatch (ctx , []TimelineEvent {mk ("a" , base ), mk ("b" , base .Add (time .Second ))}); err != nil {
1297- t .Fatalf ("AppendBatch: %v" , err )
1298- }
1299- all , err := store .Query (ctx , QueryOptions {Limit : 10 , IncludeManaged : true })
1300- if err != nil {
1301- t .Fatalf ("Query: %v" , err )
1302- }
1303- if len (all ) != 2 || all [0 ].Seq == 0 || all [1 ].Seq == 0 || all [0 ].Seq == all [1 ].Seq {
1304- t .Fatalf ("expected 2 events with distinct non-zero seqs, got %+v" , all )
1305- }
1306- cursor := max (all [0 ].Seq , all [1 ].Seq )
1307-
1308- if err := store .Append (ctx , mk ("late" , base .Add (- time .Hour ))); err != nil {
1309- t .Fatalf ("Append late: %v" , err )
1310- }
1311- delta , err := store .Query (ctx , QueryOptions {Limit : 10 , IncludeManaged : true , SinceSeq : cursor })
1312- if err != nil {
1313- t .Fatalf ("Query delta: %v" , err )
1314- }
1315- if len (delta ) != 1 || delta [0 ].ID != "late" {
1316- t .Fatalf ("expected exactly the late arrival past the cursor, got %+v" , delta )
1317- }
1318- if delta [0 ].Seq <= cursor {
1319- t .Fatalf ("late arrival seq %d must exceed cursor %d" , delta [0 ].Seq , cursor )
1320- }
1321- }
1322-
1323- // A K8s Event count bump upserts in place but must take a fresh seq, or a
1324- // delta reader holding a cursor past the original arrival never sees the bump.
1325- // Mirrors TestMemoryStore_K8sEventBumpAdvancesSeq.
1326- func TestSQLiteStore_K8sEventBumpAdvancesSeq (t * testing.T ) {
1327- store , cleanup := createTestSQLiteStore (t )
1328- defer cleanup ()
1329- ctx := context .Background ()
1330-
1331- base := time .Now ()
1332- mk := func (count int32 , ts time.Time ) TimelineEvent {
1333- return TimelineEvent {
1334- ID : "k8s-uid-1" , Timestamp : ts , Source : SourceK8sEvent ,
1335- Kind : "Pod" , Namespace : "default" , Name : "web-abc" ,
1336- EventType : EventTypeWarning , Reason : "BackOff" , Count : count ,
1337- }
1338- }
1339- if err := store .Append (ctx , mk (1 , base )); err != nil {
1340- t .Fatalf ("Append first: %v" , err )
1341- }
1342- first , err := store .Query (ctx , QueryOptions {Limit : 10 , IncludeManaged : true , IncludeK8sEvents : true })
1343- if err != nil || len (first ) != 1 {
1344- t .Fatalf ("Query first: %v %+v" , err , first )
1345- }
1346- cursor := first [0 ].Seq
1347-
1348- if err := store .Append (ctx , mk (5 , base .Add (30 * time .Second ))); err != nil {
1349- t .Fatalf ("Append bump: %v" , err )
1350- }
1351- delta , err := store .Query (ctx , QueryOptions {Limit : 10 , IncludeManaged : true , IncludeK8sEvents : true , SinceSeq : cursor })
1352- if err != nil {
1353- t .Fatalf ("Query delta: %v" , err )
1354- }
1355- if len (delta ) != 1 || delta [0 ].Count != 5 {
1356- t .Fatalf ("expected the bumped row past the cursor, got %+v" , delta )
1357- }
1358- }
1359-
13601151// A database created before the seq column existed must come back with arrival
13611152// numbers backfilled from rowid, so pre-upgrade rows are addressable by cursor.
13621153func TestSQLiteStore_SeqMigrationBackfillsFromRowid (t * testing.T ) {
@@ -1452,76 +1243,6 @@ func TestSQLiteStore_ResourceCreatedAtRoundtrip(t *testing.T) {
14521243 }
14531244}
14541245
1455- // A bump that lost its enrichment (tombstone expired) must not erase the
1456- // owner/labels/createdAt the row already knows; a bump that carries fresh
1457- // enrichment wins. Mirrors TestMemoryStore_K8sEventBumpPreservesEnrichment.
1458- func TestSQLiteStore_K8sEventBumpPreservesEnrichment (t * testing.T ) {
1459- store , cleanup := createTestSQLiteStore (t )
1460- defer cleanup ()
1461- ctx := context .Background ()
1462-
1463- base := time .Now ()
1464- born := base .Add (- time .Hour ).Truncate (time .Millisecond )
1465- if err := store .Append (ctx , TimelineEvent {
1466- ID : "k8s-uid-1" , Timestamp : base , Source : SourceK8sEvent ,
1467- Kind : "Pod" , Namespace : "default" , Name : "web-abc" ,
1468- EventType : EventTypeWarning , Reason : "BackOff" , Count : 1 ,
1469- CreatedAt : & born ,
1470- Owner : & OwnerInfo {Kind : "ReplicaSet" , Name : "web" },
1471- Labels : map [string ]string {"app" : "web" },
1472- }); err != nil {
1473- t .Fatalf ("Append enriched: %v" , err )
1474- }
1475- if err := store .Append (ctx , TimelineEvent {
1476- ID : "k8s-uid-1" , Timestamp : base .Add (30 * time .Second ), Source : SourceK8sEvent ,
1477- Kind : "Pod" , Namespace : "default" , Name : "web-abc" ,
1478- EventType : EventTypeWarning , Reason : "BackOff" , Count : 5 ,
1479- }); err != nil {
1480- t .Fatalf ("Append bare bump: %v" , err )
1481- }
1482-
1483- got , err := store .Query (ctx , QueryOptions {Limit : 10 , IncludeManaged : true , IncludeK8sEvents : true })
1484- if err != nil || len (got ) != 1 {
1485- t .Fatalf ("Query: %v %+v" , err , got )
1486- }
1487- if got [0 ].Count != 5 {
1488- t .Fatalf ("expected bumped count 5, got %d" , got [0 ].Count )
1489- }
1490- if got [0 ].CreatedAt == nil || ! got [0 ].CreatedAt .Equal (born ) {
1491- t .Fatalf ("bare bump erased CreatedAt: %+v" , got [0 ].CreatedAt )
1492- }
1493- if got [0 ].Owner == nil || got [0 ].Owner .Name != "web" {
1494- t .Fatalf ("bare bump erased Owner: %+v" , got [0 ].Owner )
1495- }
1496- if got [0 ].Labels ["app" ] != "web" {
1497- t .Fatalf ("bare bump erased Labels: %+v" , got [0 ].Labels )
1498- }
1499-
1500- // The inverse: a bump that carries enrichment fills a row that lacked it.
1501- if err := store .Append (ctx , TimelineEvent {
1502- ID : "k8s-uid-2" , Timestamp : base , Source : SourceK8sEvent ,
1503- Kind : "Pod" , Namespace : "default" , Name : "late-enriched" ,
1504- EventType : EventTypeWarning , Reason : "BackOff" , Count : 1 ,
1505- }); err != nil {
1506- t .Fatalf ("Append bare first: %v" , err )
1507- }
1508- if err := store .Append (ctx , TimelineEvent {
1509- ID : "k8s-uid-2" , Timestamp : base .Add (time .Minute ), Source : SourceK8sEvent ,
1510- Kind : "Pod" , Namespace : "default" , Name : "late-enriched" ,
1511- EventType : EventTypeWarning , Reason : "BackOff" , Count : 2 ,
1512- Owner : & OwnerInfo {Kind : "Job" , Name : "batch" },
1513- }); err != nil {
1514- t .Fatalf ("Append enriched bump: %v" , err )
1515- }
1516- row , err := store .GetEvent (ctx , "k8s-uid-2" )
1517- if err != nil || row == nil {
1518- t .Fatalf ("GetEvent: %v %+v" , err , row )
1519- }
1520- if row .Owner == nil || row .Owner .Name != "batch" {
1521- t .Fatalf ("enriched bump did not fill Owner: %+v" , row .Owner )
1522- }
1523- }
1524-
15251246// Timestamps are stored as TEXT and ordered lexically; informer events carry
15261247// the host's local zone while K8s events are UTC. Without UTC normalization on
15271248// write, a local-zone wall clock sorts ahead of an earlier-instant UTC string.
@@ -1559,58 +1280,6 @@ func TestSQLiteStore_UTCTimestampOrdering(t *testing.T) {
15591280 }
15601281}
15611282
1562- // Delta reads must page by ascending arrival order so a burst larger than the
1563- // page limit isn't skipped as the server advances the cursor by each page's max
1564- // seq. Successive polls must cover every unseen event with no gaps.
1565- func TestSQLiteStore_DeltaPagesAscendingUnderLimit (t * testing.T ) {
1566- store , cleanup := createTestSQLiteStore (t )
1567- defer cleanup ()
1568- ctx := context .Background ()
1569-
1570- base := time .Now ()
1571- for i := 0 ; i < 6 ; i ++ {
1572- ev := TimelineEvent {
1573- ID : fmt .Sprintf ("e%d" , i ), Timestamp : base .Add (time .Duration (i ) * time .Second ),
1574- Source : SourceInformer , Kind : "Deployment" , Namespace : "default" ,
1575- Name : fmt .Sprintf ("e%d" , i ), EventType : EventTypeUpdate ,
1576- }
1577- if err := store .Append (ctx , ev ); err != nil {
1578- t .Fatalf ("Append %d: %v" , i , err )
1579- }
1580- }
1581-
1582- cursor := int64 (1 )
1583- seen := map [int64 ]bool {}
1584- for polls := 0 ; polls < 10 ; polls ++ {
1585- page , err := store .Query (ctx , QueryOptions {Limit : 2 , IncludeManaged : true , SinceSeq : cursor })
1586- if err != nil {
1587- t .Fatalf ("delta query: %v" , err )
1588- }
1589- if len (page ) == 0 {
1590- break
1591- }
1592- if len (page ) == 2 && page [0 ].Seq >= page [1 ].Seq {
1593- t .Fatalf ("delta page not ascending by seq: %d,%d" , page [0 ].Seq , page [1 ].Seq )
1594- }
1595- var maxSeq int64
1596- for _ , e := range page {
1597- if seen [e .Seq ] {
1598- t .Fatalf ("seq %d returned twice across polls" , e .Seq )
1599- }
1600- seen [e .Seq ] = true
1601- if e .Seq > maxSeq {
1602- maxSeq = e .Seq
1603- }
1604- }
1605- cursor = maxSeq
1606- }
1607- for want := int64 (2 ); want <= 6 ; want ++ {
1608- if ! seen [want ] {
1609- t .Fatalf ("delta paging skipped seq %d; seen=%v" , want , seen )
1610- }
1611- }
1612- }
1613-
16141283// seq must not rewind when retention empties the table: a live client's cursor
16151284// (seq>N) would otherwise go dead with no forced resync while the store lives.
16161285func TestSQLiteStore_SeqSurvivesEmptyTable (t * testing.T ) {
0 commit comments