rate_limit_observation_database_test.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. //go:build protectionintegration
  2. package repository
  3. import (
  4. "context"
  5. "github.com/Wei-Shaw/sub2api/internal/service"
  6. "github.com/stretchr/testify/require"
  7. "sync"
  8. "testing"
  9. "time"
  10. )
  11. func TestRateLimitObservationCannotShortenConcurrentCooldown(t *testing.T) {
  12. client, db := protectionTestDatabase(t)
  13. repo := newAccountRepositoryWithSQL(client, db, nil)
  14. ctx := context.Background()
  15. a := &service.Account{Name: "cooldown-observation", Platform: service.PlatformOpenAI, Type: service.AccountTypeOAuth, Status: service.StatusActive, Concurrency: 4}
  16. require.NoError(t, repo.Create(ctx, a))
  17. later := time.Now().Add(time.Hour).UTC().Truncate(time.Second)
  18. require.NoError(t, repo.SetRateLimited(ctx, a.ID, later))
  19. var wg sync.WaitGroup
  20. errors := make(chan error, 8)
  21. for i := 0; i < 8; i++ {
  22. wg.Add(1)
  23. go func() { defer wg.Done(); errors <- repo.SetRateLimited(ctx, a.ID, time.Now().Add(5*time.Second)) }()
  24. }
  25. wg.Wait()
  26. close(errors)
  27. for err := range errors {
  28. require.NoError(t, err)
  29. }
  30. current, err := repo.GetByID(ctx, a.ID)
  31. require.NoError(t, err)
  32. require.True(t, later.Equal(*current.RateLimitResetAt), "the longest cooldown instant must survive regardless of database timezone")
  33. require.NoError(t, repo.ClearRateLimit(ctx, a.ID), "explicit administrator recovery remains available")
  34. current, err = repo.GetByID(ctx, a.ID)
  35. require.NoError(t, err)
  36. require.Nil(t, current.RateLimitResetAt)
  37. }