Artifact 49462684c3708ebc1076c3837e1b18a65a6501d342967f00991a9ea327a9c9fb:
- File
internal/web/opstrend_test.go
— part of check-in
[a0fa952495]
at
2026-08-26 11:24:13
on branch landing-merge
— ops: read the history back — a route across days
The store recorded renders and nothing read them. The panels are one process's memory, so the page could say how fast a route is now and never whether it is worse than it was — which is the question after a deploy.
The drilldown gains a per-day table from the store: p50, p95, max. Nearest-rank percentiles, matching how the snapshot computes them, so two numbers on one page both called p95 agree.
Empty for no traffic and empty for history-off are different answers and the page gives the right one. (user: dmestas, size: 2835) [annotate] [blame] [check-ins using] [more...]
package web import ( "bytes" "strings" "testing" ) func renderRoute(t *testing.T, v opsRouteView, store bool) string { t.Helper() var ops opsView ops.BudgetMs = 500 ops.Store.Configured = store var buf bytes.Buffer if err := opsRoutePage.ExecuteTemplate(&buf, "content", pageData{Title: "route", OpsRoute: v, Ops: ops}); err != nil { t.Fatal(err) } return buf.String() } func trendPoint(day string, n int, p50, p95, max int64) struct { Day string `json:"day"` N int `json:"n"` P50Ms int64 `json:"p50Ms"` P95Ms int64 `json:"p95Ms"` MaxMs int64 `json:"maxMs"` } { var p struct { Day string `json:"day"` N int `json:"n"` P50Ms int64 `json:"p50Ms"` P95Ms int64 `json:"p95Ms"` MaxMs int64 `json:"maxMs"` } p.Day, p.N, p.P50Ms, p.P95Ms, p.MaxMs = day, n, p50, p95, max return p } // The question after a deploy is not "how fast is this now" but "is it // worse than it was", and a snapshot of one process's memory cannot // answer it. func TestRoutePageShowsTheTrend(t *testing.T) { var v opsRouteView v.Path = "GET /{$}" v.TrendDays = 7 v.Trend = append(v.Trend, trendPoint("2026-08-24", 20, 19, 28, 29)) v.Trend = append(v.Trend, trendPoint("2026-08-26", 20, 190, 280, 290)) body := renderRoute(t, v, true) for _, want := range []string{"Across days", "2026-08-24", "28ms", "2026-08-26", "280ms"} { if !strings.Contains(body, want) { t.Errorf("the trend table is missing %q:\n%s", want, body) } } } // A day over budget is marked, the same way the panel marks one. func TestRouteTrendMarksDaysOverBudget(t *testing.T) { var v opsRouteView v.Path = "GET /{$}" v.Trend = append(v.Trend, trendPoint("2026-08-26", 20, 100, 900, 1200)) if !strings.Contains(renderRoute(t, v, true), "ci-fail-text") { t.Error("a 900ms p95 against a 500ms budget renders unmarked") } var ok opsRouteView ok.Path = "GET /{$}" ok.Trend = append(ok.Trend, trendPoint("2026-08-26", 20, 10, 20, 30)) if strings.Contains(renderRoute(t, ok, true), "ci-fail-text") { t.Error("a route comfortably inside budget renders as failing") } } // No history and history switched off are different answers, and a page // that gives one for the other sends an operator looking for traffic // that was never recorded. func TestRoutePageSaysWhyTheTrendIsEmpty(t *testing.T) { var v opsRouteView v.Path = "GET /{$}" v.TrendDays = 14 on := renderRoute(t, v, true) if !strings.Contains(on, "No history for this route in the last 14 days") { t.Errorf("a configured store with no rows does not say so:\n%s", on) } off := renderRoute(t, v, false) if !strings.Contains(off, "History is off") { t.Errorf("an unconfigured store is reported as no traffic:\n%s", off) } if strings.Contains(off, "No history for this route") { t.Error("history-off is reported as an empty window") } }