test: fold remaining Docker lanes into QA (#97708)

This commit is contained in:
Dallin Romney
2026-06-29 00:39:06 -07:00
committed by GitHub
parent 0ce10d7793
commit 96c8338d5b
19 changed files with 211 additions and 37 deletions
@@ -24,7 +24,7 @@ scenario:
codeRefs:
- src/crestodian/operations.ts
- scripts/e2e/crestodian-first-run-spec.json
- scripts/e2e/crestodian-first-run-docker-client.ts
- test/e2e/qa-lab/runtime/crestodian-first-run-docker-client.ts
- extensions/qa-lab/src/suite-runtime-agent-process.ts
execution:
kind: flow
@@ -0,0 +1,28 @@
title: Docker agent bundle MCP tools
scenario:
id: docker-agent-bundle-mcp-tools
surface: docker-podman-hosting
category: docker-podman-hosting.agent-sandbox-and-tooling
coverage:
primary:
- docker.backed-agent-sandbox-support
objective: Verify the package-installed Docker image can materialize bundled MCP tools for an agent run and apply tool policy inside the container-hosted runtime.
successCriteria:
- The functional Docker E2E image starts with an empty OpenClaw test state.
- The mounted QA Lab harness imports packaged `dist` modules from the installed app, not source modules.
- Bundled MCP tools materialize for a Docker-hosted agent session and respect effective tool policy.
- The probe MCP server returns the expected tool result through the container runtime.
docsRefs:
- docs/install/docker.md
- docs/help/testing.md
codeRefs:
- scripts/e2e/agent-bundle-mcp-tools-docker.sh
- test/e2e/qa-lab/runtime/agent-bundle-mcp-tools-docker-client.ts
execution:
kind: script
path: scripts/qa/docker-e2e-lane.ts
summary: Runs the existing agent-bundle-mcp-tools Docker E2E lane for Docker-backed agent tooling coverage.
args:
- --lane
- agent-bundle-mcp-tools
@@ -0,0 +1,28 @@
title: Docker agents delete shared workspace
scenario:
id: docker-agents-delete-shared-workspace
surface: docker-podman-hosting
category: docker-podman-hosting.agent-sandbox-and-tooling
coverage:
primary:
- docker.backed-agent-sandbox-support
objective: Verify Docker-hosted agent workspace deletion keeps shared workspace state safe while running against the package-installed image.
successCriteria:
- The Docker lane starts from an empty OpenClaw state.
- The in-container CLI resolves from the installed app image.
- "`openclaw agents delete --force --json` preserves the configured shared workspace."
- The fixture assertion validates the JSON result and workspace state.
docsRefs:
- docs/install/docker.md
- docs/help/testing.md
codeRefs:
- scripts/e2e/agents-delete-shared-workspace-docker.sh
- scripts/e2e/lib/fixture.mjs
execution:
kind: script
path: scripts/qa/docker-e2e-lane.ts
summary: Runs the existing agents-delete-shared-workspace Docker E2E lane for Docker-hosted agent workspace safety coverage.
args:
- --lane
- agents-delete-shared-workspace
@@ -1,14 +1,18 @@
title: Docker Compose setup evidence
title: Docker setup and Compose evidence
scenario:
id: docker-compose-setup
surface: docker-podman-hosting
category: docker-podman-hosting.container-operations
category: docker-podman-hosting.container-setup
coverage:
primary:
- docker.compose
- docker.local-image-setup-script
- docker.only-first-run-notes
objective: Link Docker Compose setup e2e coverage to Docker maturity accounting.
successCriteria:
- The Docker setup script builds local images, reuses preloaded GHCR images in offline mode, and preserves BuildKit behavior.
- First-run setup emits Docker-only post-start notes without printing the gateway token.
- Docker Compose gateway and CLI service command shape stays in sync.
- Compose service env, token, auth-profile, timezone, and optional env-file defaults stay aligned.
- Container-side state, config, and workspace paths override host `.env` values.
@@ -16,8 +20,9 @@ scenario:
- docs/install/docker.md
- docs/help/testing.md
codeRefs:
- scripts/docker/setup.sh
- src/docker-setup.e2e.test.ts
execution:
kind: vitest
path: src/docker-setup.e2e.test.ts
summary: Vitest e2e coverage for Docker Compose setup and mount/env contracts.
summary: Vitest e2e coverage for Docker setup script, first-run notes, Compose service shape, and mount/env contracts.
@@ -0,0 +1,32 @@
title: Docker Crestodian first-run onboarding
scenario:
id: docker-crestodian-first-run
surface: docker-podman-hosting
category: docker-podman-hosting.container-setup
coverage:
primary:
- docker.first-run-onboarding
secondary:
- raspberry-pi.first-run-verification
objective: Verify a fresh package-installed Docker state routes through modern first-run onboarding and Crestodian setup without leaking secrets.
successCriteria:
- A bare invocation routes to onboarding and modern onboard routes to Crestodian.
- Crestodian reports missing config, writes the default workspace/model, and creates the configured agent.
- Discord setup is written through a SecretRef without persisting the raw token.
- Config validation and expected Crestodian audit entries succeed.
docsRefs:
- docs/install/docker.md
- docs/cli/crestodian.md
- docs/help/testing.md
codeRefs:
- scripts/e2e/crestodian-first-run-docker.sh
- test/e2e/qa-lab/runtime/crestodian-first-run-docker-client.ts
- scripts/e2e/crestodian-first-run-spec.json
execution:
kind: script
path: scripts/qa/docker-e2e-lane.ts
summary: Runs the existing Crestodian first-run Docker E2E lane and records primary Docker first-run onboarding evidence; the Raspberry Pi link is secondary because this is generic Linux/container first-run proof, not Pi hardware proof.
args:
- --lane
- crestodian-first-run
@@ -0,0 +1,28 @@
title: Docker gateway network access
scenario:
id: docker-gateway-network
surface: docker-podman-hosting
category: docker-podman-hosting.container-operations
coverage:
primary:
- docker.compose-network-access
objective: Verify a Docker-networked client container can connect to the Gateway container over the compose-style service network and receive a health summary.
successCriteria:
- The gateway container starts on an isolated Docker network with token auth.
- A separate client container connects over `ws://<gateway-container>:<port>`.
- The client completes the Gateway protocol connect request with the current protocol version.
- The health RPC returns a structured Gateway health summary.
docsRefs:
- docs/install/docker.md
- docs/help/testing.md
codeRefs:
- scripts/e2e/gateway-network-docker.sh
- scripts/e2e/lib/gateway-network/client.mjs
execution:
kind: script
path: scripts/qa/docker-e2e-lane.ts
summary: Runs the existing gateway-network Docker E2E lane for compose-style container network access coverage.
args:
- --lane
- gateway-network
@@ -0,0 +1,31 @@
title: Docker npm onboard channel agent
scenario:
id: docker-npm-onboard-channel-agent
surface: docker-podman-hosting
category: docker-podman-hosting.agent-sandbox-and-tooling
coverage:
primary:
- docker.backed-agent-sandbox-support
secondary:
- docker.first-run-onboarding
objective: Verify a package-installed Docker runner can complete non-interactive onboarding, configure a channel, start Gateway-backed agent behavior, and complete a mocked model turn.
successCriteria:
- The candidate OpenClaw tarball installs in a clean Docker home.
- Non-interactive onboarding configures local Gateway auth and model state.
- Channel setup writes the expected account config and status surfaces.
- A local agent turn reaches the mocked OpenAI provider and returns the success marker.
docsRefs:
- docs/install/docker.md
- docs/help/testing.md
- docs/cli/onboard.md
codeRefs:
- scripts/e2e/npm-onboard-channel-agent-docker.sh
- scripts/e2e/lib/npm-onboard-channel-agent/assertions.mjs
execution:
kind: script
path: scripts/qa/docker-e2e-lane.ts
summary: Runs the existing npm-onboard-channel-agent Docker E2E lane for package-installed Docker agent setup and turn coverage.
args:
- --lane
- npm-onboard-channel-agent
+1 -1
View File
@@ -28,7 +28,7 @@ docker_e2e_run_with_harness \
bash -lc "set -euo pipefail
source scripts/lib/openclaw-e2e-instance.sh
openclaw_e2e_eval_test_state_from_b64 \"\${OPENCLAW_TEST_STATE_SCRIPT_B64:?missing OPENCLAW_TEST_STATE_SCRIPT_B64}\"
tsx scripts/e2e/agent-bundle-mcp-tools-docker-client.ts
tsx test/e2e/qa-lab/runtime/agent-bundle-mcp-tools-docker-client.ts
" >"$RUN_LOG" 2>&1
status=${PIPESTATUS[0]}
set -e
+1 -1
View File
@@ -28,7 +28,7 @@ docker_e2e_run_with_harness \
bash -lc "set -euo pipefail
source scripts/lib/openclaw-e2e-instance.sh
openclaw_e2e_eval_test_state_from_b64 \"\${OPENCLAW_TEST_STATE_SCRIPT_B64:?missing OPENCLAW_TEST_STATE_SCRIPT_B64}\"
tsx scripts/e2e/crestodian-first-run-docker-client.ts
tsx test/e2e/qa-lab/runtime/crestodian-first-run-docker-client.ts
" >"$RUN_LOG" 2>&1
status=${PIPESTATUS[0]}
set -e
+1 -1
View File
@@ -27,5 +27,5 @@ export OPENCLAW_SKIP_GMAIL_WATCHER=1
export OPENCLAW_SKIP_CRON=1
export OPENCLAW_SKIP_CANVAS_HOST=1
tsx scripts/e2e/openai-image-auth-docker-client.ts
tsx test/e2e/qa-lab/runtime/openai-image-auth-docker-client.ts
'
+15
View File
@@ -7,6 +7,21 @@ type Lane = {
};
const lanes: Record<string, Lane> = {
"agent-bundle-mcp-tools": {
script: "scripts/e2e/agent-bundle-mcp-tools-docker.sh",
},
"agents-delete-shared-workspace": {
script: "scripts/e2e/agents-delete-shared-workspace-docker.sh",
},
"crestodian-first-run": {
script: "scripts/e2e/crestodian-first-run-docker.sh",
},
"gateway-network": {
script: "scripts/e2e/gateway-network-docker.sh",
},
"npm-onboard-channel-agent": {
script: "scripts/e2e/npm-onboard-channel-agent-docker.sh",
},
"release-upgrade-user-journey": {
script: "scripts/e2e/release-upgrade-user-journey-docker.sh",
},
+3 -3
View File
@@ -761,7 +761,7 @@ const TOOLING_SOURCE_TEST_TARGETS = new Map([
],
],
[
"scripts/e2e/agent-bundle-mcp-tools-docker-client.ts",
"test/e2e/qa-lab/runtime/agent-bundle-mcp-tools-docker-client.ts",
[
"src/agents/agent-bundle-mcp-runtime.test.ts",
"src/agents/agent-bundle-mcp-tools.materialize.test.ts",
@@ -796,7 +796,7 @@ const TOOLING_SOURCE_TEST_TARGETS = new Map([
],
],
[
"scripts/e2e/crestodian-first-run-docker-client.ts",
"test/e2e/qa-lab/runtime/crestodian-first-run-docker-client.ts",
[
"test/scripts/docker-e2e-crestodian.test.ts",
"src/cli/run-main.test.ts",
@@ -1829,7 +1829,7 @@ const TOOLING_SOURCE_TEST_TARGETS = new Map([
],
],
[
"scripts/e2e/openai-image-auth-docker-client.ts",
"test/e2e/qa-lab/runtime/openai-image-auth-docker-client.ts",
[
"test/scripts/openai-image-auth-docker-client.test.ts",
"extensions/openai/image-generation-provider.test.ts",
+4
View File
@@ -386,6 +386,10 @@ describe("scripts/docker/setup.sh", () => {
`run --rm --no-deps ${prestartContainerEnvFlags} --entrypoint node openclaw-gateway dist/index.js onboard --mode local --no-install-daemon --gateway-auth token --gateway-token-ref-env OPENCLAW_GATEWAY_TOKEN --skip-ui --suppress-gateway-token-output`,
);
expect(result.stdout).toContain("Gateway token: stored in Docker environment/config");
expect(result.stdout).toContain("Gateway running with host port mapping.");
expect(result.stdout).toContain("Access from tailnet devices via the host's tailnet IP.");
expect(result.stdout).toContain("Commands:");
expect(result.stdout).toContain("logs -f openclaw-gateway");
expect(result.stdout).not.toContain("test-token");
expect(result.stdout).not.toContain("#token=");
expect(log).toContain(
@@ -5,16 +5,16 @@ import { randomUUID } from "node:crypto";
import fs from "node:fs/promises";
import { createRequire } from "node:module";
import path from "node:path";
import { materializeBundleMcpToolsForRun } from "../../dist/agents/agent-bundle-mcp-materialize.js";
import { materializeBundleMcpToolsForRun } from "../../../../dist/agents/agent-bundle-mcp-materialize.js";
import {
disposeAllSessionMcpRuntimes,
getOrCreateSessionMcpRuntime,
} from "../../dist/agents/agent-bundle-mcp-runtime.js";
import { applyFinalEffectiveToolPolicy } from "../../dist/agents/embedded-agent-runner/effective-tool-policy.js";
import { splitSdkTools } from "../../dist/agents/embedded-agent-runner/tool-split.js";
import type { OpenClawConfig } from "../../dist/config/types.openclaw.js";
import { getPluginToolMeta } from "../../dist/plugins/tools.js";
import { createE2eStateDir } from "./lib/temp-state-dir.ts";
} from "../../../../dist/agents/agent-bundle-mcp-runtime.js";
import { applyFinalEffectiveToolPolicy } from "../../../../dist/agents/embedded-agent-runner/effective-tool-policy.js";
import { splitSdkTools } from "../../../../dist/agents/embedded-agent-runner/tool-split.js";
import type { OpenClawConfig } from "../../../../dist/config/types.openclaw.js";
import { getPluginToolMeta } from "../../../../dist/plugins/tools.js";
import { createE2eStateDir } from "../../../../scripts/e2e/lib/temp-state-dir.ts";
const require = createRequire(import.meta.url);
@@ -7,12 +7,12 @@ import {
runCli,
shouldStartCrestodianForModernOnboard,
shouldStartOnboardingForFreshInstall,
} from "../../dist/cli/run-main.js";
import { clearConfigCache } from "../../dist/config/config.js";
import type { OpenClawConfig } from "../../dist/config/types.openclaw.js";
import { runCrestodian } from "../../dist/crestodian/crestodian.js";
import type { RuntimeEnv } from "../../dist/runtime.js";
import { createE2eStateDir } from "./lib/temp-state-dir.ts";
} from "../../../../dist/cli/run-main.js";
import { clearConfigCache } from "../../../../dist/config/config.js";
import type { OpenClawConfig } from "../../../../dist/config/types.openclaw.js";
import { runCrestodian } from "../../../../dist/crestodian/crestodian.js";
import type { RuntimeEnv } from "../../../../dist/runtime.js";
import { createE2eStateDir } from "../../../../scripts/e2e/lib/temp-state-dir.ts";
type CrestodianFirstRunCommand = {
id: string;
@@ -3,7 +3,10 @@ import http from "node:http";
import type { AddressInfo } from "node:net";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { isRequestBodyTooLargeError, readBody } from "./lib/mock-openai-http.mjs";
import {
isRequestBodyTooLargeError,
readBody,
} from "../../../../scripts/e2e/lib/mock-openai-http.mjs";
const DIRECT_IMAGE_BYTES = Buffer.from("docker-direct-image");
const CODEX_IMAGE_BYTES = Buffer.from("docker-codex-image");
@@ -174,7 +177,7 @@ export async function main() {
const mock = await startMockServer(records);
try {
const { buildOpenAIImageGenerationProvider } =
await import("../../dist/extensions/openai/image-generation-provider.js");
await import("../../../../dist/extensions/openai/image-generation-provider.js");
const provider = buildOpenAIImageGenerationProvider();
const directResult = await provider.generateImage({
+6 -6
View File
@@ -8,19 +8,19 @@ function readScript(pathname: string): string {
describe("Crestodian Docker E2E scripts", () => {
it("keeps first-run checks wired to packaged CLI and Crestodian behavior", () => {
const source = readScript("scripts/e2e/crestodian-first-run-docker-client.ts");
const source = readScript("test/e2e/qa-lab/runtime/crestodian-first-run-docker-client.ts");
const spec = readScript("scripts/e2e/crestodian-first-run-spec.json");
expect(source).toContain("../../dist/cli/run-main.js");
expect(source).toContain("../../dist/crestodian/crestodian.js");
expect(source).toContain("../../../../dist/cli/run-main.js");
expect(source).toContain("../../../../dist/crestodian/crestodian.js");
expect(source).toContain("shouldStartOnboardingForFreshInstall");
expect(source).toContain("shouldStartCrestodianForModernOnboard");
expect(source).toContain("runCli([\"node\", \"openclaw\", \"onboard\"");
expect(source).toContain('runCli(["node", "openclaw", "onboard"');
expect(source).toContain("runCrestodian(");
expect(source).toContain("Config: missing");
expect(source).toContain("Crestodian first-run Docker E2E passed");
expect(spec).toContain("\"auditOperations\"");
expect(spec).toContain("\"crestodian.setup\"");
expect(spec).toContain('"auditOperations"');
expect(spec).toContain('"crestodian.setup"');
});
it("keeps planner fallback checks wired to packaged Crestodian assistant flow", () => {
@@ -3,7 +3,7 @@ import { describe, expect, it } from "vitest";
import {
startMockServer,
type RequestRecord,
} from "../../scripts/e2e/openai-image-auth-docker-client.ts";
} from "../e2e/qa-lab/runtime/openai-image-auth-docker-client.ts";
describe("OpenAI image auth Docker client mock server", () => {
it("rejects oversized request bodies before recording them", async () => {
+5 -5
View File
@@ -605,7 +605,7 @@ describe("scripts/test-projects changed-target routing", () => {
],
],
[
"scripts/e2e/crestodian-first-run-docker-client.ts",
"test/e2e/qa-lab/runtime/crestodian-first-run-docker-client.ts",
[
"test/scripts/docker-e2e-crestodian.test.ts",
"src/cli/run-main.test.ts",
@@ -951,7 +951,7 @@ describe("scripts/test-projects changed-target routing", () => {
],
],
[
"scripts/e2e/openai-image-auth-docker-client.ts",
"test/e2e/qa-lab/runtime/openai-image-auth-docker-client.ts",
[
"test/scripts/openai-image-auth-docker-client.test.ts",
"extensions/openai/image-generation-provider.test.ts",
@@ -2442,7 +2442,7 @@ describe("scripts/test-projects changed-target routing", () => {
"scripts/e2e/mcp-code-mode-gateway-live-docker.sh",
"scripts/e2e/mcp-code-mode-gateway-seed.ts",
"scripts/e2e/agent-bundle-mcp-tools-docker.sh",
"scripts/e2e/agent-bundle-mcp-tools-docker-client.ts",
"test/e2e/qa-lab/runtime/agent-bundle-mcp-tools-docker-client.ts",
"scripts/mcp-code-mode-gateway-e2e.ts",
"scripts/e2e/cron-cli-docker.sh",
"scripts/e2e/cron-mcp-cleanup-docker.sh",
@@ -2476,7 +2476,7 @@ describe("scripts/test-projects changed-target routing", () => {
it("routes OpenAI image auth Docker E2E script targets instead of skipping changed tests", () => {
const targets = [
"scripts/e2e/openai-image-auth-docker.sh",
"scripts/e2e/openai-image-auth-docker-client.ts",
"test/e2e/qa-lab/runtime/openai-image-auth-docker-client.ts",
];
expect(findUnmatchedExplicitTestTargets(targets)).toEqual([]);
@@ -2518,7 +2518,7 @@ describe("scripts/test-projects changed-target routing", () => {
it("routes Crestodian Docker E2E script targets instead of skipping changed tests", () => {
const targets = [
"scripts/e2e/crestodian-first-run-docker.sh",
"scripts/e2e/crestodian-first-run-docker-client.ts",
"test/e2e/qa-lab/runtime/crestodian-first-run-docker-client.ts",
"scripts/e2e/crestodian-first-run-spec.json",
"scripts/e2e/crestodian-planner-docker.sh",
"scripts/e2e/crestodian-planner-docker-client.mjs",