diff --git a/src/commands/doctor.warns-state-directory-is-missing.e2e.test.ts b/src/commands/doctor.warns-state-directory-is-missing.e2e.test.ts index a48cc53149d..82c2c463e45 100644 --- a/src/commands/doctor.warns-state-directory-is-missing.e2e.test.ts +++ b/src/commands/doctor.warns-state-directory-is-missing.e2e.test.ts @@ -94,6 +94,9 @@ describe("doctor command", () => { const missingDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-missing-state-")); fs.rmSync(missingDir, { recursive: true, force: true }); process.env.OPENCLAW_STATE_DIR = missingDir; + doctorCommand = await loadDoctorCommandForTest({ + unmockModules: ["../flows/doctor-health-contributions.js", "./doctor-state-integrity.js"], + }); await doctorCommand(createDoctorRuntime(), { nonInteractive: true, workspaceSuggestions: false, diff --git a/src/infra/net/proxy/external-proxy.e2e.test.ts b/src/infra/net/proxy/external-proxy.e2e.test.ts index a91cabbd4ae..f9445d5bc14 100644 --- a/src/infra/net/proxy/external-proxy.e2e.test.ts +++ b/src/infra/net/proxy/external-proxy.e2e.test.ts @@ -4,6 +4,8 @@ import * as net from "node:net"; import { afterEach, describe, expect, it } from "vitest"; import { WebSocketServer } from "ws"; +const CHILD_PROBE_TIMEOUT_MS = 20_000; + async function listenOnLoopback(server: Server): Promise { return new Promise((resolve, reject) => { server.once("error", reject); @@ -202,6 +204,8 @@ describe("SSRF external proxy routing", () => { import { startProxy, stopProxy } from "./src/infra/net/proxy/proxy-lifecycle.ts"; import { dangerouslyBypassManagedProxyForGatewayLoopbackControlPlane } from "./src/infra/net/proxy/proxy-lifecycle.ts"; + const probeTimeoutMs = Number(process.env.OPENCLAW_TEST_PROXY_TIMEOUT_MS || "20000"); + async function nodeHttpGet(url, options = {}) { return new Promise((resolve, reject) => { const req = http.get(url, options, (response) => { @@ -214,7 +218,7 @@ describe("SSRF external proxy routing", () => { resolve({ status: response.statusCode, body }); }); }); - req.setTimeout(5000, () => { + req.setTimeout(probeTimeoutMs, () => { req.destroy(new Error("node:http request timed out")); }); req.on("error", reject); @@ -236,7 +240,7 @@ describe("SSRF external proxy routing", () => { response.resume(); response.on("end", resolve); }); - req.setTimeout(5000, () => { + req.setTimeout(probeTimeoutMs, () => { req.destroy(new Error("node:https request timed out")); }); req.on("error", reject); @@ -245,7 +249,7 @@ describe("SSRF external proxy routing", () => { async function websocketProbe(url) { return new Promise((resolve, reject) => { - const ws = new WebSocket(url, { handshakeTimeout: 5000 }); + const ws = new WebSocket(url, { handshakeTimeout: probeTimeoutMs }); ws.once("open", () => { ws.close(); reject(new Error("proxied websocket unexpectedly opened")); @@ -257,7 +261,7 @@ describe("SSRF external proxy routing", () => { async function gatewayLoopbackBypassProbe(url) { return new Promise((resolve, reject) => { const ws = dangerouslyBypassManagedProxyForGatewayLoopbackControlPlane(url, () => - new WebSocket(url, { handshakeTimeout: 5000 }), + new WebSocket(url, { handshakeTimeout: probeTimeoutMs }), ); ws.once("open", () => { ws.close(); @@ -273,7 +277,7 @@ describe("SSRF external proxy routing", () => { } try { const response = await undiciFetch(process.env.OPENCLAW_TEST_TARGET_URL, { - signal: AbortSignal.timeout(5000), + signal: AbortSignal.timeout(probeTimeoutMs), }); const body = await response.text(); const nodeHttp = await nodeHttpGet(process.env.OPENCLAW_TEST_NODE_HTTP_TARGET_URL); @@ -306,6 +310,7 @@ describe("SSRF external proxy routing", () => { OPENCLAW_TEST_NODE_HTTPS_TARGET_URL: `https://127.0.0.1:${httpsLikeTargetPort}/https-connect-proof`, OPENCLAW_TEST_WS_TARGET_URL: `ws://127.0.0.1:${targetPort}/websocket-proxied`, OPENCLAW_TEST_GATEWAY_BYPASS_WS_URL: `ws://127.0.0.1:${targetPort}/gateway-bypass`, + OPENCLAW_TEST_PROXY_TIMEOUT_MS: String(CHILD_PROBE_TIMEOUT_MS), NO_PROXY: "127.0.0.1,localhost", no_proxy: "localhost", GLOBAL_AGENT_NO_PROXY: "localhost",