From f25f7429df9fe4a89658a7717aa3fa54cc6c81dd Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Tue, 18 Aug 2026 23:52:17 +0800 Subject: [PATCH] test(release): redact shared failure diagnostics (#125697) * test(release): use shared channel diagnostics * fix(release): redact shared E2E failure logs * test(release): configure redaction timeout fixture --- .../e2e/npm-onboard-channel-agent-docker.sh | 3 +- scripts/lib/openclaw-e2e-instance.sh | 18 ++++++- test/scripts/docker-build-helper.test.ts | 8 ++++ test/scripts/openclaw-e2e-instance.test.ts | 47 ++++++++++++++++++- 4 files changed, 71 insertions(+), 5 deletions(-) diff --git a/scripts/e2e/npm-onboard-channel-agent-docker.sh b/scripts/e2e/npm-onboard-channel-agent-docker.sh index 5ab1600cc3d0..53c18a79dce1 100644 --- a/scripts/e2e/npm-onboard-channel-agent-docker.sh +++ b/scripts/e2e/npm-onboard-channel-agent-docker.sh @@ -165,7 +165,6 @@ dump_debug_logs() { openclaw_e2e_dump_logs \ /tmp/openclaw-install.log \ /tmp/openclaw-onboard.json \ - /tmp/openclaw-channel-add.log \ /tmp/openclaw-channels-status.json \ /tmp/openclaw-channels-status.err \ /tmp/openclaw-status.txt \ @@ -214,7 +213,7 @@ node scripts/e2e/lib/npm-onboard-channel-agent/assertions.mjs assert-onboard-sta openclaw_e2e_assert_dep_absent "$DEP_SENTINEL" "$HOME/.openclaw" echo "Configuring $CHANNEL..." -openclaw channels add --channel "$CHANNEL" "${CHANNEL_ADD_ARGS[@]}" >/tmp/openclaw-channel-add.log 2>&1 +openclaw_e2e_run_logged channel-add "$OPENCLAW_E2E_CLI_BIN" channels add --channel "$CHANNEL" "${CHANNEL_ADD_ARGS[@]}" node scripts/e2e/lib/npm-onboard-channel-agent/assertions.mjs assert-channel-config "$CHANNEL" "${CHANNEL_CONFIG_TOKENS[@]}" echo "Checking status surfaces for $CHANNEL..." diff --git a/scripts/lib/openclaw-e2e-instance.sh b/scripts/lib/openclaw-e2e-instance.sh index e6bde807e7be..b31c31d4506d 100644 --- a/scripts/lib/openclaw-e2e-instance.sh +++ b/scripts/lib/openclaw-e2e-instance.sh @@ -216,12 +216,26 @@ NODE } openclaw_e2e_print_log() { local path="$1" - local max_bytes max_lines + local max_bytes max_lines redactor_module max_bytes="$(openclaw_e2e_read_nonnegative_int_env OPENCLAW_E2E_LOG_TAIL_BYTES 262144)" || return $? max_lines="$(openclaw_e2e_read_nonnegative_int_env OPENCLAW_E2E_LOG_TAIL_LINES 120)" || return $? [ -f "$path" ] || return 0 echo "--- $path ---" - tail -c "$max_bytes" "$path" 2>/dev/null | tail -n "$max_lines" || tail -n "$max_lines" "$path" || true + redactor_module="${OPENCLAW_E2E_REDACTOR_MODULE:-$(openclaw_e2e_package_root)/dist/plugin-sdk/logging-core.js}" + [ -f "$redactor_module" ] || redactor_module="$PWD/dist/plugin-sdk/logging-core.js" + if [ ! -f "$redactor_module" ]; then + echo "[failure log omitted: canonical redactor unavailable]" + return 0 + fi + if ! { tail -c "$max_bytes" "$path" 2>/dev/null | tail -n "$max_lines" || tail -n "$max_lines" "$path" || true; } | \ + node --input-type=module -e ' + import fs from "node:fs"; + import { pathToFileURL } from "node:url"; + const { redactSensitiveText } = await import(pathToFileURL(process.argv[1]).href); + process.stdout.write(redactSensitiveText(fs.readFileSync(0, "utf8"), { mode: "tools" })); + ' "$redactor_module"; then + echo "[failure log omitted: canonical redaction failed]" + fi } openclaw_e2e_install_package() { local log_file="$1" diff --git a/test/scripts/docker-build-helper.test.ts b/test/scripts/docker-build-helper.test.ts index 18d58a47e8bf..7d29d1dd2430 100644 --- a/test/scripts/docker-build-helper.test.ts +++ b/test/scripts/docker-build-helper.test.ts @@ -2708,6 +2708,14 @@ docker_e2e_docker_run_cmd run demo expect(script).not.toContain('"$HOME/.openclaw/agents/main/agent/auth-profiles.json"'); }); + it("prints channel-add failures through the shared E2E logger", () => { + const script = readFileSync(NPM_ONBOARD_CHANNEL_AGENT_DOCKER_E2E_PATH, "utf8"); + expect(script).toContain( + 'openclaw_e2e_run_logged channel-add "$OPENCLAW_E2E_CLI_BIN" channels add --channel "$CHANNEL" "${CHANNEL_ADD_ARGS[@]}"', + ); + expect(script).not.toContain("/tmp/openclaw-channel-add.log"); + }); + it("keeps real-TTY onboarding drivers aligned with the first-agent prompt", () => { expectOrderedScriptFragments(readFileSync(RELEASE_TYPED_ONBOARDING_SCENARIO_PATH, "utf8"), [ 'wait_for_log "Continue?"', diff --git a/test/scripts/openclaw-e2e-instance.test.ts b/test/scripts/openclaw-e2e-instance.test.ts index d21e9070cfde..8a37867b5caf 100644 --- a/test/scripts/openclaw-e2e-instance.test.ts +++ b/test/scripts/openclaw-e2e-instance.test.ts @@ -118,9 +118,15 @@ function createPackageInstallFixture(tempDir: string) { npmArgsPath: path.join(tempDir, "npm-args.txt"), packagePath: path.join(tempDir, "openclaw.tgz"), prefixPath: path.join(tempDir, "prefix"), + redactorPath: path.join(tempDir, "redactor.mjs"), timeoutArgsPath: path.join(tempDir, "timeout-args.txt"), }; writePackageFixture(fixture.packagePath); + fs.writeFileSync( + fixture.redactorPath, + "export const redactSensitiveText = (value) => value;\n", + "utf8", + ); return fixture; } @@ -132,7 +138,7 @@ function runPackageInstall( [ `openclaw_e2e_install_package ${shellQuote(fixture.logPath)} ${shellQuote("fixture package")} ${shellQuote(fixture.prefixPath)}`, ], - env, + { ...env, OPENCLAW_E2E_REDACTOR_MODULE: fixture.redactorPath }, undefined, "; ", ); @@ -878,6 +884,12 @@ exit 1 const logLabel = path.basename(tempDir); const logDir = path.join(tempDir, "logs"); const timeoutArgsPath = path.join(tempDir, "timeout-args.txt"); + const redactorPath = path.join(tempDir, "redactor.mjs"); + fs.writeFileSync( + redactorPath, + "export const redactSensitiveText = (value) => value;\n", + "utf8", + ); writeFakeTimeout(path.join(tempDir, "timeout"), true); writeBashExecutable(path.join(tempDir, "fixture-command"), [ 'printf "DO_NOT_PRINT_OLD_COMMAND_LOG\\n"', @@ -893,6 +905,7 @@ exit 1 OPENCLAW_E2E_COMMAND_TIMEOUT: "17s", OPENCLAW_E2E_LOG_DIR: logDir, OPENCLAW_E2E_LOG_TAIL_BYTES: "80", + OPENCLAW_E2E_REDACTOR_MODULE: redactorPath, OPENCLAW_TEST_TIMEOUT_ARGS: timeoutArgsPath, }, undefined, @@ -909,6 +922,38 @@ exit 1 }); }); + it("redacts logged command failures before replay", () => { + withTempDir("openclaw-e2e-instance-run-log-redact-", (tempDir) => { + const redactorPath = path.join(tempDir, "redactor.mjs"); + fs.writeFileSync( + redactorPath, + 'export const redactSensitiveText = (value) => value.replaceAll("fixture-secret", "***");\n', + "utf8", + ); + writeFakeTimeout(path.join(tempDir, "timeout"), true); + writeBashExecutable(path.join(tempDir, "fixture-command"), [ + 'printf "actionable failure fixture-secret\\n"', + "exit 23", + ]); + + const result = runBashWithHelper( + ["openclaw_e2e_run_logged redacted-failure fixture-command"], + { + PATH: `${tempDir}${path.delimiter}${hostPath}`, + OPENCLAW_E2E_LOG_DIR: path.join(tempDir, "logs"), + OPENCLAW_E2E_REDACTOR_MODULE: redactorPath, + OPENCLAW_TEST_TIMEOUT_ARGS: path.join(tempDir, "timeout-args.txt"), + }, + undefined, + "; ", + ); + + expect(result.status).toBe(1); + expect(result.stdout).toContain("actionable failure ***"); + expect(result.stdout).not.toContain("fixture-secret"); + }); + }); + it("installs the trash shim under isolated test state", () => { withTempDir("openclaw-e2e-trash-shim-", (tempDir) => { const homeDir = path.join(tempDir, "home");