package serial import ( "testing" "time" ) func TestCRConnectionStatusReportsDownAfterConfirmedResponseExpires(t *testing.T) { now := time.Date(2026, 9, 14, 1, 0, 0, 0, time.UTC) probe := CRProbeState{Enabled: true, EverUp: true, LastResponseAt: &now} for _, state := range []string{CRProbeStateNoResponse, CRProbeStateBusy, CRProbeStateSuppressed, CRProbeStateError} { probe.State = state for _, age := range []time.Duration{0, 4 * time.Second, CRResponseGracePeriod} { if got := CRConnectionStatus(probe, now.Add(age)); got != "up" { t.Fatalf("transient %s at %s = %s", state, age, got) } } if got := CRConnectionStatus(probe, now.Add(CRResponseGracePeriod+time.Millisecond)); got != "down" { t.Fatalf("stale %s = %s; previously confirmed port must become down", state, got) } } probe.EverUp = false if CRConnectionStatus(probe, now) != "unknown" { t.Fatal("unconfirmed response promoted") } probe.Up = true if CRConnectionStatus(probe, now) != "up" { t.Fatal("confirmed reply ignored") } probe.Enabled = false if CRConnectionStatus(probe, now) != "unknown" { t.Fatal("disabled probe promoted") } } func TestCRConnectionStatusUnknownUpDownUp(t *testing.T) { now := time.Now() probe := CRProbeState{Enabled: true, State: CRProbeStateNoResponse} if got := CRConnectionStatus(probe, now); got != "unknown" { t.Fatalf("initial = %s", got) } probe.Up, probe.EverUp, probe.LastResponseAt = true, true, &now if got := CRConnectionStatus(probe, now); got != "up" { t.Fatalf("response = %s", got) } probe.Up = false if got := CRConnectionStatus(probe, now.Add(CRResponseGracePeriod+time.Second)); got != "down" { t.Fatalf("response lost = %s", got) } probe.Up = true if got := CRConnectionStatus(probe, now.Add(time.Minute)); got != "up" { t.Fatalf("response recovered = %s", got) } }