Skip to content
quarry Artifact [739f69317d]
Login

Artifact [739f69317d]

Artifact 739f69317d584a827727eef4d4ed7fb51437d709b0b1bbf6e0bf1d5ae5f78a21:


package streamcap

import (
	"net/http/httptest"
	"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")
}

// The address is the host alone: two connections from one machine
// differ only by port and must count as one reader.
func TestTheAddressIsTheHostWithoutItsPort(t *testing.T) {
	a := httptest.NewRequest("GET", "/", nil)
	a.RemoteAddr = "203.0.113.9:5000"
	b := httptest.NewRequest("GET", "/", nil)
	b.RemoteAddr = "203.0.113.9:6000"
	if Addr(a) != Addr(b) {
		t.Fatalf("FAIL: one host read as two addresses: %q %q", Addr(a), Addr(b))
	}
	t.Log("ok: ports do not split an address")
}

// Behind the forge's TLS proxy every socket is the proxy's, so readers
// are told apart by the address the proxy forwards. Without that, the
// per-address cap would be one cap for every anonymous reader at once.
func TestReadersBehindTheProxyAreToldApart(t *testing.T) {
	a := httptest.NewRequest("GET", "/", nil)
	a.RemoteAddr = "127.0.0.1:5000"
	a.Header.Set("X-Forwarded-For", "198.51.100.1")
	b := httptest.NewRequest("GET", "/", nil)
	b.RemoteAddr = "127.0.0.1:5001"
	b.Header.Set("X-Forwarded-For", "198.51.100.2")
	if Addr(a) == Addr(b) {
		t.Fatalf("FAIL: two readers behind the proxy read as one address %q", Addr(a))
	}
	t.Log("ok: the forwarded address tells readers apart")
}