mirror of https://github.com/openclaw/openclaw.git
refactor(infra): share shell env timeout normalization
This commit is contained in:
parent
5ae4595bb9
commit
0a78331536
|
|
@ -1,6 +1,8 @@
|
|||
import { describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
getShellPathFromLoginShell,
|
||||
loadShellEnvFallback,
|
||||
resetShellPathCacheForTests,
|
||||
resolveShellEnvFallbackTimeoutMs,
|
||||
shouldEnableShellEnvFallback,
|
||||
} from "./shell-env.js";
|
||||
|
|
@ -71,4 +73,42 @@ describe("shell env fallback", () => {
|
|||
expect(env.DISCORD_BOT_TOKEN).toBe("discord");
|
||||
expect(exec2).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("resolves PATH via login shell and caches it", () => {
|
||||
resetShellPathCacheForTests();
|
||||
const exec = vi.fn(() => Buffer.from("PATH=/usr/local/bin:/usr/bin\0HOME=/tmp\0"));
|
||||
|
||||
const first = getShellPathFromLoginShell({
|
||||
env: {} as NodeJS.ProcessEnv,
|
||||
exec: exec as unknown as Parameters<typeof getShellPathFromLoginShell>[0]["exec"],
|
||||
});
|
||||
const second = getShellPathFromLoginShell({
|
||||
env: {} as NodeJS.ProcessEnv,
|
||||
exec: exec as unknown as Parameters<typeof getShellPathFromLoginShell>[0]["exec"],
|
||||
});
|
||||
|
||||
expect(first).toBe("/usr/local/bin:/usr/bin");
|
||||
expect(second).toBe("/usr/local/bin:/usr/bin");
|
||||
expect(exec).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("returns null on shell env read failure and caches null", () => {
|
||||
resetShellPathCacheForTests();
|
||||
const exec = vi.fn(() => {
|
||||
throw new Error("exec failed");
|
||||
});
|
||||
|
||||
const first = getShellPathFromLoginShell({
|
||||
env: {} as NodeJS.ProcessEnv,
|
||||
exec: exec as unknown as Parameters<typeof getShellPathFromLoginShell>[0]["exec"],
|
||||
});
|
||||
const second = getShellPathFromLoginShell({
|
||||
env: {} as NodeJS.ProcessEnv,
|
||||
exec: exec as unknown as Parameters<typeof getShellPathFromLoginShell>[0]["exec"],
|
||||
});
|
||||
|
||||
expect(first).toBeNull();
|
||||
expect(second).toBeNull();
|
||||
expect(exec).toHaveBeenCalledOnce();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,6 +6,13 @@ const DEFAULT_MAX_BUFFER_BYTES = 2 * 1024 * 1024;
|
|||
let lastAppliedKeys: string[] = [];
|
||||
let cachedShellPath: string | null | undefined;
|
||||
|
||||
function resolveTimeoutMs(timeoutMs: number | undefined): number {
|
||||
if (typeof timeoutMs !== "number" || !Number.isFinite(timeoutMs)) {
|
||||
return DEFAULT_TIMEOUT_MS;
|
||||
}
|
||||
return Math.max(0, timeoutMs);
|
||||
}
|
||||
|
||||
function resolveShell(env: NodeJS.ProcessEnv): string {
|
||||
const shell = env.SHELL?.trim();
|
||||
return shell && shell.length > 0 ? shell : "/bin/sh";
|
||||
|
|
@ -76,10 +83,7 @@ export function loadShellEnvFallback(opts: ShellEnvFallbackOptions): ShellEnvFal
|
|||
return { ok: true, applied: [], skippedReason: "already-has-keys" };
|
||||
}
|
||||
|
||||
const timeoutMs =
|
||||
typeof opts.timeoutMs === "number" && Number.isFinite(opts.timeoutMs)
|
||||
? Math.max(0, opts.timeoutMs)
|
||||
: DEFAULT_TIMEOUT_MS;
|
||||
const timeoutMs = resolveTimeoutMs(opts.timeoutMs);
|
||||
|
||||
const shell = resolveShell(opts.env);
|
||||
|
||||
|
|
@ -146,10 +150,7 @@ export function getShellPathFromLoginShell(opts: {
|
|||
}
|
||||
|
||||
const exec = opts.exec ?? execFileSync;
|
||||
const timeoutMs =
|
||||
typeof opts.timeoutMs === "number" && Number.isFinite(opts.timeoutMs)
|
||||
? Math.max(0, opts.timeoutMs)
|
||||
: DEFAULT_TIMEOUT_MS;
|
||||
const timeoutMs = resolveTimeoutMs(opts.timeoutMs);
|
||||
const shell = resolveShell(opts.env);
|
||||
|
||||
let stdout: Buffer;
|
||||
|
|
|
|||
Loading…
Reference in New Issue