opencode-cursor-agent/internal/pool/pool_test.go

153 lines
3.9 KiB
Go
Raw Permalink Normal View History

2026-03-30 14:09:15 +00:00
package pool
import (
"testing"
"time"
)
func TestEmptyPool(t *testing.T) {
p := NewAccountPool(nil)
if got := p.GetNextConfigDir(); got != "" {
t.Fatalf("expected empty string for empty pool, got %q", got)
}
if p.Count() != 0 {
t.Fatalf("expected count 0, got %d", p.Count())
}
}
func TestSingleDir(t *testing.T) {
p := NewAccountPool([]string{"/dir1"})
if got := p.GetNextConfigDir(); got != "/dir1" {
t.Fatalf("expected /dir1, got %q", got)
}
if got := p.GetNextConfigDir(); got != "/dir1" {
t.Fatalf("expected /dir1 again, got %q", got)
}
}
func TestRoundRobin(t *testing.T) {
p := NewAccountPool([]string{"/a", "/b", "/c"})
got := []string{
p.GetNextConfigDir(),
p.GetNextConfigDir(),
p.GetNextConfigDir(),
p.GetNextConfigDir(),
}
want := []string{"/a", "/b", "/c", "/a"}
for i, w := range want {
if got[i] != w {
t.Fatalf("call %d: expected %q, got %q", i, w, got[i])
}
}
}
func TestLeastBusy(t *testing.T) {
p := NewAccountPool([]string{"/dir1", "/dir2", "/dir3"})
p.ReportRequestStart("/dir1")
p.ReportRequestStart("/dir2")
if got := p.GetNextConfigDir(); got != "/dir3" {
t.Fatalf("expected /dir3 (least busy), got %q", got)
}
p.ReportRequestStart("/dir3")
p.ReportRequestEnd("/dir1")
if got := p.GetNextConfigDir(); got != "/dir1" {
t.Fatalf("expected /dir1 after end, got %q", got)
}
}
func TestSkipsRateLimited(t *testing.T) {
p := NewAccountPool([]string{"/dir1", "/dir2"})
p.ReportRateLimit("/dir1", 60000)
if got := p.GetNextConfigDir(); got != "/dir2" {
t.Fatalf("expected /dir2, got %q", got)
}
if got := p.GetNextConfigDir(); got != "/dir2" {
t.Fatalf("expected /dir2 again, got %q", got)
}
}
func TestFallbackToSoonestRecovery(t *testing.T) {
p := NewAccountPool([]string{"/dir1", "/dir2"})
p.ReportRateLimit("/dir1", 60000)
p.ReportRateLimit("/dir2", 30000)
// dir2 recovers sooner — should be selected
if got := p.GetNextConfigDir(); got != "/dir2" {
t.Fatalf("expected /dir2 (sooner recovery), got %q", got)
}
}
func TestActiveRequestsDoesNotGoNegative(t *testing.T) {
p := NewAccountPool([]string{"/dir1"})
p.ReportRequestEnd("/dir1")
p.ReportRequestEnd("/dir1")
if got := p.GetNextConfigDir(); got != "/dir1" {
t.Fatalf("pool should still work, got %q", got)
}
}
func TestIgnoreUnknownConfigDir(t *testing.T) {
p := NewAccountPool([]string{"/dir1"})
p.ReportRequestStart("/nonexistent")
p.ReportRequestEnd("/nonexistent")
p.ReportRateLimit("/nonexistent", 60000)
if got := p.GetNextConfigDir(); got != "/dir1" {
t.Fatalf("expected /dir1, got %q", got)
}
}
func TestRateLimitExpires(t *testing.T) {
p := NewAccountPool([]string{"/dir1", "/dir2"})
p.ReportRateLimit("/dir1", 50)
if got := p.GetNextConfigDir(); got != "/dir2" {
t.Fatalf("immediately expected /dir2, got %q", got)
}
time.Sleep(100 * time.Millisecond)
if got := p.GetNextConfigDir(); got != "/dir1" {
t.Fatalf("after expiry expected /dir1, got %q", got)
}
}
func TestGlobalPool(t *testing.T) {
InitAccountPool([]string{"/g1", "/g2"})
if got := GetNextAccountConfigDir(); got != "/g1" {
t.Fatalf("expected /g1, got %q", got)
}
if got := GetNextAccountConfigDir(); got != "/g2" {
t.Fatalf("expected /g2, got %q", got)
}
if got := GetNextAccountConfigDir(); got != "/g1" {
t.Fatalf("expected /g1 again, got %q", got)
}
}
func TestGlobalPoolEmpty(t *testing.T) {
InitAccountPool(nil)
if got := GetNextAccountConfigDir(); got != "" {
t.Fatalf("expected empty string for empty global pool, got %q", got)
}
}
func TestGlobalPoolReinit(t *testing.T) {
InitAccountPool([]string{"/old1", "/old2"})
GetNextAccountConfigDir()
InitAccountPool([]string{"/new1"})
if got := GetNextAccountConfigDir(); got != "/new1" {
t.Fatalf("expected /new1 after reinit, got %q", got)
}
}
func TestGlobalPoolFunctionsNoopBeforeInit(t *testing.T) {
InitAccountPool(nil)
ReportRequestStart("/dir1")
ReportRequestEnd("/dir1")
ReportRateLimit("/dir1", 1000)
}