test(runtime): shared ContainerRuntime contract suite across both backends (RIG-2493) - #720
Open
rigel-mintaka wants to merge 1 commit into
Conversation
This was referenced Aug 28, 2026
|
Compass engineering docs preview: https://compass-runner-rig-2493-u5-c.compass-eng-docs.pages.dev Deployed from |
…kends (RIG-2493) U5 of the frozen microVM Runner V2b plan (`docs/designs/infra/runtime/compass-elastic-session-runtime/microvm-v2b-guest-supervisor-exec.md`, §Plan U5) — the V2b acceptance gate. One table-driven contract suite proves `MicroVMRuntime` and `PodmanCLI` behave identically through the `runtime.ContainerRuntime` interface, run against BOTH backends, with the 6 conceded divergences (record 580-593) encoded as a per-backend capability matrix so a divergence that silently *widens* fails a row. ### What - **`contract_suite_test.go`** (UNTAGGED, package `runtime`): the shared body. `backendCaps` capability descriptor (factory + the 6 divergence flags + typed-error closures) and `runContractSuite`, a thin dispatcher whose rows are one helper each. It references ONLY untagged production symbols plus `backendCaps` — every KVM/podman-only symbol (`microvmtest`, `podmanUsable`, `buildImage`, `*DuplicateNameError`) is reached through a caps closure, so the file compiles on every platform. A `var _ = runContractSuite` roots the graph for the untagged `unused` lint pass (both real callers are tag-gated). - **`contract_podman_test.go`** (`//go:build podman`): `TestContractSuite_Podman` — skips unless `podmanUsable()`, builds the agent image once, containers run `sleep infinity` as uid 1000; all microVM divergence flags OFF so those rows self-skip; the deliberate-kill row asserts the byte-identical `*exec.ExitError` path (podman byte-path unregressed). - **`contract_microvm_test.go`** (`//go:build microvm && unix`): `TestContractSuite_MicroVM` — `microvmtest.Require(t)`, sessions with a `/workspace` share + uid 1000; all 6 divergence flags ON so every divergence row runs and a silent widening fails. Plus `TestMicroVMQBudget`, informational boot-latency + per-process PSS via `t.Logf` (record §(g)), NOT a boot gate. - **Fold, not duplicate**: `TestMicroVMLifecycleEndToEnd` (Create→Start→Exec→Stop→Remove) and `TestMicroVMExecStreamingKillSignalsExit` (ExecStreaming-kill), previously standalone in `microvm_lifecycle_microvm_test.go`, are now shared contract rows and were folded out of that file. `e2eConfig` and `TestMicroVMStartFailureLeavesNoState` (a microVM-backend-only negative with no podman analog) stay. ### Divergence 6 (deliberate-kill error shape) The shared row body proves the SAME behavioral contract — a deliberate Kill+Wait surfaces as a signalled exit `isDeliberateKill` accepts — in the two shapes the frozen code matches: microVM's portable `*ExitStatusError` (`Signal != 0`) and podman's byte-identical `*exec.ExitError` (`ExitCode() == -1`). The error SHAPE is capability-gated (`portableKillError`) rather than forced to one type, because asserting `*ExitStatusError` on podman would require a forbidden production change to `PodmanCLI` and contradict record 590-591. This honors the frozen record. ### Verification `gofmt -l` clean; `go build`/`go vet` clean untagged, under `-tags 'microvm unix'`, and under `-tags podman`; `go test -race -count=1 ./internal/runtime/...` ok; `golangci-lint run` 0 issues (untagged, and under each tag for the touched files). Live: `go test -tags podman -run TestContractSuite_Podman` PASS (all shared rows; microVM-gated rows correctly absent). Live on KVM: `go test -tags 'microvm unix' -run TestContractSuite_MicroVM` — all 15 rows PASS (the exec rows exercise the U2 guest PATH resolution and the whole suite the U4 socket-budget fix). Ledger-impact: none Spec-impact: none. Refs RIG-2493 Co-authored-by: Matt Wilkinson <matt@rigel.build>
rigel-mintaka
force-pushed
the
compass-runner/rig-2493-u4-microvm-lifecycle
branch
from
August 28, 2026 11:11
b95a89a to
9f07047
Compare
rigel-mintaka
force-pushed
the
compass-runner/rig-2493-u5-contract-suite
branch
from
August 28, 2026 11:12
79f96e3 to
e664f7e
Compare
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.
This PR is part of a stack containing 5 PRs:
mainU5 of the frozen microVM Runner V2b plan (
docs/designs/infra/runtime/compass-elastic-session-runtime/microvm-v2b-guest-supervisor-exec.md, §Plan U5) — the V2b acceptance gate. One table-driven contract suite provesMicroVMRuntimeandPodmanCLIbehave identically through theruntime.ContainerRuntimeinterface, run against BOTH backends, with the 6 conceded divergences (record 580-593) encoded as a per-backend capability matrix so a divergence that silently widens fails a row.What
contract_suite_test.go(UNTAGGED, packageruntime): the shared body.backendCapscapability descriptor (factory + the 6 divergence flags + typed-error closures) andrunContractSuite, a thin dispatcher whose rows are one helper each. It references ONLY untagged production symbols plusbackendCaps— every KVM/podman-only symbol (microvmtest,podmanUsable,buildImage,*DuplicateNameError) is reached through a caps closure, so the file compiles on every platform. Avar _ = runContractSuiteroots the graph for the untaggedunusedlint pass (both real callers are tag-gated).contract_podman_test.go(//go:build podman):TestContractSuite_Podman— skips unlesspodmanUsable(), builds the agent image once, containers runsleep infinityas uid 1000; all microVM divergence flags OFF so those rows self-skip; the deliberate-kill row asserts the byte-identical*exec.ExitErrorpath (podman byte-path unregressed).contract_microvm_test.go(//go:build microvm && unix):TestContractSuite_MicroVM—microvmtest.Require(t), sessions with a/workspaceshare + uid 1000; all 6 divergence flags ON so every divergence row runs and a silent widening fails. PlusTestMicroVMQBudget, informational boot-latency + per-process PSS viat.Logf(record §(g)), NOT a boot gate.TestMicroVMLifecycleEndToEnd(Create→Start→Exec→Stop→Remove) andTestMicroVMExecStreamingKillSignalsExit(ExecStreaming-kill), previously standalone inmicrovm_lifecycle_microvm_test.go, are now shared contract rows and were folded out of that file.e2eConfigandTestMicroVMStartFailureLeavesNoState(a microVM-backend-only negative with no podman analog) stay.Divergence 6 (deliberate-kill error shape)
The shared row body proves the SAME behavioral contract — a deliberate Kill+Wait surfaces as a signalled exit
isDeliberateKillaccepts — in the two shapes the frozen code matches: microVM's portable*ExitStatusError(Signal != 0) and podman's byte-identical*exec.ExitError(ExitCode() == -1). The error SHAPE is capability-gated (portableKillError) rather than forced to one type, because asserting*ExitStatusErroron podman would require a forbidden production change toPodmanCLIand contradict record 590-591. This honors the frozen record.Verification
gofmt -lclean;go build/go vetclean untagged, under-tags 'microvm unix', and under-tags podman;go test -race -count=1 ./internal/runtime/...ok;golangci-lint run0 issues (untagged, and under each tag for the touched files). Live:go test -tags podman -run TestContractSuite_PodmanPASS (all shared rows; microVM-gated rows correctly absent). Live on KVM:go test -tags 'microvm unix' -run TestContractSuite_MicroVM— all 15 rows PASS (the exec rows exercise the U2 guest PATH resolution and the whole suite the U4 socket-budget fix).Ledger-impact: none
Spec-impact: none. Refs RIG-2493
Co-authored-by: Matt Wilkinson matt@rigel.build