diff --git a/internal/gateway/key_limits_test.go b/internal/gateway/key_limits_test.go index dbc1f03b..aa7b3528 100644 --- a/internal/gateway/key_limits_test.go +++ b/internal/gateway/key_limits_test.go @@ -274,7 +274,21 @@ func TestRestingKeyReadAgainInAnOrderedGroup(t *testing.T) { week := time.Now().Add(72 * time.Hour).Truncate(time.Second).Format(time.RFC3339) var mu sync.Mutex limit, reads, raised := 800, 0, 0 + // the owner raises the limit after the key refused, before magpie + // reads its windows again: a reading that reaches the relay after the + // refusal waits for it. Else the reading ee2588c2 asks again at once, + // once one still out as the key refused is back, could reach the + // relay first (a loaded CI runner), see the week still used up and be + // trusted for its minute, past this test's wait (d7bdb076's CI) + var refused bool + raise := make(chan struct{}) relay := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + mu.Lock() + held := refused + mu.Unlock() + if held { + <-raise + } mu.Lock() l := limit reads++ @@ -322,6 +336,16 @@ func TestRestingKeyReadAgainInAnOrderedGroup(t *testing.T) { a := cs[0] t.Cleanup(func() { clearRest(a.restKey()) }) quota := []byte(`{"error":{"message":"api key 7天限额已用完","type":"rate_limit_exceeded"}}`) + mu.Lock() + refused = true + mu.Unlock() + defer func() { + select { + case <-raise: + default: + close(raise) // failed before the limit was raised + } + }() if r := s.restAfter(a, 429, http.Header{}, quota); r.Why != failQuota || r.By != "window" { t.Fatalf("out of its week: rests by %s (%s)", r.By, r.Why) } @@ -330,6 +354,7 @@ func TestRestingKeyReadAgainInAnOrderedGroup(t *testing.T) { mu.Lock() limit = 1000 mu.Unlock() + close(raise) // a reading out as the key refused is followed by another at once, // which may have seen the limit raised and brought it back already at, r := first()