package relay import ( "testing" "time" ) func TestAdmissionCaps(t *testing.T) { now := time.Unix(1_800_000_000, 0) clock := func() time.Time { return now } l := DefaultLimits() l.AppLive, l.AppPerMinute, l.AccountLive, l.BoxLive = 2, 100, 3, 100 a := NewAdmission(l, clock) meet := Identity{"abc", "meet"} docs := Identity{"abc", "docs"} for i := 0; i < 2; i++ { if ok, r := a.Admit(meet); !ok { t.Fatalf("admit %d refused: %s", i, r) } } if ok, r := a.Admit(meet); ok || r != "app live" { t.Fatalf("third meet = %v %q", ok, r) } if ok, _ := a.Admit(docs); !ok { t.Fatal("docs first should pass") } if ok, r := a.Admit(docs); ok || r != "account live" { t.Fatalf("account cap = %v %q", ok, r) } a.Release(meet) if ok, _ := a.Admit(docs); !ok { t.Fatal("after release, account has room") } } func TestAdmissionRate(t *testing.T) { now := time.Unix(1_800_000_000, 0) clock := func() time.Time { return now } l := DefaultLimits() l.AppPerMinute = 2 a := NewAdmission(l, clock) id := Identity{"abc", "meet"} a.Admit(id) a.Release(id) a.Admit(id) a.Release(id) if ok, r := a.Admit(id); ok || r != "app rate" { t.Fatalf("rate = %v %q", ok, r) } now = now.Add(61 * time.Second) if ok, _ := a.Admit(id); !ok { t.Fatal("rate window should have rolled") } } func TestAdmissionBudgetRollsAndSeeds(t *testing.T) { now := time.Unix(1_800_000_000, 0) clock := func() time.Time { return now } l := DefaultLimits() l.AppBytesPerHour = 100 a := NewAdmission(l, clock) id := Identity{"abc", "meet"} if a.AddBytes(id, 60) { t.Fatal("60 under 100") } if !a.AddBytes(id, 50) { t.Fatal("110 over 100") } now = now.Add(61 * time.Minute) if a.OverBudget(id, now) { t.Fatal("window rolled") } b := NewAdmission(l, clock) b.Seed(id, now.Add(-30*time.Minute), 90) if !b.AddBytes(id, 20) { t.Fatal("seeded 90 + 20 over 100") } } func TestBucket(t *testing.T) { now := time.Unix(1_800_000_000, 0) clock := func() time.Time { return now } b := NewBucket(8000, clock) // 1000 bytes/s if !b.Allow(1000) { t.Fatal("first second's worth") } if b.Allow(1) { t.Fatal("empty") } now = now.Add(500 * time.Millisecond) if !b.Allow(500) || b.Allow(1) { t.Fatal("refilled 500") } }