diff --git a/events.go b/events.go index 58f2b9a..e582e06 100644 --- a/events.go +++ b/events.go @@ -12,6 +12,9 @@ import ( const ( initialDelay = 60 * time.Second cleanupInterval = 1 * time.Hour + + // minRetentionDays guards against a cutoff at or after NOW(), which would delete all event history. + minRetentionDays = 1 ) // Use parameterized queries to prevent SQL injection @@ -46,6 +49,10 @@ func enableHasuraEventCleaner(ctx context.Context) error { logger := cfg.Logger cfgMutex.RUnlock() + if clearOlderThan < minRetentionDays { + return fmt.Errorf("HASURA_EVENT_CLEANER_OLDER_THAN must be at least %d day, got %d: event cleaner not started", minRetentionDays, clearOlderThan) + } + logger.Info(&libpack_logger.LogMessage{ Message: "Event cleaner enabled", Pairs: map[string]any{"interval_in_days": clearOlderThan}, diff --git a/events_retention_test.go b/events_retention_test.go new file mode 100644 index 0000000..b43d234 --- /dev/null +++ b/events_retention_test.go @@ -0,0 +1,26 @@ +package main + +import ( + "context" + "testing" + + libpack_logger "github.com/lukaszraczylo/graphql-monitoring-proxy/logging" + "github.com/stretchr/testify/assert" +) + +// Pins theorems/Theorems/EventCleaner.lean: a retention below one day would delete all event history. +func TestEnableHasuraEventCleaner_RejectsNonPositiveRetention(t *testing.T) { + for _, days := range []int{0, -1, -30} { + cfgMutex.Lock() + cfg = &config{Logger: libpack_logger.New()} + cfg.HasuraEventCleaner.Enable = true + cfg.HasuraEventCleaner.EventMetadataDb = "postgres://fake:fake@127.0.0.1:1/fake" + cfg.HasuraEventCleaner.ClearOlderThan = days + cfgMutex.Unlock() + + ctx, cancel := context.WithCancel(context.Background()) + err := enableHasuraEventCleaner(ctx) + cancel() + assert.Error(t, err, "days=%d", days) + } +}