mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-16 07:33:06 +08:00
110 lines
4.6 KiB
Go
110 lines
4.6 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/Wei-Shaw/sub2api/internal/config"
|
|
"github.com/Wei-Shaw/sub2api/internal/pkg/logger"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestRequestLogRetention_RuntimePolicy(t *testing.T) {
|
|
for _, tt := range []struct {
|
|
name string
|
|
raw string
|
|
enabled bool
|
|
wantDays int
|
|
wantCleanup bool
|
|
}{
|
|
{"legacy uses deployment", `{"retention_days":30}`, true, 90, true},
|
|
{"short window", `{"request_retention_days":7}`, true, 7, true},
|
|
{"long window extends dedup", `{"request_retention_days":730}`, true, 730, true},
|
|
{"forever skips request and dedup deletion", `{"request_retention_days":0}`, true, 0, false},
|
|
{"works without aggregation", `{"request_retention_days":14}`, false, 14, true},
|
|
{"legacy disabled stays disabled", `{"retention_days":30}`, false, 0, false},
|
|
} {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
settings := newRuntimeSettingRepoStub()
|
|
settings.values[SettingKeyOpsRuntimeLogConfig] = tt.raw
|
|
repo := &dashboardAggregationRepoTestStub{}
|
|
svc := NewDashboardAggregationService(repo, nil, &config.Config{DashboardAgg: config.DashboardAggregationConfig{
|
|
Enabled: tt.enabled,
|
|
Retention: config.DashboardAggregationRetentionConfig{UsageLogsDays: 90, UsageBillingDedupDays: 365, HourlyDays: 180, DailyDays: 730},
|
|
}})
|
|
svc.settingRepo = settings
|
|
now := time.Date(2026, 9, 15, 12, 0, 0, 0, time.UTC)
|
|
svc.maybeCleanupRetention(context.Background(), now)
|
|
if tt.wantCleanup {
|
|
require.Equal(t, 1, repo.cleanupUsageCalls)
|
|
require.Equal(t, now.AddDate(0, 0, -tt.wantDays), repo.cleanupUsageCutoff)
|
|
require.Equal(t, now.AddDate(0, 0, -max(365, tt.wantDays)), repo.cleanupDedupCutoff)
|
|
} else {
|
|
require.Zero(t, repo.cleanupUsageCalls)
|
|
require.Zero(t, repo.cleanupDedupCalls)
|
|
}
|
|
if !tt.enabled {
|
|
require.Zero(t, repo.cleanupAggregateCalls)
|
|
}
|
|
// Read the updated policy at the next rolling cleanup.
|
|
settings.values[SettingKeyOpsRuntimeLogConfig] = `{"request_retention_days":180}`
|
|
next := now.Add(dashboardAggregationRetentionInterval)
|
|
svc.maybeCleanupRetention(context.Background(), next)
|
|
require.Equal(t, next.AddDate(0, 0, -180), repo.cleanupUsageCutoff)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRequestLogRetention_ReadFailureSkipsDeletion(t *testing.T) {
|
|
for _, raw := range []string{`{broken`, `{"request_retention_days":-1}`, `{"request_retention_days":3651}`} {
|
|
settings := newRuntimeSettingRepoStub()
|
|
settings.values[SettingKeyOpsRuntimeLogConfig] = raw
|
|
repo := &dashboardAggregationRepoTestStub{}
|
|
svc := &DashboardAggregationService{repo: repo, settingRepo: settings}
|
|
svc.runScheduledRetention()
|
|
require.Zero(t, repo.cleanupUsageCalls)
|
|
require.Zero(t, repo.cleanupDedupCalls)
|
|
require.Nil(t, svc.lastRetentionCleanup.Load())
|
|
}
|
|
settings := newRuntimeSettingRepoStub()
|
|
settings.getValueFn = func(string) (string, error) { return "", errors.New("database unavailable") }
|
|
svc := &DashboardAggregationService{repo: &dashboardAggregationRepoTestStub{}, settingRepo: settings}
|
|
svc.runScheduledRetention()
|
|
require.Nil(t, svc.lastRetentionCleanup.Load())
|
|
}
|
|
|
|
func TestRuntimeLogConfig_RequestRetentionCompatibility(t *testing.T) {
|
|
settings := newRuntimeSettingRepoStub()
|
|
settings.values[SettingKeyOpsRuntimeLogConfig] = `{"level":"info","retention_days":7,"request_retention_days":180}`
|
|
svc := &OpsService{settingRepo: settings}
|
|
require.NoError(t, logger.Init(logger.InitOptions{Level: "info", Format: "json", Output: logger.OutputOptions{ToStdout: true}}))
|
|
t.Cleanup(logger.Sync)
|
|
legacy := defaultOpsRuntimeLogConfig(nil)
|
|
legacy.RequestRetentionDays = nil
|
|
updated, err := svc.UpdateRuntimeLogConfig(context.Background(), legacy, 1)
|
|
require.NoError(t, err)
|
|
require.Equal(t, 180, *updated.RequestRetentionDays)
|
|
for _, days := range []int{0, 1, 3650} {
|
|
updated.RequestRetentionDays = &days
|
|
saved, err := svc.UpdateRuntimeLogConfig(context.Background(), updated, 1)
|
|
require.NoError(t, err)
|
|
require.Equal(t, days, *saved.RequestRetentionDays)
|
|
var persisted OpsRuntimeLogConfig
|
|
require.NoError(t, json.Unmarshal([]byte(settings.values[SettingKeyOpsRuntimeLogConfig]), &persisted))
|
|
require.Equal(t, days, *persisted.RequestRetentionDays)
|
|
}
|
|
for _, days := range []int{-1, 3651} {
|
|
updated.RequestRetentionDays = &days
|
|
before := settings.values[SettingKeyOpsRuntimeLogConfig]
|
|
_, err := svc.UpdateRuntimeLogConfig(context.Background(), updated, 1)
|
|
require.ErrorContains(t, err, "request_retention_days")
|
|
require.Equal(t, before, settings.values[SettingKeyOpsRuntimeLogConfig])
|
|
}
|
|
reset, err := svc.ResetRuntimeLogConfig(context.Background(), 1)
|
|
require.NoError(t, err)
|
|
require.Equal(t, 90, *reset.RequestRetentionDays)
|
|
}
|