account_scheduling_threshold_integration_test.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. //go:build unit
  2. package service
  3. import (
  4. "context"
  5. "testing"
  6. "time"
  7. "github.com/Wei-Shaw/sub2api/internal/config"
  8. "github.com/stretchr/testify/require"
  9. )
  10. type thresholdSelectionAccountRepoStub struct {
  11. rateLimitAccountRepoStub
  12. accounts []Account
  13. }
  14. func (r *thresholdSelectionAccountRepoStub) ListSchedulableByPlatform(_ context.Context, platform string) ([]Account, error) {
  15. filtered := make([]Account, 0, len(r.accounts))
  16. for _, account := range r.accounts {
  17. if account.Platform == platform {
  18. filtered = append(filtered, account)
  19. }
  20. }
  21. return filtered, nil
  22. }
  23. func (r *thresholdSelectionAccountRepoStub) ListSchedulableByGroupIDAndPlatform(ctx context.Context, _ int64, platform string) ([]Account, error) {
  24. return r.ListSchedulableByPlatform(ctx, platform)
  25. }
  26. func (r *thresholdSelectionAccountRepoStub) ListSchedulableUngroupedByPlatform(ctx context.Context, platform string) ([]Account, error) {
  27. return r.ListSchedulableByPlatform(ctx, platform)
  28. }
  29. func TestGatewayService_ListSchedulableAccounts_DoesNotFilterUnsupportedThresholdPlatforms(t *testing.T) {
  30. accountSchedulingThresholdsSF.Forget(SettingKeyAccountSchedulingThresholds)
  31. accountSchedulingThresholdsCache.Store(&cachedAccountSchedulingThresholds{})
  32. settingsRepo := newMockSettingRepo()
  33. settingsRepo.data[SettingKeyAccountSchedulingThresholds] = `{"openai":90}`
  34. accountRepo := &thresholdSelectionAccountRepoStub{
  35. accounts: []Account{
  36. {
  37. ID: 3101,
  38. Platform: PlatformKiro,
  39. Status: StatusActive,
  40. Schedulable: true,
  41. Credentials: map[string]any{
  42. "account_scheduling_threshold": 1,
  43. },
  44. Extra: map[string]any{
  45. "kiro_sched_utilization": 95.0,
  46. "kiro_sched_reset_at": time.Now().UTC().Add(2 * time.Hour).Format(time.RFC3339),
  47. },
  48. },
  49. {
  50. ID: 3102,
  51. Platform: PlatformKiro,
  52. Status: StatusActive,
  53. Schedulable: true,
  54. Extra: map[string]any{
  55. "kiro_sched_utilization": 42.0,
  56. "kiro_sched_reset_at": time.Now().UTC().Add(2 * time.Hour).Format(time.RFC3339),
  57. },
  58. },
  59. },
  60. }
  61. rateLimitService := NewRateLimitService(accountRepo, nil, &config.Config{}, nil, nil)
  62. rateLimitService.SetSettingService(NewSettingService(settingsRepo, &config.Config{}))
  63. svc := &GatewayService{
  64. accountRepo: accountRepo,
  65. cfg: &config.Config{},
  66. rateLimitService: rateLimitService,
  67. }
  68. accounts, useMixed, err := svc.listSchedulableAccounts(context.Background(), nil, PlatformKiro, false)
  69. require.NoError(t, err)
  70. require.False(t, useMixed)
  71. require.Len(t, accounts, 2)
  72. require.Equal(t, int64(3101), accounts[0].ID)
  73. require.Equal(t, int64(3102), accounts[1].ID)
  74. require.Equal(t, 0, accountRepo.tempCalls)
  75. }
  76. func TestOpenAIGatewayService_ListSchedulableAccounts_FiltersThresholdBlockedAccounts(t *testing.T) {
  77. accountSchedulingThresholdsSF.Forget(SettingKeyAccountSchedulingThresholds)
  78. accountSchedulingThresholdsCache.Store(&cachedAccountSchedulingThresholds{})
  79. settingsRepo := newMockSettingRepo()
  80. settingsRepo.data[SettingKeyAccountSchedulingThresholds] = `{"openai":85}`
  81. accountRepo := &thresholdSelectionAccountRepoStub{
  82. accounts: []Account{
  83. {
  84. ID: 4101,
  85. Platform: PlatformOpenAI,
  86. Status: StatusActive,
  87. Schedulable: true,
  88. Extra: map[string]any{
  89. "codex_7d_used_percent": 91.0,
  90. "codex_7d_reset_at": time.Now().UTC().Add(12 * time.Hour).Format(time.RFC3339),
  91. },
  92. },
  93. {
  94. ID: 4102,
  95. Platform: PlatformOpenAI,
  96. Status: StatusActive,
  97. Schedulable: true,
  98. Extra: map[string]any{
  99. "codex_7d_used_percent": 40.0,
  100. "codex_7d_reset_at": time.Now().UTC().Add(12 * time.Hour).Format(time.RFC3339),
  101. },
  102. },
  103. },
  104. }
  105. rateLimitService := NewRateLimitService(accountRepo, nil, &config.Config{}, nil, nil)
  106. rateLimitService.SetSettingService(NewSettingService(settingsRepo, &config.Config{}))
  107. svc := &OpenAIGatewayService{
  108. accountRepo: accountRepo,
  109. cfg: &config.Config{},
  110. rateLimitService: rateLimitService,
  111. }
  112. accounts, err := svc.listSchedulableAccounts(context.Background(), nil, PlatformOpenAI)
  113. require.NoError(t, err)
  114. require.Len(t, accounts, 1)
  115. require.Equal(t, int64(4102), accounts[0].ID)
  116. require.Equal(t, 1, accountRepo.tempCalls)
  117. }