diff --git a/docs/API.md b/docs/API.md index bd51eb2..b8513f3 100644 --- a/docs/API.md +++ b/docs/API.md @@ -43,6 +43,8 @@ Current transmitter status (read-only snapshot). Runtime indicator, alert, and q } ``` +`runtimeIndicator` is derived from the engine queue health plus any late buffers and can be "normal", "degraded", or "queueCritical". `runtimeAlert` surfaces a short reason (e.g. "queue health low" or "late buffers") when the indicator is not "normal", otherwise it stays empty. + --- ### `GET /runtime` diff --git a/internal/app/runtime_indicator_test.go b/internal/app/runtime_indicator_test.go index 44a825e..22ca93b 100644 --- a/internal/app/runtime_indicator_test.go +++ b/internal/app/runtime_indicator_test.go @@ -6,101 +6,55 @@ import ( "github.com/jan/fm-rds-tx/internal/output" ) -func TestRuntimeIndicator(t *testing.T) { +func TestRuntimeIndicatorAndAlert(t *testing.T) { cases := []struct { - name string - queueHealth output.QueueHealth - lateBuffers uint64 - want RuntimeIndicator + name string + health output.QueueHealth + lateBuffers uint64 + wantIndicator RuntimeIndicator + wantAlert string }{ { - name: "normal", - queueHealth: output.QueueHealthNormal, - lateBuffers: 0, - want: RuntimeIndicatorNormal, + name: "queue critical", + health: output.QueueHealthCritical, + lateBuffers: 0, + wantIndicator: RuntimeIndicatorQueueCritical, + wantAlert: "queue health critical", }, { - name: "degradedLateBuffers", - queueHealth: output.QueueHealthNormal, - lateBuffers: 1, - want: RuntimeIndicatorDegraded, + name: "queue low", + health: output.QueueHealthLow, + lateBuffers: 0, + wantIndicator: RuntimeIndicatorDegraded, + wantAlert: "queue health low", }, { - name: "degradedQueueLow", - queueHealth: output.QueueHealthLow, - lateBuffers: 0, - want: RuntimeIndicatorDegraded, + name: "late buffers", + health: output.QueueHealthNormal, + lateBuffers: 2, + wantIndicator: RuntimeIndicatorDegraded, + wantAlert: "late buffers", }, { - name: "queueCritical", - queueHealth: output.QueueHealthCritical, - lateBuffers: 0, - want: RuntimeIndicatorQueueCritical, - }, - { - name: "criticalLateBuffers", - queueHealth: output.QueueHealthCritical, - lateBuffers: 3, - want: RuntimeIndicatorQueueCritical, + name: "normal", + health: output.QueueHealthNormal, + lateBuffers: 0, + wantIndicator: RuntimeIndicatorNormal, + wantAlert: "", }, } for _, tc := range cases { tc := tc t.Run(tc.name, func(t *testing.T) { - if got := runtimeIndicator(tc.queueHealth, tc.lateBuffers); got != tc.want { - t.Fatalf("runtime indicator mismatch: queue=%s late=%d want=%s got=%s", - tc.queueHealth, tc.lateBuffers, tc.want, got) + t.Parallel() + got := runtimeIndicator(tc.health, tc.lateBuffers) + if got != tc.wantIndicator { + t.Fatalf("indicator: expected %s, got %s", tc.wantIndicator, got) } - }) - } -} - -func TestRuntimeAlert(t *testing.T) { - cases := []struct { - name string - queueHealth output.QueueHealth - lateBuffers uint64 - want string - }{ - { - name: "normal", - queueHealth: output.QueueHealthNormal, - lateBuffers: 0, - want: "", - }, - { - name: "lateBuffers", - queueHealth: output.QueueHealthNormal, - lateBuffers: 1, - want: "late buffers", - }, - { - name: "queueLow", - queueHealth: output.QueueHealthLow, - lateBuffers: 0, - want: "queue health low", - }, - { - name: "queueCritical", - queueHealth: output.QueueHealthCritical, - lateBuffers: 0, - want: "queue health critical", - }, - { - name: "criticalLateBuffers", - queueHealth: output.QueueHealthCritical, - lateBuffers: 5, - want: "queue health critical", - }, - } - - for _, tc := range cases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - if got := runtimeAlert(tc.queueHealth, tc.lateBuffers); got != tc.want { - t.Fatalf("runtime alert mismatch: queue=%s late=%d want=%q got=%q", - tc.queueHealth, tc.lateBuffers, tc.want, got) + alert := runtimeAlert(tc.health, tc.lateBuffers) + if alert != tc.wantAlert { + t.Fatalf("alert: expected %q, got %q", tc.wantAlert, alert) } }) }