package notify import ( "errors" "testing" "time" ) func TestGetSignalReliabilityStatsDefaults(t *testing.T) { clientStats, err := GetSignalReliabilityStatsClient(NewClient()) if err != nil { t.Fatalf("GetSignalReliabilityStatsClient failed: %v", err) } if clientStats != (SignalReliabilityStats{}) { t.Fatalf("client default stats mismatch: %+v", clientStats) } serverStats, err := GetSignalReliabilityStatsServer(NewServer()) if err != nil { t.Fatalf("GetSignalReliabilityStatsServer failed: %v", err) } if serverStats != (SignalReliabilityStats{}) { t.Fatalf("server default stats mismatch: %+v", serverStats) } } func TestGetSignalReliabilityStatsRejectsNil(t *testing.T) { if _, err := GetSignalReliabilityStatsClient(nil); !errors.Is(err, errSignalReliabilityStatsClientNil) { t.Fatalf("GetSignalReliabilityStatsClient nil error = %v, want %v", err, errSignalReliabilityStatsClientNil) } if _, err := GetSignalReliabilityStatsServer(nil); !errors.Is(err, errSignalReliabilityStatsServerNil) { t.Fatalf("GetSignalReliabilityStatsServer nil error = %v, want %v", err, errSignalReliabilityStatsServerNil) } } func TestSendSignalWithAckTrackedStats(t *testing.T) { pool := newSignalAckPool() state := newSignalReliabilityState() err := sendSignalWithAckTracked(state, "scope", 1001, 100*time.Millisecond, pool, func() error { go func() { time.Sleep(time.Millisecond) pool.deliver("scope", 1001) }() return nil }) if err != nil { t.Fatalf("sendSignalWithAckTracked success path failed: %v", err) } stats := state.snapshot() if got, want := stats.AckWaitTotal, uint64(1); got != want { t.Fatalf("AckWaitTotal mismatch: got %d want %d", got, want) } if got, want := stats.AckDeliverTotal, uint64(1); got != want { t.Fatalf("AckDeliverTotal mismatch: got %d want %d", got, want) } if got, want := stats.AckTimeoutTotal, uint64(0); got != want { t.Fatalf("AckTimeoutTotal mismatch: got %d want %d", got, want) } if got, want := stats.AckCanceledTotal, uint64(0); got != want { t.Fatalf("AckCanceledTotal mismatch: got %d want %d", got, want) } } func TestSendSignalWithAckTrackedTimeoutAndCanceledStats(t *testing.T) { timeoutPool := newSignalAckPool() timeoutState := newSignalReliabilityState() err := sendSignalWithAckTracked(timeoutState, "scope-timeout", 1002, time.Millisecond, timeoutPool, func() error { return nil }) if !errors.Is(err, errSignalAckTimeout) { t.Fatalf("timeout error = %v, want %v", err, errSignalAckTimeout) } timeoutStats := timeoutState.snapshot() if got, want := timeoutStats.AckTimeoutTotal, uint64(1); got != want { t.Fatalf("AckTimeoutTotal mismatch: got %d want %d", got, want) } cancelPool := newSignalAckPool() cancelState := newSignalReliabilityState() err = sendSignalWithAckTracked(cancelState, "scope-cancel", 1003, 100*time.Millisecond, cancelPool, func() error { go func() { time.Sleep(time.Millisecond) cancelPool.closeScope("scope-cancel") }() return nil }) if !errors.Is(err, errSignalAckCanceled) { t.Fatalf("cancel error = %v, want %v", err, errSignalAckCanceled) } cancelStats := cancelState.snapshot() if got, want := cancelStats.AckCanceledTotal, uint64(1); got != want { t.Fatalf("AckCanceledTotal mismatch: got %d want %d", got, want) } }