Smoke test
Rendered from docs/smoke-test.md in the repository.
scripts/smoke-test.sh exercises the full happy path of the dev environment: build the image, launch a container, do an HTTPS git push from inside it via the credential helper from item C, verify the push by re-cloning on the host, and tear the container down.
It retroactively verifies the two deferred acceptance criteria of item D:
- D-AC2 —
git pushfrom inside the container works non-interactively. - D-AC3 — credentials never appear in image layers or container logs.
Prerequisites#
The script refuses to run unless all of these hold:
dockerorpodmanis onPATH.agent-containeris executable../.envexists withGH_TOKEN,GIT_USER_NAME,GIT_USER_EMAILnon-empty.AGENT_CONTAINER_SMOKE_REPOenv var is set toowner/nameof a GitHub repo yourGH_TOKENcan push to. The test pushes a heartbeat commit there.
No default is provided for AGENT_CONTAINER_SMOKE_REPO on purpose: the script is destructive against that repo (one commit per run).
Running#
AGENT_CONTAINER_SMOKE_REPO=your-handle/agent-container-smoke-target ./scripts/smoke-test.sh
Exit code is 0 on PASS, non-zero on FAIL. On failure the script dumps agent-container logs smoketest to stderr before tearing the container down.
What it does#
- Pre-flight — checks runtime,
agent-container,.envkeys, target repo env var. - Build —
agent-container build. - Up —
agent-container up smoketest; reads the assigned port from the state file. - Wait for sshd —
nc -z localhost <port>polled up to 30s. - In-container push —
<runtime> exec -i agent-container-smoketest bash -s <<…runs a small heredoc that clones the target repo into/workspace, appends a timestamped line toSMOKE_LOG.md, commits with a(#1)reference, and pushes via HTTPS. The credential helper from item C resolves$GH_TOKENat push time. The heredoc is piped over stdin so the token never reaches argv. - Verify on host — re-clones the target repo into a temp dir using the same credential helper pattern (so the host-side verify does not depend on a long-lived
git credentialconfig) and greps for the heartbeat line. - Cleanup — a
trap cleanup EXIT INT TERMensures the container and its workspace volume are removed regardless of pass/fail/interrupt.
Safety properties#
- No
echo/printf/catof any secret env var. Phase headers and short status lines only. - No
--no-verify,--amend, or force-push anywhere. - Touches host filesystem only under
$(mktemp -d -t agent-container-smoke.XXXXXX)(always/tmpor$TMPDIR), which is removed in the trap. - The
git pushoutput is grep-filtered to drop anything matchingtoken|password|x-access-token(defensive — git itself does not normally echo credentials, but progress lines can be surprising). - Re-runnable: each run starts from a clean state because pre-flight verifies prereqs and cleanup destroys the previous container + volume.
What it does NOT verify#
- Parallel-container safety (item E core AC). Smoke test launches a single instance. Run
agent-container up alpha && agent-container up bravo && agent-container listseparately to confirm. - Attach UX (item F). The smoke test uses
execrather thanssh, so it never exercises host-key verification. Verify attach manually:agent-container attach smoketest(oragent-container attach --local smoketest) while a container is running. Since Feature 018 attach is verified against the key the deploy pinned — if it warns that nothing is pinned and asks, the capture did not happen, which is itself the finding. - Real image size.
agent-container builddoes not print the resulting size. After a successful run inspect manually:docker images localhost/agent-container:latest(orpodman images …).