mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 17:10:49 +00:00
test: strengthen published upgrade survivor lane (#75361)
* test: integrate upgrade survivor baseline controls * test: gate published upgrade survivor path * test: preserve upgrade survivor fixture contract * test: keep upgrade survivor temp state off overlay
This commit is contained in:
@@ -194,6 +194,7 @@ describe("scripts/lib/docker-e2e-plan", () => {
|
||||
}),
|
||||
expect.objectContaining({
|
||||
name: "upgrade-survivor",
|
||||
command: "OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:upgrade-survivor",
|
||||
stateScenario: "upgrade-survivor",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
|
||||
@@ -15,6 +15,10 @@ function shellQuote(value: string): string {
|
||||
return `'${value.replace(/'/gu, `'\\''`)}'`;
|
||||
}
|
||||
|
||||
function escapeRegex(value: string): string {
|
||||
return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
||||
}
|
||||
|
||||
describe("scripts/lib/openclaw-test-state", () => {
|
||||
it("creates a sourceable env file and JSON description", async () => {
|
||||
const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-test-state-script-"));
|
||||
@@ -88,7 +92,10 @@ describe("scripts/lib/openclaw-test-state", () => {
|
||||
"update-stable",
|
||||
]);
|
||||
expect(stdout).toContain(
|
||||
"mktemp -d '/tmp/openclaw-update-channel-switch-update-stable-home.XXXXXX'",
|
||||
'OPENCLAW_TEST_STATE_TMP_ROOT="${OPENCLAW_TEST_STATE_TMPDIR:-${TMPDIR:-/tmp}}"',
|
||||
);
|
||||
expect(stdout).toContain(
|
||||
'mktemp -d "$OPENCLAW_TEST_STATE_TMP_ROOT/openclaw-update-channel-switch-update-stable-home.XXXXXX"',
|
||||
);
|
||||
expect(stdout).toContain("OPENCLAW_TEST_STATE_JSON");
|
||||
expect(stdout).toContain('"channel": "stable"');
|
||||
@@ -100,10 +107,26 @@ describe("scripts/lib/openclaw-test-state", () => {
|
||||
]);
|
||||
|
||||
const payload = JSON.parse(probe.stdout);
|
||||
expect(payload.home).toMatch(/^\/tmp\/openclaw-update-channel-switch-update-stable-home\./u);
|
||||
expect(payload.home.startsWith(os.tmpdir())).toBe(true);
|
||||
expect(path.basename(payload.home)).toMatch(
|
||||
/^openclaw-update-channel-switch-update-stable-home\./u,
|
||||
);
|
||||
expect(payload.openclawHome).toBe(payload.home);
|
||||
expect(payload.workspace).toBe(`${payload.home}/workspace`);
|
||||
expect(payload.channel).toBe("stable");
|
||||
|
||||
const customTemp = path.join(tempRoot, "state-tmp");
|
||||
const customProbe = await execFileAsync("bash", [
|
||||
"-lc",
|
||||
`export OPENCLAW_TEST_STATE_TMPDIR=${shellQuote(customTemp)}; source ${shellQuote(snippetFile)}; node -e 'process.stdout.write(JSON.stringify({home:process.env.HOME,tmpRoot:process.env.OPENCLAW_TEST_STATE_TMP_ROOT}));'; rm -rf "$HOME"`,
|
||||
]);
|
||||
const customPayload = JSON.parse(customProbe.stdout);
|
||||
expect(customPayload.tmpRoot).toBe(customTemp);
|
||||
expect(customPayload.home).toMatch(
|
||||
new RegExp(
|
||||
`^${escapeRegex(customTemp)}/openclaw-update-channel-switch-update-stable-home\\.`,
|
||||
),
|
||||
);
|
||||
} finally {
|
||||
await fs.rm(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
@@ -167,11 +190,12 @@ describe("scripts/lib/openclaw-test-state", () => {
|
||||
|
||||
const probe = await execFileAsync("bash", [
|
||||
"-lc",
|
||||
`source ${shellQuote(snippetFile)}; export OPENCLAW_AGENT_DIR=/tmp/outside-agent; openclaw_test_state_create "onboard case" minimal; node -e 'const fs=require("node:fs"); const config=JSON.parse(fs.readFileSync(process.env.OPENCLAW_CONFIG_PATH,"utf8")); process.stdout.write(JSON.stringify({home:process.env.HOME,agentDir:process.env.OPENCLAW_AGENT_DIR || null,workspace:process.env.OPENCLAW_TEST_WORKSPACE_DIR,config}));'; rm -rf "$HOME"`,
|
||||
`export OPENCLAW_TEST_STATE_TMPDIR=${shellQuote(path.join(tempRoot, "function-tmp"))}; source ${shellQuote(snippetFile)}; export OPENCLAW_AGENT_DIR=/tmp/outside-agent; openclaw_test_state_create "onboard case" minimal; node -e 'const fs=require("node:fs"); const config=JSON.parse(fs.readFileSync(process.env.OPENCLAW_CONFIG_PATH,"utf8")); process.stdout.write(JSON.stringify({home:process.env.HOME,tmpDir:process.env.OPENCLAW_TEST_STATE_TMPDIR,agentDir:process.env.OPENCLAW_AGENT_DIR || null,workspace:process.env.OPENCLAW_TEST_WORKSPACE_DIR,config}));'; rm -rf "$HOME"`,
|
||||
]);
|
||||
|
||||
const payload = JSON.parse(probe.stdout);
|
||||
expect(payload.home).toMatch(/^\/tmp\/openclaw-onboard-case-minimal-home\./u);
|
||||
expect(payload.home).toBe(`${payload.tmpDir}/${path.basename(payload.home)}`);
|
||||
expect(payload.home).toContain("/openclaw-onboard-case-minimal-home.");
|
||||
expect(payload.agentDir).toBeNull();
|
||||
expect(payload.workspace).toBe(`${payload.home}/workspace`);
|
||||
expect(payload.config).toEqual({});
|
||||
|
||||
@@ -4,6 +4,7 @@ import { describe, expect, it } from "vitest";
|
||||
const PACKAGE_ACCEPTANCE_WORKFLOW = ".github/workflows/package-acceptance.yml";
|
||||
const LIVE_E2E_WORKFLOW = ".github/workflows/openclaw-live-and-e2e-checks-reusable.yml";
|
||||
const NPM_TELEGRAM_WORKFLOW = ".github/workflows/npm-telegram-beta-e2e.yml";
|
||||
const PACKAGE_JSON = "package.json";
|
||||
const RELEASE_CHECKS_WORKFLOW = ".github/workflows/openclaw-release-checks.yml";
|
||||
const FULL_RELEASE_VALIDATION_WORKFLOW = ".github/workflows/full-release-validation.yml";
|
||||
const QA_LIVE_TRANSPORTS_WORKFLOW = ".github/workflows/qa-live-transports-convex.yml";
|
||||
@@ -39,9 +40,11 @@ describe("package acceptance workflow", () => {
|
||||
const workflow = readFileSync(PACKAGE_ACCEPTANCE_WORKFLOW, "utf8");
|
||||
|
||||
expect(workflow).toContain("suite_profile:");
|
||||
expect(workflow).toContain("published_upgrade_survivor_baseline:");
|
||||
expect(workflow).toContain("npm-onboard-channel-agent gateway-network config-reload");
|
||||
expect(workflow).toContain("npm-onboard-channel-agent doctor-switch");
|
||||
expect(workflow).toContain("update-channel-switch upgrade-survivor");
|
||||
expect(workflow).toContain("published-upgrade-survivor");
|
||||
expect(workflow).toContain("bundled-channel-deps-compat");
|
||||
expect(workflow).toContain("plugins-offline plugin-update");
|
||||
expect(workflow).toContain("include_release_path_suites=true");
|
||||
@@ -61,18 +64,28 @@ describe("package acceptance workflow", () => {
|
||||
expect(workflow).toContain(
|
||||
"harness_ref: ${{ needs.resolve_package.outputs.package_source_sha || inputs.workflow_ref }}",
|
||||
);
|
||||
expect(workflow).toContain(
|
||||
"published_upgrade_survivor_baseline: ${{ inputs.published_upgrade_survivor_baseline }}",
|
||||
);
|
||||
expect(workflow).toContain("Published upgrade survivor baseline:");
|
||||
});
|
||||
});
|
||||
|
||||
describe("package artifact reuse", () => {
|
||||
it("lets reusable Docker E2E consume an already resolved package artifact", () => {
|
||||
const workflow = readFileSync(LIVE_E2E_WORKFLOW, "utf8");
|
||||
const packageJson = readFileSync(PACKAGE_JSON, "utf8");
|
||||
const scheduler = readFileSync("scripts/test-docker-all.mjs", "utf8");
|
||||
|
||||
expect(workflow).toContain("package_artifact_name:");
|
||||
expect(workflow).toContain("package_artifact_run_id:");
|
||||
expect(workflow).toContain("published_upgrade_survivor_baseline:");
|
||||
expect(workflow).toContain("docker_e2e_bare_image:");
|
||||
expect(workflow).toContain("docker_e2e_functional_image:");
|
||||
expect(workflow).toContain("OPENCLAW_DOCKER_E2E_SELECTED_SHA:");
|
||||
expect(workflow).toContain(
|
||||
"OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC: ${{ inputs.published_upgrade_survivor_baseline }}",
|
||||
);
|
||||
expect(workflow).toContain("Download current-run OpenClaw Docker E2E package");
|
||||
expect(workflow).toContain("Download previous-run OpenClaw Docker E2E package");
|
||||
expect(workflow).toContain("inputs.package_artifact_name != ''");
|
||||
@@ -95,6 +108,13 @@ describe("package artifact reuse", () => {
|
||||
expect(workflow).toContain("LANES: ${{ matrix.group.docker_lanes }}");
|
||||
expect(workflow).toContain("DOCKER_E2E_LANES: ${{ matrix.group.docker_lanes }}");
|
||||
expect(workflow).toContain("name: docker-e2e-${{ steps.plan.outputs.artifact_suffix }}");
|
||||
expect(scheduler).toContain(
|
||||
"published_upgrade_survivor_baseline=${shellQuote(process.env.OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC)}",
|
||||
);
|
||||
expect(scheduler).toContain(
|
||||
'["OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC", baseEnv.OPENCLAW_UPGRADE_SURVIVOR_BASELINE_SPEC]',
|
||||
);
|
||||
expect(packageJson).toContain("OPENCLAW_UPGRADE_SURVIVOR_PUBLISHED_BASELINE=1");
|
||||
});
|
||||
|
||||
it("bounds shared Docker image pulls so package acceptance cannot stall forever", () => {
|
||||
|
||||
Reference in New Issue
Block a user