spend_guard_test.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. package service
  2. import (
  3. "context"
  4. "testing"
  5. "github.com/stretchr/testify/require"
  6. )
  7. func TestSpendGuardBreach(t *testing.T) {
  8. cfg := SpendGuardSettings{Enabled: true, WindowMinutes: 5, TokensPerMinute: 1000, MinRequests: 5, MaxErrorRate: 0.8}
  9. // 样本不足
  10. ok, _ := spendGuardBreach(SpendGuardOffender{Requests: 3, Tokens: 100000}, cfg)
  11. require.False(t, ok)
  12. // 速率超阈
  13. ok, reason := spendGuardBreach(SpendGuardOffender{Requests: 10, Tokens: 10 * 1000 * 5, TokensPerMin: 10000}, cfg)
  14. require.True(t, ok)
  15. require.Equal(t, "token velocity", reason)
  16. // 错误率超阈
  17. ok, reason = spendGuardBreach(SpendGuardOffender{Requests: 2, Errors: 8, ErrRate: 0.8, TokensPerMin: 10}, cfg)
  18. require.True(t, ok)
  19. require.Equal(t, "error rate", reason)
  20. // 正常
  21. ok, _ = spendGuardBreach(SpendGuardOffender{Requests: 10, Tokens: 100, TokensPerMin: 20, Errors: 1, ErrRate: 0.09}, cfg)
  22. require.False(t, ok)
  23. }
  24. func TestNormalizeSpendGuardSettings(t *testing.T) {
  25. norm := normalizeSpendGuardSettings(SpendGuardSettings{})
  26. require.True(t, norm.WindowMinutes > 0)
  27. require.True(t, norm.MinRequests > 0)
  28. require.True(t, norm.MaxErrorRate > 0 && norm.MaxErrorRate <= 1)
  29. require.True(t, norm.IntervalSeconds >= 10)
  30. }
  31. func TestSpendGuardSettingsRoundtrip(t *testing.T) {
  32. repo := &stubHealthSettingRepo{}
  33. svc := NewSpendGuardService(nil, nil, repo)
  34. got := svc.GetSettings(context.Background())
  35. require.False(t, got.Enabled)
  36. updated, err := svc.UpdateSettings(context.Background(), SpendGuardSettings{Enabled: true})
  37. require.NoError(t, err)
  38. require.True(t, updated.Enabled)
  39. require.Contains(t, repo.values[SettingKeySpendGuardSettings], `"enabled":true`)
  40. require.Empty(t, svc.Events())
  41. }