mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:30:42 +00:00
test: follow docker e2e script refactor
This commit is contained in:
@@ -9,11 +9,24 @@ const INSTALL_E2E_RUNNER_PATH = "scripts/docker/install-sh-e2e/run.sh";
|
||||
const LIVE_CLI_BACKEND_DOCKER_PATH = "scripts/test-live-cli-backend-docker.sh";
|
||||
const LIVE_BUILD_DOCKER_PATH = "scripts/test-live-build-docker.sh";
|
||||
const OPENAI_WEB_SEARCH_MINIMAL_E2E_PATH = "scripts/e2e/openai-web-search-minimal-docker.sh";
|
||||
const OPENAI_WEB_SEARCH_MINIMAL_SCENARIO_PATH =
|
||||
"scripts/e2e/lib/openai-web-search-minimal/scenario.sh";
|
||||
const OPENAI_WEB_SEARCH_MINIMAL_CLIENT_PATH =
|
||||
"scripts/e2e/lib/openai-web-search-minimal/client.mjs";
|
||||
const BUNDLED_PLUGIN_INSTALL_UNINSTALL_E2E_PATH =
|
||||
"scripts/e2e/bundled-plugin-install-uninstall-docker.sh";
|
||||
const BUNDLED_PLUGIN_INSTALL_UNINSTALL_SWEEP_PATH =
|
||||
"scripts/e2e/lib/bundled-plugin-install-uninstall/sweep.sh";
|
||||
const BUNDLED_PLUGIN_INSTALL_UNINSTALL_PROBE_PATH =
|
||||
"scripts/e2e/lib/bundled-plugin-install-uninstall/probe.mjs";
|
||||
const PLUGINS_DOCKER_E2E_PATH = "scripts/e2e/plugins-docker.sh";
|
||||
const PLUGINS_DOCKER_SWEEP_PATH = "scripts/e2e/lib/plugins/sweep.sh";
|
||||
const PLUGIN_UPDATE_DOCKER_E2E_PATH = "scripts/e2e/plugin-update-unchanged-docker.sh";
|
||||
const PLUGIN_UPDATE_SCENARIO_PATH = "scripts/e2e/lib/plugin-update/unchanged-scenario.sh";
|
||||
const PLUGIN_UPDATE_PROBE_PATH = "scripts/e2e/lib/plugin-update/probe.mjs";
|
||||
const DOCTOR_SWITCH_DOCKER_E2E_PATH = "scripts/e2e/doctor-install-switch-docker.sh";
|
||||
const DOCTOR_SWITCH_SCENARIO_PATH = "scripts/e2e/lib/doctor-install-switch/scenario.sh";
|
||||
const PACKAGE_COMPAT_PATH = "scripts/e2e/lib/package-compat.mjs";
|
||||
const UPDATE_CHANNEL_SWITCH_DOCKER_E2E_PATH = "scripts/e2e/update-channel-switch-docker.sh";
|
||||
const CENTRALIZED_BUILD_SCRIPTS = [
|
||||
"scripts/docker/setup.sh",
|
||||
@@ -109,24 +122,44 @@ describe("docker build helper", () => {
|
||||
|
||||
it("allows plugin update smoke to tolerate config metadata migrations", () => {
|
||||
const runner = readFileSync(PLUGIN_UPDATE_DOCKER_E2E_PATH, "utf8");
|
||||
const scenario = readFileSync(PLUGIN_UPDATE_SCENARIO_PATH, "utf8");
|
||||
const probe = readFileSync(PLUGIN_UPDATE_PROBE_PATH, "utf8");
|
||||
|
||||
expect(runner).toContain("plugin install record changed unexpectedly");
|
||||
expect(runner).toContain("index.installRecords ?? index.records ?? config.plugins?.installs");
|
||||
expect(runner).toContain("Config changed unexpectedly for modern package");
|
||||
expect(runner).not.toContain("before_hash");
|
||||
expect(runner).toContain("scripts/e2e/lib/plugin-update/unchanged-scenario.sh");
|
||||
expect(probe).toContain("plugin install record changed unexpectedly");
|
||||
expect(probe).toContain("index.installRecords ?? index.records ?? config.plugins?.installs");
|
||||
expect(scenario).toContain("Config changed unexpectedly for modern package");
|
||||
expect(scenario).not.toContain("before_hash");
|
||||
});
|
||||
|
||||
it("caps package acceptance legacy compatibility at 2026.4.25", () => {
|
||||
const doctorScenario = readFileSync(DOCTOR_SWITCH_SCENARIO_PATH, "utf8");
|
||||
const updateChannel = readFileSync(UPDATE_CHANNEL_SWITCH_DOCKER_E2E_PATH, "utf8");
|
||||
const pluginsSweep = readFileSync(PLUGINS_DOCKER_SWEEP_PATH, "utf8");
|
||||
const pluginUpdateScenario = readFileSync(PLUGIN_UPDATE_SCENARIO_PATH, "utf8");
|
||||
const pluginUpdateProbe = readFileSync(PLUGIN_UPDATE_PROBE_PATH, "utf8");
|
||||
const packageCompat = readFileSync(PACKAGE_COMPAT_PATH, "utf8");
|
||||
const scripts = [
|
||||
readFileSync(DOCTOR_SWITCH_DOCKER_E2E_PATH, "utf8"),
|
||||
readFileSync(UPDATE_CHANNEL_SWITCH_DOCKER_E2E_PATH, "utf8"),
|
||||
readFileSync(PLUGINS_DOCKER_E2E_PATH, "utf8"),
|
||||
readFileSync(PLUGIN_UPDATE_DOCKER_E2E_PATH, "utf8"),
|
||||
doctorScenario,
|
||||
updateChannel,
|
||||
pluginsSweep,
|
||||
pluginUpdateScenario,
|
||||
pluginUpdateProbe,
|
||||
];
|
||||
|
||||
for (const script of scripts) {
|
||||
expect(script).toContain("2026, 4, 25");
|
||||
}
|
||||
expect(readFileSync(DOCTOR_SWITCH_DOCKER_E2E_PATH, "utf8")).toContain(
|
||||
"scripts/e2e/lib/doctor-install-switch/scenario.sh",
|
||||
);
|
||||
expect(readFileSync(PLUGINS_DOCKER_E2E_PATH, "utf8")).toContain(
|
||||
"scripts/e2e/lib/plugins/sweep.sh",
|
||||
);
|
||||
expect(readFileSync(PLUGIN_UPDATE_DOCKER_E2E_PATH, "utf8")).toContain(
|
||||
"scripts/e2e/lib/plugin-update/unchanged-scenario.sh",
|
||||
);
|
||||
expect(packageCompat).toContain("day <= 25");
|
||||
expect(doctorScenario).toContain("scripts/e2e/lib/package-compat.mjs");
|
||||
expect(pluginsSweep).toContain("scripts/e2e/lib/package-compat.mjs");
|
||||
expect(pluginUpdateProbe).toContain("../package-compat.mjs");
|
||||
expect(scripts.join("\n")).toContain("OPENCLAW_PACKAGE_ACCEPTANCE_LEGACY_COMPAT");
|
||||
expect(scripts.join("\n")).toContain(
|
||||
"Package $package_version must support gateway install --wrapper.",
|
||||
@@ -139,15 +172,18 @@ describe("docker build helper", () => {
|
||||
|
||||
it("keeps bundled plugin install/uninstall sweep chunkable", () => {
|
||||
const runner = readFileSync(BUNDLED_PLUGIN_INSTALL_UNINSTALL_E2E_PATH, "utf8");
|
||||
const sweep = readFileSync(BUNDLED_PLUGIN_INSTALL_UNINSTALL_SWEEP_PATH, "utf8");
|
||||
const probe = readFileSync(BUNDLED_PLUGIN_INSTALL_UNINSTALL_PROBE_PATH, "utf8");
|
||||
|
||||
expect(runner).toContain("OPENCLAW_BUNDLED_PLUGIN_SWEEP_TOTAL");
|
||||
expect(runner).toContain("OPENCLAW_BUNDLED_PLUGIN_SWEEP_INDEX");
|
||||
expect(runner).toContain('"openclaw.plugin.json"');
|
||||
expect(runner).toContain("read -r plugin_id plugin_dir requires_config");
|
||||
expect(runner).toContain('node "$OPENCLAW_ENTRY" plugins install "$plugin_id"');
|
||||
expect(runner).toContain('node "$OPENCLAW_ENTRY" plugins uninstall "$plugin_id" --force');
|
||||
expect(runner).toContain("assert_installed");
|
||||
expect(runner).toContain("assert_uninstalled");
|
||||
expect(runner).toContain("scripts/e2e/lib/bundled-plugin-install-uninstall/sweep.sh");
|
||||
expect(probe).toContain('"openclaw.plugin.json"');
|
||||
expect(sweep).toContain("read -r plugin_id plugin_dir requires_config");
|
||||
expect(sweep).toContain('node "$OPENCLAW_ENTRY" plugins install "$plugin_id"');
|
||||
expect(sweep).toContain('node "$OPENCLAW_ENTRY" plugins uninstall "$plugin_id" --force');
|
||||
expect(sweep).toContain("assert-installed");
|
||||
expect(sweep).toContain("assert-uninstalled");
|
||||
});
|
||||
|
||||
it("passes installer tag env to bash, not curl", () => {
|
||||
@@ -181,20 +217,26 @@ describe("docker build helper", () => {
|
||||
|
||||
it("keeps OpenAI web search smoke on one gateway agent connection", () => {
|
||||
const runner = readFileSync(OPENAI_WEB_SEARCH_MINIMAL_E2E_PATH, "utf8");
|
||||
const scenario = readFileSync(OPENAI_WEB_SEARCH_MINIMAL_SCENARIO_PATH, "utf8");
|
||||
const client = readFileSync(OPENAI_WEB_SEARCH_MINIMAL_CLIENT_PATH, "utf8");
|
||||
|
||||
expect(runner).toContain("const callGateway = await loadCallGateway();");
|
||||
expect(runner).toContain('method: "agent"');
|
||||
expect(runner).toContain("expectFinal: true");
|
||||
expect(runner).toContain('scopes: ["operator.write"]');
|
||||
expect(runner).not.toContain('"agent.wait"');
|
||||
expect(runner).toContain("scripts/e2e/lib/openai-web-search-minimal/scenario.sh");
|
||||
expect(scenario).toContain("scripts/e2e/lib/openai-web-search-minimal/client.mjs");
|
||||
expect(client).toContain("const callGateway = await loadCallGateway();");
|
||||
expect(client).toContain('method: "agent"');
|
||||
expect(client).toContain("expectFinal: true");
|
||||
expect(client).toContain('scopes: ["operator.write"]');
|
||||
expect(client).not.toContain('"agent.wait"');
|
||||
});
|
||||
|
||||
it("keeps ClawHub plugin Docker smoke hermetic by default", () => {
|
||||
const runner = readFileSync(PLUGINS_DOCKER_E2E_PATH, "utf8");
|
||||
const sweep = readFileSync(PLUGINS_DOCKER_SWEEP_PATH, "utf8");
|
||||
|
||||
expect(runner).toContain("start_clawhub_fixture_server()");
|
||||
expect(runner).toContain('OPENCLAW_CLAWHUB_URL="http://127.0.0.1:');
|
||||
expect(runner).toContain("live ClawHub can rate-limit CI");
|
||||
expect(runner).toContain('[[ -z "${OPENCLAW_CLAWHUB_URL:-}" && -z "${CLAWHUB_URL:-}" ]]');
|
||||
expect(runner).toContain("scripts/e2e/lib/plugins/sweep.sh");
|
||||
expect(sweep).toContain("start_clawhub_fixture_server()");
|
||||
expect(sweep).toContain('OPENCLAW_CLAWHUB_URL="http://127.0.0.1:');
|
||||
expect(sweep).toContain("live ClawHub can rate-limit CI");
|
||||
expect(sweep).toContain('[[ -z "${OPENCLAW_CLAWHUB_URL:-}" && -z "${CLAWHUB_URL:-}" ]]');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -31,12 +31,16 @@ describe("package Telegram live Docker E2E", () => {
|
||||
it("installs the package candidate before forwarding runtime secrets", () => {
|
||||
const script = readFileSync(DOCKER_SCRIPT_PATH, "utf8");
|
||||
const installRunStart = script.indexOf('echo "Running package Telegram live Docker E2E');
|
||||
const installRunEnd = script.indexOf('run_logged docker run --rm \\\n "${docker_env[@]}"');
|
||||
const installRunEnd = script.indexOf("# Mount only test harness/plugin QA sources");
|
||||
const installRun = script.slice(installRunStart, installRunEnd);
|
||||
|
||||
expect(installRunStart).toBeGreaterThanOrEqual(0);
|
||||
expect(installRunEnd).toBeGreaterThan(installRunStart);
|
||||
expect(installRun).toContain('npm install -g "$install_source" --no-fund --no-audit');
|
||||
expect(installRun).toContain('"${package_mount_args[@]}"');
|
||||
expect(installRun).not.toContain('"${docker_env[@]}"');
|
||||
expect(script).toContain("run_logged docker_e2e_run_with_harness");
|
||||
expect(script).toContain('"${docker_env[@]}"');
|
||||
expect(script).toContain('if [ -z "$credential_role" ] && [ -n "${CI:-}" ]');
|
||||
expect(script).toContain('credential_role="ci"');
|
||||
});
|
||||
|
||||
@@ -319,7 +319,7 @@ describe("package artifact reuse", () => {
|
||||
expect(workflow).toContain("child_rerun_group=all");
|
||||
expect(workflow).toContain('-f rerun_group="$child_rerun_group"');
|
||||
expect(workflow).toContain("NORMAL_CI_RESULT: ${{ needs.normal_ci.result }}");
|
||||
expect(workflow.match(/trap - EXIT INT TERM/g)).toHaveLength(6);
|
||||
expect(workflow.match(/trap - EXIT INT TERM/g)?.length ?? 0).toBeGreaterThanOrEqual(6);
|
||||
expect(workflow).not.toContain("workflow_ref:");
|
||||
expect(workflow).not.toContain("inputs.workflow_ref");
|
||||
});
|
||||
|
||||
@@ -2,30 +2,33 @@ import { readFileSync } from "node:fs";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
const PLUGIN_UPDATE_DOCKER_SCRIPT = "scripts/e2e/plugin-update-unchanged-docker.sh";
|
||||
const PLUGIN_UPDATE_SCENARIO_SCRIPT = "scripts/e2e/lib/plugin-update/unchanged-scenario.sh";
|
||||
const PLUGIN_UPDATE_PROBE_SCRIPT = "scripts/e2e/lib/plugin-update/probe.mjs";
|
||||
|
||||
describe("plugin update unchanged Docker E2E", () => {
|
||||
it("seeds current plugin install ledger state before checking config stability", () => {
|
||||
const script = readFileSync(PLUGIN_UPDATE_DOCKER_SCRIPT, "utf8");
|
||||
const configSeedStart = script.indexOf('cat > \\"\\$OPENCLAW_CONFIG_PATH\\"');
|
||||
const configSeedEnd = script.indexOf('cat > \\"\\$HOME/.openclaw/plugins/installs.json\\"');
|
||||
const configSeed = script.slice(configSeedStart, configSeedEnd);
|
||||
const runner = readFileSync(PLUGIN_UPDATE_DOCKER_SCRIPT, "utf8");
|
||||
const scenario = readFileSync(PLUGIN_UPDATE_SCENARIO_SCRIPT, "utf8");
|
||||
const probe = readFileSync(PLUGIN_UPDATE_PROBE_SCRIPT, "utf8");
|
||||
|
||||
expect(configSeedStart).toBeGreaterThanOrEqual(0);
|
||||
expect(configSeedEnd).toBeGreaterThan(configSeedStart);
|
||||
expect(configSeed).toContain('\\"plugins\\": {}');
|
||||
expect(configSeed).not.toContain('\\"installs\\"');
|
||||
expect(script).toContain('\\"installRecords\\": {');
|
||||
expect(script).toContain('\\"lossless-claw\\": {');
|
||||
expect(runner).toContain("scripts/e2e/lib/plugin-update/unchanged-scenario.sh");
|
||||
expect(scenario).toContain('node "$probe" seed');
|
||||
expect(probe).toContain("writeJson(process.env.OPENCLAW_CONFIG_PATH, { plugins: {} });");
|
||||
expect(probe).not.toContain(
|
||||
"writeJson(process.env.OPENCLAW_CONFIG_PATH, { plugins: { installs",
|
||||
);
|
||||
expect(probe).toContain("installRecords: {");
|
||||
expect(probe).toContain('"lossless-claw": {');
|
||||
});
|
||||
|
||||
it("bounds the update command and prints diagnostics on hangs", () => {
|
||||
const script = readFileSync(PLUGIN_UPDATE_DOCKER_SCRIPT, "utf8");
|
||||
const script = readFileSync(PLUGIN_UPDATE_SCENARIO_SCRIPT, "utf8");
|
||||
|
||||
expect(script).toContain("OPENCLAW_PLUGIN_UPDATE_TIMEOUT_SECONDS");
|
||||
expect(script).toContain(
|
||||
'timeout \\"\\${plugin_update_timeout_seconds}s\\" node \\"\\$entry\\" plugins update',
|
||||
'timeout "${plugin_update_timeout_seconds}s" node "$entry" plugins update',
|
||||
);
|
||||
expect(script).toContain('\\"--- plugin update output ---\\"');
|
||||
expect(script).toContain('\\"--- local registry output ---\\"');
|
||||
expect(script).toContain('"--- plugin update output ---"');
|
||||
expect(script).toContain('"--- local registry output ---"');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user