From 84bcdaa9837327da878fbdebb82d61cd5947cb8d Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 19 Jun 2026 00:29:16 +0200 Subject: [PATCH] fix(e2e): validate fixture cleanup interval --- scripts/e2e/lib/plugins/fixtures.sh | 18 +++++++++++-- test/scripts/plugins-assertions.test.ts | 34 +++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/scripts/e2e/lib/plugins/fixtures.sh b/scripts/e2e/lib/plugins/fixtures.sh index dd78d9fd24c..82023cb31d6 100644 --- a/scripts/e2e/lib/plugins/fixtures.sh +++ b/scripts/e2e/lib/plugins/fixtures.sh @@ -16,6 +16,20 @@ openclaw_plugins_read_positive_int_env() { printf "%s\n" "$((10#$value))" } +openclaw_plugins_read_nonnegative_decimal_env() { + local name="${1:?missing environment variable name}" + local fallback="${2:?missing fallback value}" + local value="${!name-}" + if [[ -z "${!name+x}" ]]; then + value="$fallback" + fi + if [[ ! "$value" =~ ^[0-9]+([.][0-9]+)?$ ]]; then + echo "invalid $name: $value" >&2 + return 2 + fi + printf "%s\n" "$value" +} + openclaw_plugins_cleanup_fixture_servers() { local pid_file local pid @@ -47,9 +61,9 @@ openclaw_plugins_fixture_process_alive() { openclaw_plugins_stop_fixture_process() { local pid="$1" local _ - local attempts + local attempts interval attempts="$(openclaw_plugins_read_positive_int_env OPENCLAW_PLUGINS_FIXTURE_STOP_ATTEMPTS 40)" || return $? - local interval="${OPENCLAW_PLUGINS_FIXTURE_STOP_INTERVAL_SECONDS:-0.25}" + interval="$(openclaw_plugins_read_nonnegative_decimal_env OPENCLAW_PLUGINS_FIXTURE_STOP_INTERVAL_SECONDS 0.25)" || return $? if declare -F openclaw_e2e_stop_process >/dev/null 2>&1; then openclaw_e2e_stop_process "$pid" return diff --git a/test/scripts/plugins-assertions.test.ts b/test/scripts/plugins-assertions.test.ts index 594a731e70b..cfe5fc21b85 100644 --- a/test/scripts/plugins-assertions.test.ts +++ b/test/scripts/plugins-assertions.test.ts @@ -423,6 +423,40 @@ test -d "$OPENCLAW_PLUGINS_TMP_DIR" expect(result.stdout).not.toContain("probe"); }); + it("rejects invalid fixture stop intervals before cleanup polling", () => { + const result = spawnSync( + "/bin/bash", + [ + "-c", + [ + "set -euo pipefail", + "source scripts/e2e/lib/plugins/fixtures.sh", + "openclaw_plugins_signal_fixture_process() { echo signal; }", + "openclaw_plugins_fixture_process_alive() { echo probe; return 1; }", + "set +e", + "openclaw_plugins_stop_fixture_process 12345", + 'status="$?"', + "set -e", + 'exit "$status"', + ].join("\n"), + ], + { + cwd: process.cwd(), + encoding: "utf8", + env: { + ...process.env, + OPENCLAW_PLUGINS_FIXTURE_STOP_ATTEMPTS: "2", + OPENCLAW_PLUGINS_FIXTURE_STOP_INTERVAL_SECONDS: "soon", + }, + }, + ); + + expect(result.status).toBe(2); + expect(result.stderr).toContain("invalid OPENCLAW_PLUGINS_FIXTURE_STOP_INTERVAL_SECONDS: soon"); + expect(result.stdout).not.toContain("signal"); + expect(result.stdout).not.toContain("probe"); + }); + it("bounds npm fixture registry logs when readiness fails", () => { const root = mkdtempSync(path.join(tmpdir(), "openclaw-plugin-npm-fixture-log-")); try {