test(e2e): drive submitqueue request Land→landed with runway in the stack#297
Merged
Conversation
…tack ## Summary ### Why? The e2e suite barely validated anything: pings, a Land that only checked a non-empty sqid, one test that stopped at status `started`, and a thin cancel smoke test with a standing TODO. It also could not exercise the full pipeline, because `service/submitqueue/docker-compose.yml` did not include runway — the orchestrator blocks on runway's merge-conflict-check and merge signals, so every request stalled at `started`. ### What? Add `runway-service` to `service/submitqueue/docker-compose.yml`, sharing the existing `mysql-queue` (no app DB). Runway already publishes SUCCEEDED signals via its Merger extension (the noop merger wired in `service/runway/server`), so with it in the stack a request now flows all the way to `landed`. Add a reusable e2e harness (`test/e2e/submitqueue/harness_test.go`): `land`, `awaitStatus`, `awaitTerminal`, `timeline` + `assertStatusesInOrder` (white-box ordered `request_log` status history, tolerant subsequence), `terminalState` (white-box internal `RequestState` from the operating store), and `lastError` — so new per-stage and error-path tests drop in as a few lines. Rewrite the suite: `TestLand_HappyPath_ReachesLanded` drives a request to terminal success and asserts three views — the black-box `landed` Status, the ordered status history `accepted → started → batched → scored → landed`, and the operating store's internal `RequestStateLanded` (this also covers the request-log ownership invariant: every status but the synchronous `accepted` reaches storage only via the orchestrator-publishes / gateway-persists log path). The pings and graceful-shutdown checks are kept. The cancel test asserts the deterministic half (Cancel returns OK and the gateway synchronously records the `cancelling` intent). Asserting terminal `cancelled` is racy — a cancel processed before the orchestrator's start controller creates the request is rejected to the DLQ and reconciled to `error` — and needs a pipeline-pause lever, deferred to the next per-stage increment. ## Test Plan ✅ `make e2e-test` — full Docker stack (gateway + orchestrator + runway + 2 MySQL) passes; a request reaches `landed` end to end. ✅ `make fmt`; `make check-gazelle` / `make check-tidy` verified clean (only intended edits).
kevinlnew
approved these changes
Jul 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Why?
The e2e suite barely validated anything: pings, a Land that only checked a non-empty sqid, one test that stopped at status
started, and a thin cancel smoke test with a standing TODO. It also could not exercise the full pipeline, becauseservice/submitqueue/docker-compose.ymldid not include runway — the orchestrator blocks on runway's merge-conflict-check and merge signals, so every request stalled atstarted.What?
Add
runway-servicetoservice/submitqueue/docker-compose.yml, sharing the existingmysql-queue(no app DB). Runway already publishes SUCCEEDED signals via its Merger extension (the noop merger wired inservice/runway/server), so with it in the stack a request now flows all the way tolanded.Add a reusable e2e harness (
test/e2e/submitqueue/harness_test.go):land,awaitStatus,awaitTerminal,timeline+assertStatusesInOrder(white-box orderedrequest_logstatus history, tolerant subsequence),terminalState(white-box internalRequestStatefrom the operating store), andlastError— so new per-stage and error-path tests drop in as a few lines.Rewrite the suite:
TestLand_HappyPath_ReachesLandeddrives a request to terminal success and asserts three views — the black-boxlandedStatus, the ordered status historyaccepted → started → batched → scored → landed, and the operating store's internalRequestStateLanded(this also covers the request-log ownership invariant: every status but the synchronousacceptedreaches storage only via the orchestrator-publishes / gateway-persists log path). The pings and graceful-shutdown checks are kept. The cancel test asserts the deterministic half (Cancel returns OK and the gateway synchronously records thecancellingintent). Asserting terminalcancelledis racy — a cancel processed before the orchestrator's start controller creates the request is rejected to the DLQ and reconciled toerror— and needs a pipeline-pause lever, deferred to the next per-stage increment.Test Plan
✅
make e2e-test— full Docker stack (gateway + orchestrator + runway + 2 MySQL) passes; a request reacheslandedend to end.✅
make fmt;make check-gazelle/make check-tidyverified clean (only intended edits).