diff --git a/modules/pier/reaper_test.go b/modules/pier/reaper_test.go index 01e19897..e7a71f92 100644 --- a/modules/pier/reaper_test.go +++ b/modules/pier/reaper_test.go @@ -127,10 +127,13 @@ func TestSessionReaper(t *testing.T) { if na, nb := a.pier().LocalSessions(), b.pier().LocalSessions(); na != 1 || nb != 1 { t.Fatalf("local sessions while the record lives: A %d, B %d, want 1 and 1", na, nb) } + // A request's state is persisted after its answer has been streamed; + // let the last ones finish before the record expires. + time.Sleep(100 * time.Millisecond) mr.FastForward(31 * time.Minute) // A pass that cannot read the store keeps the copy (asserted below), - // so a loaded host may need a second pass; the copy is reaped once. - reapAll := func(name string, in *instance) { + // so a loaded host may need a second pass. + reapAll := func(name string, in *instance) int { t.Helper() closed := 0 deadline := time.Now().Add(5 * time.Second) @@ -140,12 +143,19 @@ func TestSessionReaper(t *testing.T) { } closed += in.pier().ReapNow(ctx) } - if closed != 1 { - t.Fatalf("%s reaped %d sessions after the record expired, want 1", name, closed) - } + return closed + } + // B did not serve the last request: only the reaper can close its + // copy. + if closed := reapAll("B", b); closed != 1 { + t.Fatalf("B reaped %d sessions after the record expired, want 1", closed) + } + // A served it; a request of A's that finished after the expiry may + // close the copy first (persist finds the record gone), so A only + // has to hold no copy. + if closed := reapAll("A", a); closed > 1 { + t.Fatalf("A reaped %d sessions, want at most 1", closed) } - reapAll("B", b) - reapAll("A", a) if a.pier().LocalSessions() != 0 || b.pier().LocalSessions() != 0 { t.Fatalf("copies left: A %d, B %d", a.pier().LocalSessions(), b.pier().LocalSessions()) }