Artifact d4c3c1457d85cea5f33414a9dda2231ee83521dadd7be4a0a6364b2150d7265e:
- File
internal/web/stream_test.go
— part of check-in
[0f1c202c58]
at
2026-08-26 12:43:53
on branch tl-rev
— Timeline: a revision signal, not rendered rows
The stream carried the filter it was opened with, so every later tick repainted the reader's page with a view they had left. That is not a bug that gets fixed once — it shipped, was fixed this morning, and would come back the next time a default moved, because the shape makes it possible.
The fleet page was rebuilt around a revision number for this reason. The timeline now follows: the signal says THAT the repository changed, the client re-requests the listing and sends its own controls with it. Nothing can capture a filter and outlive it.
A fragment is delivered as SSE but is a render, so it is marked and still measured — otherwise the refresh path would have been the one route the ops panel could not see. (user: dmestas, size: 3475) [annotate] [blame] [check-ins using] [more...]
package web import ( "net/http" "net/http/httptest" "testing" "craftdesign.group/quarry/internal/obs" ) // A live stream is not a slow page. chat, the timeline and the ops // panel hold a connection open for as long as the reader keeps the tab, // so a stream's "duration" is that tab's lifetime. The fleet recorded // timeline.sse at a p95 of 435 SECONDS, which headed the slowest-routes // panel and buried every real finding under it. // // The second consequence was worse: every stream crosses the render // budget by design, so the first-crossing alert fired on connections // that were working perfectly — the muted-channel failure that rule // exists to prevent, defeated from inside the same feature. func TestStreamsAreNotRecordedAsRenders(t *testing.T) { for _, ct := range []string{ "text/event-stream", "text/event-stream; charset=utf-8", // the charset must not defeat it } { if !isStream(ct) { t.Errorf("isStream(%q) = false, want true", ct) } } for _, ct := range []string{"text/html; charset=utf-8", "application/json", ""} { if isStream(ct) { t.Errorf("isStream(%q) = true, want false — an ordinary page must still be measured", ct) } } } // End to end through the middleware: a streaming handler files nothing, // an ordinary one files a render. func TestWithTimerSkipsStreamsAndKeepsPages(t *testing.T) { mux := http.NewServeMux() mux.HandleFunc("GET /stream", func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "text/event-stream") w.Write([]byte("data: hi\n\n")) }) mux.HandleFunc("GET /page", func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Write([]byte("<p>hi</p>")) }) // The middleware records into the process recorder; swap in a fresh // one so this test reads only its own traffic. saved := obs.Default obs.Default = obs.NewRecorder(16, nil) defer func() { obs.Default = saved }() h := withTimer(mux, mux) for _, path := range []string{"/stream", "/page", "/page"} { h.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest("GET", path, nil)) } snap := obs.Default.Snapshot() for _, p := range snap.Paths { if p.Path == "GET /stream" { t.Errorf("a stream was filed as a render: %+v", p) } } var pages int for _, p := range snap.Paths { if p.Path == "GET /page" { pages = p.N } } if pages != 2 { t.Errorf("ordinary renders recorded = %d, want 2 — the fix must not silence real pages", pages) } } // A Datastar fragment is delivered as SSE and is nevertheless a RENDER: // it completes immediately, and its duration is work rather than a tab // left open. Excluding it by content-type alone would leave the live // timeline's refresh — the route it actually spends its time in — the // one thing nothing measured. func TestOneShotFragmentsAreStillMeasured(t *testing.T) { sw := &statusWriter{ResponseWriter: httptest.NewRecorder()} sw.Header().Set("Content-Type", "text/event-stream") if !isStream(sw.Header().Get("Content-Type")) || sw.oneShot { t.Fatal("precondition: a plain event-stream response is a stream") } markOneShot(sw) if !sw.oneShot { t.Error("markOneShot did not reach the writer the timer inspects") } } // ...and marking something that is not a statusWriter must not panic: // handlers call this without knowing what they were wrapped in. func TestMarkOneShotToleratesAnUnwrappedWriter(t *testing.T) { markOneShot(httptest.NewRecorder()) }