package events import ( "fmt" "testing" panelv1 "github.com/dbledeez/panel/proto/panel/v1" ) func stateEvent(instanceID string) *panelv1.Event { return &panelv1.Event{Payload: &panelv1.Event_InstanceState{ InstanceState: &panelv1.InstanceStateUpdate{InstanceId: instanceID}, }} } func TestRingMonotonicIDsAndSince(t *testing.T) { r := newReplayRing(8) for i := 0; i < 5; i++ { id := r.append(stateEvent(fmt.Sprintf("i%d", i))) if want := uint64(i + 1); id != want { t.Fatalf("append id = %d, want %d", id, want) } } if r.lastID() != 5 { t.Fatalf("lastID = %d, want 5", r.lastID()) } out, ok := r.since(2) if !ok { t.Fatalf("since(2) reported a gap on an unfilled ring") } if len(out) != 3 || out[0].ID != 3 || out[2].ID != 5 { t.Fatalf("since(2) = %+v, want ids 3..5", out) } // Fully caught up → empty, gapless. if out, ok := r.since(5); len(out) != 0 || !ok { t.Fatalf("since(lastID) = (%d events, ok=%v), want (0, true)", len(out), ok) } } func TestRingOverflowReportsGap(t *testing.T) { r := newReplayRing(4) for i := 0; i < 10; i++ { // ids 1..10; ring retains 7..10 r.append(stateEvent("x")) } out, ok := r.since(3) if ok { t.Fatalf("since(3) after overflow should report a gap") } if len(out) != 4 || out[0].ID != 7 || out[3].ID != 10 { t.Fatalf("since(3) = %d events (first=%d), want retained suffix 7..10", len(out), out[0].ID) } // Resume point exactly at oldest-1 is gapless. if _, ok := r.since(6); !ok { t.Fatalf("since(oldest-1) should be gapless") } } func TestBusReplayFiltersAndStampedSubscribe(t *testing.T) { b := New(16) sub := b.SubscribeStamped(Filter{InstanceID: "a"}) defer sub.Close() b.Publish(stateEvent("a")) // id 1 b.Publish(stateEvent("b")) // id 2 b.Publish(stateEvent("a")) // id 3 // Stamped subscription only sees matching events, with real ids. got1 := <-sub.Stamped() got2 := <-sub.Stamped() if got1.ID != 1 || got2.ID != 3 { t.Fatalf("stamped ids = %d,%d, want 1,3", got1.ID, got2.ID) } // Replay applies the same filter. out, ok := b.Replay(0, Filter{InstanceID: "a"}) if !ok || len(out) != 2 || out[0].ID != 1 || out[1].ID != 3 { t.Fatalf("Replay = %+v ok=%v, want ids 1,3 gapless", out, ok) } if b.LastID() != 3 { t.Fatalf("LastID = %d, want 3", b.LastID()) } } func TestBusDroppedTotal(t *testing.T) { b := New(1) sub := b.Subscribe(Filter{}) defer sub.Close() b.Publish(stateEvent("a")) // fills the 1-slot buffer b.Publish(stateEvent("a")) // dropped if b.DroppedTotal() != 1 { t.Fatalf("DroppedTotal = %d, want 1", b.DroppedTotal()) } }