Artifact 2b0b04d1a1611d0759aad8d3c52ff046c47e501bc953caa043a6aad4a0b4171a:
- File
internal/api/opsphase_test.go
— part of check-in
[24fdaa723a]
at
2026-08-25 19:05:45
on branch search-guards
— tests: the regression guards that were never added
Seven test files were written this session, reported as landed, and never committed: `zit commit` with no paths captures TRACKED files, and new files need `zit add` first. make check passed every time because they were on disk in the worktree, which proves nothing about what is in the check-in.
What was missing:
- search kinds, held in agreement across four places (the index list, two ops validators, the scope chips, hitOf). This is the guard that caught `doc` and again `file` the moment each was added; without it the validator silently refused a kind the chips offered. - technote edits collapsing to one timeline row, folded in three different orders, because a clone delivers artifacts in wire order. - wiki and technote search matching the CURRENT revision only, the "terrified" case. - Contributors(0) meaning every contributor rather than a silent 100. - the ops phase states, the stalled-store trap, and an empty fleet.
Verified by removing them and running the suite: it stays green, which is precisely the problem — trunk has been passing on their absence. (user: dmestas, size: 3741) [annotate] [blame] [check-ins using] [more...]
package api import ( "slices" "testing" ) // repoAt builds a served store in a given condition. func repoAt(lastOK string, indexing, stalled bool, lastCount, total int, round float64) *Repo { return &Repo{ Indexing: func() bool { return indexing }, Health: func() RepoHealth { return RepoHealth{LastOK: lastOK, Stalled: stalled, LastCount: lastCount, Total: total, RoundSeconds: round} }, } } // The phase is the only thing on the ops page that is true while a // fleet is coming up: the panels below it are steady-state numbers and // read as an empty forge. A multi-repo re-ingest on this fleet was // mistaken for a hang because nothing said how far along it was. func TestFleetPhaseNamesTheMoment(t *testing.T) { cases := []struct { name string repos map[string]*Repo want string }{{ name: "nothing has finished a round yet", repos: map[string]*Repo{ "a": repoAt("", false, false, 0, 0, 0), "b": repoAt("2026-01-01T00:00:00Z", false, false, 0, 5, 1), }, want: "starting", }, { // Rebuilding outranks everything: it is the longest and the // most confusing state to sit in without being told. name: "a store is rebuilding", repos: map[string]*Repo{ "a": repoAt("2026-01-01T00:00:00Z", true, false, 0, 5, 1), "b": repoAt("2026-01-01T00:00:00Z", false, false, 0, 5, 1), }, want: "indexing", }, { name: "rounds are moving artifacts", repos: map[string]*Repo{ "a": repoAt("2026-01-01T00:00:00Z", false, false, 12, 90, 2), "b": repoAt("2026-01-01T00:00:00Z", false, false, 0, 5, 1), }, want: "syncing", }, { name: "everything is up and quiet", repos: map[string]*Repo{ "a": repoAt("2026-01-01T00:00:00Z", false, false, 0, 90, 1), }, want: "rest", }} for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { got := fleetPhase(Deps{Repos: NewRepos(tc.repos)}) if got.Name != tc.want { t.Errorf("phase = %q, want %q", got.Name, tc.want) } }) } } // A stalled store has stopped retrying: it is waiting for a person, not // for time. Counting it as pending would hold the fleet in "starting" // forever and leave a progress bar that never fills. func TestStalledStoresDoNotHoldTheFleetInStarting(t *testing.T) { p := fleetPhase(Deps{Repos: NewRepos(map[string]*Repo{ "good": repoAt("2026-01-01T00:00:00Z", false, false, 0, 10, 1), "dead": repoAt("", false, true, 0, 0, 0), })}) if p.Name != "rest" { t.Errorf("phase = %q, want rest — a stalled store is done waiting, not pending", p.Name) } if !slices.Contains(p.Stalled, "dead") { t.Errorf("stalled = %v, want it to name the store", p.Stalled) } if p.Ready != 1 || p.Repos != 2 { t.Errorf("ready/repos = %d/%d, want 1/2 — a stalled store is not ready either", p.Ready, p.Repos) } } // The numbers the banner reads: totals summed, worst round taken, and // the working list named rather than merely counted. func TestFleetPhaseRollsUpTheNumbers(t *testing.T) { p := fleetPhase(Deps{Repos: NewRepos(map[string]*Repo{ "a": repoAt("2026-01-01T00:00:00Z", true, false, 1, 100, 0.5), "b": repoAt("2026-01-01T00:00:00Z", false, false, 0, 250, 9.5), })}) if p.Artifacts != 350 { t.Errorf("artifacts = %d, want 350 summed across stores", p.Artifacts) } if p.SlowestRoundSeconds != 9.5 { t.Errorf("slowest round = %v, want the worst not the last", p.SlowestRoundSeconds) } if !slices.Contains(p.Working, "a") || len(p.Working) != 1 { t.Errorf("working = %v, want exactly the rebuilding store", p.Working) } } // An empty forge must not divide by zero or claim to be starting. func TestFleetPhaseWithNoStores(t *testing.T) { if p := fleetPhase(Deps{}); p.Name != "rest" || p.Repos != 0 { t.Errorf("phase = %+v, want a quiet empty fleet", p) } }