From 6ab4c16f6883389d728d497e10f7d0fc78dec173 Mon Sep 17 00:00:00 2001 From: yetone Date: Thu, 8 Oct 2026 18:54:55 +0800 Subject: [PATCH] =?UTF-8?q?gateway=20tests:=20TestRestingKeyReadAgainInAnO?= =?UTF-8?q?rderedGroup=20has=20the=20relay=20hold=20a=20reading=20made=20a?= =?UTF-8?q?fter=20the=20key=20refused=20until=20the=20test=20has=20raised?= =?UTF-8?q?=20its=20limit=20(red=20on=20ubuntu=20CI=20-race=20at=20d7bdb07?= =?UTF-8?q?6:=20"its=20limit=20raised:=20still=20rests=20by=20window=20til?= =?UTF-8?q?l=20=E2=80=A6,=20its=20windows=20read=203=20times")=20=E2=80=94?= =?UTF-8?q?=20the=20third=20order=203e38bd76=20didn't=20cover.=20The=20pla?= =?UTF-8?q?nning's=20reading,=20still=20out=20as=20the=20key=20refused,=20?= =?UTF-8?q?came=20back=20between=20the=20refusal=20and=20the=20test=20rais?= =?UTF-8?q?ing=20the=20limit;=20ee2588c2's=20re-read=20that=20follows=20it?= =?UTF-8?q?=20at=20once=20reached=20the=20relay=20first=20too,=20read=20th?= =?UTF-8?q?e=20week=20still=20used=20up,=20and=20was=20trusted=20for=20its?= =?UTF-8?q?=20minute,=20so=20the=20planning=20after=20the=20raise=20didn't?= =?UTF-8?q?=20ask=20again=20and=20nothing=20lifted=20the=20rest=20within?= =?UTF-8?q?=20the=20test's=205=20s.=20That=20is=20the=20app=20as=20designe?= =?UTF-8?q?d=20(a=20key's=20windows=20are=20read=20at=20most=20once=20a=20?= =?UTF-8?q?minute;=20a=20reading=20made=20after=20the=20refusal=20is=20a?= =?UTF-8?q?=20true=20one),=20so=20the=20test=20was=20wrong:=20it=20assumed?= =?UTF-8?q?=20no=20reading=20could=20land=20between=20restAfter=20and=20th?= =?UTF-8?q?e=20raise.=20It=20now=20models=20the=20owner=20raising=20the=20?= =?UTF-8?q?limit=20before=20magpie=20reads=20again:=20a=20reading=20that?= =?UTF-8?q?=20reaches=20the=20relay=20after=20the=20refusal=20waits=20unti?= =?UTF-8?q?l=20the=20limit=20is=20raised.=20Red=20before:=20with=20the=20f?= =?UTF-8?q?irst=20reading=20held=20100=20ms=20and=20300=20ms=20between=20t?= =?UTF-8?q?he=20refusal=20and=20the=20raise=20(a=20preempted=20test=20goro?= =?UTF-8?q?utine),=20the=20old=20test=20fails=203=20of=205=20with=20CI's?= =?UTF-8?q?=20message=20("=E2=80=A6=20its=20windows=20read=203=20times");?= =?UTF-8?q?=20the=20new=20one=20passes=2010=20of=2010,=20and=2010=20of=201?= =?UTF-8?q?0=20with=20each=20delay=20alone.=20Still=20guards=20ee2588c2:?= =?UTF-8?q?=20with=20the=20planning's=20reading=20held=20until=20after=20t?= =?UTF-8?q?he=20refusal=20and=20the=20re-read=20taken=20out=20of=20readKey?= =?UTF-8?q?Allowance,=20the=20new=20test=20fails=203=20of=203=20("still=20?= =?UTF-8?q?rests=20by=20window=20=E2=80=A6,=20read=202=20times"),=20and=20?= =?UTF-8?q?passes=203=20of=203=20with=20it.=20go=20test=20-race=20-count?= =?UTF-8?q?=3D40=20-cpu=201,2,4=20-run=20'TestRestingKey|TestKey|Lone|Allo?= =?UTF-8?q?wance'=20./internal/gateway=20at=20load=20average=20~124,=20go?= =?UTF-8?q?=20test=20-race=20./internal/provider,=20go=20test=20-race=20./?= =?UTF-8?q?internal/gateway,=20go=20vet=20(darwin,=20GOOS=3Dlinux,=20GOOS?= =?UTF-8?q?=3Dwindows)=20and=20gofmt=20-l=20pass.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/gateway/key_limits_test.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) 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()