package client import ( "testing" ) // The retained region is the one real cost stream resumption adds to the send // path: a chunk has to survive past the frame write, so it is copied. These // pin both halves of that claim — that the copy is the only cost, and that // disabling the feature removes it entirely rather than merely shrinking it. func benchStream(resumable bool) *Stream { s := &Stream{resumable: resumable} return s } // BenchmarkRetainChunk measures what emit adds over a bare frame write: the // trim-and-append into the retained region. Compare the two variants; the delta // is the per-byte copy the feature costs. func BenchmarkRetainChunk(b *testing.B) { chunk := make([]byte, DataChunkSize) window := int64(DefaultStreamWindow) b.Run("resume-on", func(b *testing.B) { s := benchStream(true) b.SetBytes(int64(len(chunk))) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { // Model the steady state: credit trails one window behind, so the // buffer trims about as fast as it grows and stays bounded. acked := s.un.end() - window if acked < 0 { acked = 0 } s.un.advance(acked) s.un.append(chunk) } if got := int64(s.un.length()); got > window+int64(len(chunk)) { b.Fatalf("retained region grew past one window: %d", got) } }) b.Run("resume-off", func(b *testing.B) { s := benchStream(false) b.SetBytes(int64(len(chunk))) b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { if s.resumable { s.un.advance(0) s.un.append(chunk) } } }) } // TestResumeDisabledAllocatesNothing pins the off switch at the level that // matters. It is easy for a feature flag to stop the wire behaviour while // leaving the bookkeeping running, which would keep the memory cost and the // per-byte copy for a user who explicitly turned it off — a partial revert that // nobody would notice. func TestResumeDisabledAllocatesNothing(t *testing.T) { chunk := make([]byte, DataChunkSize) s := benchStream(false) allocs := testing.AllocsPerRun(1000, func() { if s.resumable { s.un.advance(0) s.un.append(chunk) } }) if allocs != 0 { t.Fatalf("resume disabled still allocated %.1f times per send", allocs) } if s.un.buf != nil { t.Fatalf("resume disabled still allocated a retained region of %d bytes", cap(s.un.buf)) } } // TestRetainedRegionStaysWithinWindow is the memory bound the design rests on: // flow control already caps outstanding bytes at one window, so the retained // region needs no cap of its own. If that ever stopped holding, a busy stream // would grow without limit and the hub would be the first to notice. func TestRetainedRegionStaysWithinWindow(t *testing.T) { const window = DefaultStreamWindow chunk := make([]byte, DataChunkSize) var u unackedBuf for i := 0; i < 5000; i++ { // A sender may never have more than one window outstanding, which is // exactly what acquireSendWnd enforces before emit is ever reached. if u.length()+len(chunk) > window { u.advance(u.base() + int64(len(chunk))) } u.append(chunk) if u.length() > window { t.Fatalf("round %d: retained %d bytes for a %d-byte window", i, u.length(), window) } } if cap(u.buf) > 4*window { t.Fatalf("backing array grew to %d for a %d-byte window", cap(u.buf), window) } }