|
- package app
-
- import (
- "context"
- "errors"
- "testing"
- "time"
-
- cfgpkg "github.com/jan/fm-rds-tx/internal/config"
- "github.com/jan/fm-rds-tx/internal/output"
- "github.com/jan/fm-rds-tx/internal/platform"
- )
-
- func TestFaultSeverityString(t *testing.T) {
- cases := []struct {
- severity FaultSeverity
- want string
- }{
- {FaultSeverityWarn, "warn"},
- {FaultSeverityDegraded, "degraded"},
- {FaultSeverityMuted, "muted"},
- {FaultSeverityFaulted, "faulted"},
- {FaultSeverity(99), "unknown"},
- }
- for _, tc := range cases {
- t.Run(tc.want, func(t *testing.T) {
- if got := tc.severity.String(); got != tc.want {
- t.Fatalf("expected %s, got %s", tc.want, got)
- }
- if txt, _ := tc.severity.MarshalText(); string(txt) != tc.want {
- t.Fatalf("MarshalText mismatch: want %s, got %s", tc.want, txt)
- }
- })
- }
- }
-
- func TestEngineRecordsQueueCriticalFault(t *testing.T) {
- e := NewEngine(cfgpkg.Default(), platform.NewSimulatedDriver(nil))
- e.setRuntimeState(RuntimeStateRunning)
-
- queue := output.QueueStats{Depth: 3, Health: output.QueueHealthCritical}
- for i := 0; i < queueCriticalStreakThreshold; i++ {
- e.evaluateRuntimeState(queue, false)
- }
-
- last := e.LastFault()
- if last == nil {
- t.Fatal("expected fault recorded, got nil")
- }
- if last.Reason != FaultReasonQueueCritical {
- t.Fatalf("expected queue critical reason, got %s", last.Reason)
- }
- if last.Severity != FaultSeverityDegraded {
- t.Fatalf("expected degraded severity, got %s", last.Severity)
- }
- }
-
- func TestEngineRecordsLateBufferFault(t *testing.T) {
- e := NewEngine(cfgpkg.Default(), platform.NewSimulatedDriver(nil))
- e.setRuntimeState(RuntimeStateRunning)
-
- queue := output.QueueStats{Depth: 5, Health: output.QueueHealthNormal}
- e.evaluateRuntimeState(queue, true)
-
- last := e.LastFault()
- if last == nil {
- t.Fatal("expected fault recorded for late buffers")
- }
- if last.Reason != FaultReasonLateBuffers {
- t.Fatalf("expected late buffer reason, got %s", last.Reason)
- }
- if last.Severity != FaultSeverityWarn {
- t.Fatalf("expected warn severity, got %s", last.Severity)
- }
- }
-
- func TestEngineRecordsWriteTimeoutFault(t *testing.T) {
- cfg := cfgpkg.Default()
- driver := platform.NewSimulatedDriver(&writeErrorBackend{})
- eng := NewEngine(cfg, driver)
- eng.SetChunkDuration(10 * time.Millisecond)
-
- ctx := context.Background()
- if err := eng.Start(ctx); err != nil {
- t.Fatalf("start: %v", err)
- }
- time.Sleep(120 * time.Millisecond)
- if err := eng.Stop(ctx); err != nil {
- t.Fatalf("stop: %v", err)
- }
-
- last := eng.LastFault()
- if last == nil {
- t.Fatal("expected write timeout fault")
- }
- if last.Reason != FaultReasonWriteTimeout {
- t.Fatalf("expected writeTimeout reason, got %s", last.Reason)
- }
- if last.Severity != FaultSeverityWarn {
- t.Fatalf("expected warn severity, got %s", last.Severity)
- }
- }
-
- type writeErrorBackend struct{}
-
- func (writeErrorBackend) Configure(context.Context, output.BackendConfig) error { return nil }
- func (writeErrorBackend) Write(context.Context, *output.CompositeFrame) (int, error) {
- return 0, errors.New("write timeout")
- }
- func (writeErrorBackend) Flush(context.Context) error { return nil }
- func (writeErrorBackend) Close(context.Context) error { return nil }
- func (writeErrorBackend) Info() output.BackendInfo {
- return output.BackendInfo{
- Name: "write-error",
- Description: "backend that rejects writes",
- Capabilities: output.BackendCapabilities{
- SupportsComposite: true,
- },
- }
- }
|