package streamcap
import (
"fmt"
"testing"
)
// One address may hold only its share; the next is refused until one
// of its streams ends.
func TestAnAddressIsCappedAndGetsItsSlotBack(t *testing.T) {
l := New(2, 10)
r1, ok1 := l.Acquire("a")
_, ok2 := l.Acquire("a")
if !ok1 || !ok2 {
t.Fatal("FAIL: an address was refused below its cap")
}
if _, ok := l.Acquire("a"); ok {
t.Fatal("FAIL: an address was admitted past its cap")
}
if _, ok := l.Acquire("b"); !ok {
t.Fatal("FAIL: a second address was refused for the first one's streams")
}
r1()
if _, ok := l.Acquire("a"); !ok {
t.Fatal("FAIL: an ended stream did not give its address the slot back")
}
t.Log("ok: per-address cap refuses at N+1 and releases")
}
// The total holds however many addresses the streams come from.
func TestTheTotalHoldsAcrossAddresses(t *testing.T) {
l := New(5, 3)
var releases []func()
for _, a := range []string{"a", "b", "c"} {
r, ok := l.Acquire(a)
if !ok {
t.Fatalf("FAIL: %s refused below the total", a)
}
releases = append(releases, r)
}
if _, ok := l.Acquire("d"); ok {
t.Fatal("FAIL: a fourth address was admitted past the total")
}
releases[0]()
releases[0]() // a second release must not free a slot it does not hold
if _, ok := l.Acquire("d"); !ok {
t.Fatal("FAIL: an ended stream did not return its slot to the total")
}
if _, ok := l.Acquire("e"); ok {
t.Fatal("FAIL: releasing twice freed two slots")
}
t.Log("ok: total cap holds across addresses; release is idempotent")
}
// An IPv6 client is handed a whole /64 and can pick a fresh address in
// it for every stream, so the /64 is one reader: eight streams from
// eight addresses in it fill its share, and another /64 is untouched.
func TestAnIPv6SlashSixtyFourIsOneAddress(t *testing.T) {
l := New(PerAddress, Total)
for i := 0; i < PerAddress; i++ {
if _, ok := l.Acquire(fmt.Sprintf("2001:db8:1:2::%x", i+1)); !ok {
t.Fatalf("FAIL: address %d in the /64 refused below the cap", i+1)
}
}
if _, ok := l.Acquire("2001:db8:1:2:ffff::9"); ok {
t.Fatal("FAIL: a fresh address in a full /64 was admitted")
}
if _, ok := l.Acquire("2001:db8:1:3::1"); !ok {
t.Fatal("FAIL: a neighbouring /64 was refused for another's streams")
}
t.Log("ok: a /64 shares one cap; its neighbour does not")
}
// IPv4 stays exact: an address is not widened to its neighbours.
func TestAnIPv4AddressStaysExact(t *testing.T) {
l := New(1, Total)
if _, ok := l.Acquire("203.0.113.1"); !ok {
t.Fatal("FAIL: first address refused")
}
if _, ok := l.Acquire("203.0.113.2"); !ok {
t.Fatal("FAIL: a neighbouring IPv4 address shared the first one's cap")
}
t.Log("ok: IPv4 addresses are counted one by one")
}