Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
package processing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func TestWaitRateSerializesConcurrentCallers(t *testing.T) {
|
||||
t.Parallel()
|
||||
c := &OpenAIClient{MinInterval: 30 * time.Millisecond}
|
||||
const n = 8
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(n)
|
||||
start := time.Now()
|
||||
for i := 0; i < n; i++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := c.waitRate(context.Background()); err != nil {
|
||||
t.Errorf("waitRate: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
elapsed := time.Since(start)
|
||||
// With reservation under the lock, n callers need ~ (n-1)*MinInterval.
|
||||
minExpected := time.Duration(n-2) * c.MinInterval
|
||||
if elapsed < minExpected {
|
||||
t.Fatalf("elapsed %v too short for %d serialized waits (want >= %v)", elapsed, n, minExpected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStartLimiterAllowConcurrent(t *testing.T) {
|
||||
t.Parallel()
|
||||
l := NewStartLimiter(10, time.Minute)
|
||||
company := uuid.New()
|
||||
var allowed atomic.Int64
|
||||
var wg sync.WaitGroup
|
||||
const n = 40
|
||||
wg.Add(n)
|
||||
for i := 0; i < n; i++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if l.Allow(company) {
|
||||
allowed.Add(1)
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
if got := allowed.Load(); got != 10 {
|
||||
t.Fatalf("allowed=%d want 10", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStartLimiterSeparateCompanies(t *testing.T) {
|
||||
t.Parallel()
|
||||
l := NewStartLimiter(3, time.Minute)
|
||||
a, b := uuid.New(), uuid.New()
|
||||
for i := 0; i < 3; i++ {
|
||||
if !l.Allow(a) {
|
||||
t.Fatalf("company A start %d should allow", i)
|
||||
}
|
||||
}
|
||||
if l.Allow(a) {
|
||||
t.Fatal("company A should be rate limited")
|
||||
}
|
||||
if !l.Allow(b) {
|
||||
t.Fatal("company B should not share A budget")
|
||||
}
|
||||
if NewStartLimiter(1, time.Minute) == nil {
|
||||
t.Fatal("NewStartLimiter must return non-nil")
|
||||
}
|
||||
var nilLimiter *StartLimiter
|
||||
if !nilLimiter.Allow(a) {
|
||||
t.Fatal("nil StartLimiter must allow (fail-open)")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user