package batch import ( "context" "io" "log/slog" "testing" "time" "git.cactoz.su/cacto/home_automatization/services/ingest-service/internal/telemetry" ) func discardLogger() *slog.Logger { return slog.New(slog.NewTextHandler(io.Discard, nil)) } func reading(deviceID string) telemetry.Reading { return telemetry.Reading{DeviceID: deviceID, ZoneID: "z1", SensorType: "temperature", Value: 1} } func awaitBatch(t *testing.T, flushed chan []telemetry.Reading, timeout time.Duration) []telemetry.Reading { t.Helper() select { case batch := <-flushed: return batch case <-time.After(timeout): t.Fatal("timed out waiting for flush") return nil } } func TestBatcher_FlushesOnSize(t *testing.T) { flushed := make(chan []telemetry.Reading, 1) b := New(3, time.Hour, time.Second, func(_ context.Context, r []telemetry.Reading) error { flushed <- r return nil }, discardLogger()) b.Start() defer b.Stop() b.Add(reading("a")) b.Add(reading("b")) b.Add(reading("c")) // hits maxSize, should trigger an immediate flush batch := awaitBatch(t, flushed, time.Second) if len(batch) != 3 { t.Fatalf("got %d readings, want 3", len(batch)) } } func TestBatcher_FlushesOnInterval(t *testing.T) { flushed := make(chan []telemetry.Reading, 1) b := New(100, 20*time.Millisecond, time.Second, func(_ context.Context, r []telemetry.Reading) error { flushed <- r return nil }, discardLogger()) b.Start() defer b.Stop() b.Add(reading("a")) batch := awaitBatch(t, flushed, time.Second) if len(batch) != 1 { t.Fatalf("got %d readings, want 1", len(batch)) } } func TestBatcher_StopFlushesRemainder(t *testing.T) { flushed := make(chan []telemetry.Reading, 1) b := New(100, time.Hour, time.Second, func(_ context.Context, r []telemetry.Reading) error { flushed <- r return nil }, discardLogger()) b.Start() b.Add(reading("a")) b.Add(reading("b")) b.Stop() batch := awaitBatch(t, flushed, time.Second) if len(batch) != 2 { t.Fatalf("got %d readings, want 2", len(batch)) } }