Skip to content

fix(lab): a failed run stops the Lab's sweep, a run cancelled while starting is cancelled on the server, and diff rows keep their order - #400

Merged
bmscomp merged 1 commit into
mainfrom
fix/lab-failed-runs-and-late-starts
Oct 18, 2026
Merged

bmscomp merged 1 commit into
mainfrom
fix/lab-failed-runs-and-late-starts

Conversation

@bmscomp

@bmscomp bmscomp commented Oct 18, 2026

Copy link
Copy Markdown
Owner

Item 1.8 of the CLI performance and stability plan (findings F24 and F40's Lab half). Independent of the other Wave 1 PRs.

Why

Three faults in kates lab, on main (6f4cf61):

  • A failed run counts as a measurement (cli/tui/lab.go:1115-1117). pollTestOnce sends FAILED and ERROR as an ordinary done message, so the run becomes a 0 rec/s iteration. A sweep, warmup or median series then launches its next step against the same failure.
  • A run cancelled while it starts keeps running. Pressing x while CreateTest is in flight sets the Lab not running. The labTestStartedMsg that follows is then dropped (:396-398), and the run the API started goes on with nothing watching or cancelling it.
  • The diff rows reorder on every frame (:994-1004). The Parameter Changes rows range over a map.

Changes

cli/tui/lab.go:

  • A FAILED or ERROR status returns a done message with an error (test <id> ended FAILED). The Lab's existing error path takes it: no iteration is recorded, the sweep, warmup and median series stop, and the status line offers r to retry.
  • A labTestStartedMsg that arrives when the Lab is no longer running cancels its run on the server. The command that does it is the new cancelRun, which the x key now uses too, so both send the same 10 s-bounded POST /api/tests/{id}/cancel.
  • The diff's parameter rows are in key order (slices.Sorted(maps.Keys(…))).

Tests

Added:

  • TestLabFailedRunStopsTheSweep, for FAILED and ERROR in parallel: pollTestOnce against a stub returning that status gives an error, and in a running sweep it records no iteration, stops the sweep, and names the status. It takes 2 s, pollTestOnce's own wait.
  • TestLabDiffParameterRowsKeepTheirOrder: 20 renders of a five-key diff are identical, and the keys are in sorted order.

Changed:

  • TestLabTestStartedMsg's "dropped when the run was cancelled during creation" case expected no command, which is the bug. It is now "cancelled on the server…", and it sees POST /api/tests/run-42/cancel reach a stub.

On main's lab.go all three fail: no cancel command, a nil error for FAILED and ERROR, and a diff that changed between frames.

Run locally, passing:

  • cd cli && go test ./..., go test -race ./tui, go vet ./....
  • golangci-lint run --new-from-rev=origin/main ./...: 0 issues.
  • scripts/check-cli-style.sh and scripts/check-cli-compat.sh: OK.
  • The backend suite, which cli/** triggers (Build & Test): this PR touches nothing under kates/. ./mvnw test on main's kates/ tree ran 1,254 tests with 0 failures and 0 errors, once for all of Wave 1.

Skipped locally: govulncheck, as go.mod is unchanged.

CI only: ./mvnw verify with the *IT tests, the Kind and Docker jobs, CodeQL and Trivy.

Deliberately not done

  • F40's other half, a topic filter with no match showing every topic (cli/tui/topics.go:90-108), is item 6.2.
  • A started message for an earlier create that arrives after the Lab has started a newer run is still taken as the current run. That needs x, then a fresh start, both inside one CreateTest round trip. The plan does not list it, and it is left out.

…tarting is cancelled on the server, and diff rows keep their order

Three Lab TUI faults:
- A FAILED or ERROR run came back as an ordinary result. It became a 0 rec/s
  iteration, and a sweep, warmup or median series launched its next step
  against the same failure.
- Pressing x while CreateTest was in flight left the run the API then started
  running: its labTestStartedMsg arrived with the Lab no longer running and
  was dropped, so nothing watched or cancelled it.
- The diff's Parameter Changes rows came from ranging over a map, so they
  reordered on every frame.

A FAILED or ERROR status now ends the run through the Lab's error path: no
iteration, the series stops, and the status line names the status, with r to
retry. A late labTestStartedMsg cancels its run on the server, through the
cancelRun command the x key now shares. The diff rows are in key order.
@bmscomp
bmscomp merged commit 10aabe4 into main Oct 18, 2026
55 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant