test(process): make Linux adapter wiring portable (#120741)

Co-authored-by: Peter Steinberger <steipete@openai.com>
This commit is contained in:
Peter Steinberger
2026-08-08 16:48:07 -07:00
committed by GitHub
parent 2289d9658a
commit 5400311be1
3 changed files with 27 additions and 2 deletions
@@ -10,6 +10,7 @@ import { useAutoCleanupTempDirTracker } from "../../../../test/helpers/temp-dir.
import {
expectRealExitWinsOverSigkillFallback,
expectWaitStaysPendingUntilSigkillFallback,
mockLinuxOomWrapperShell,
} from "./test-support.js";
const { spawnWithFallbackMock, signalProcessTreeMock, createWindowsOutputDecoderMock } = vi.hoisted(
@@ -742,6 +743,7 @@ describe("createChildAdapter", () => {
const originalEnv = process.env.ENV;
const originalCdpath = process.env.CDPATH;
setPlatform("linux");
const restoreLinuxShell = mockLinuxOomWrapperShell();
process.env.BASH_ENV = "/tmp/bashenv";
process.env.ENV = "/tmp/env";
process.env.CDPATH = "/tmp";
@@ -752,6 +754,7 @@ describe("createChildAdapter", () => {
});
expect(adapter.oomScoreWrapperSelected).toBe(true);
} finally {
restoreLinuxShell();
if (originalBashEnv === undefined) {
delete process.env.BASH_ENV;
} else {
+7 -2
View File
@@ -3,6 +3,7 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite
import {
expectRealExitWinsOverSigkillFallback,
expectWaitStaysPendingUntilSigkillFallback,
mockLinuxOomWrapperShell,
} from "./test-support.js";
const { spawnMock, ptyKillMock, signalProcessTreeMock } = vi.hoisted(() => ({
@@ -157,7 +158,7 @@ describe("createPtyAdapter", () => {
it("forwards non-SIGTERM explicit signals to node-pty kill on non-Windows", async () => {
const originalPlatform = Object.getOwnPropertyDescriptor(process, "platform");
Object.defineProperty(process, "platform", { value: "linux", configurable: true });
Object.defineProperty(process, "platform", { value: "darwin", configurable: true });
try {
spawnMock.mockReturnValue(createStubPty());
@@ -316,17 +317,21 @@ describe("createPtyAdapter", () => {
it("wraps Linux PTY spawns so shell children inherit higher OOM score", async () => {
const originalPlatform = Object.getOwnPropertyDescriptor(process, "platform");
Object.defineProperty(process, "platform", { value: "linux", configurable: true });
const restoreLinuxShell = mockLinuxOomWrapperShell();
vi.resetModules();
try {
const { createPtyAdapter: createLinuxPtyAdapter } = await import("./pty.js");
const stub = createStubPty();
spawnMock.mockReturnValue(stub);
const adapter = await createPtyAdapter({
const adapter = await createLinuxPtyAdapter({
shell: "bash",
args: ["-lc", "env"],
env: { PATH: "/usr/bin", BASH_ENV: "/tmp/bashenv", TERM: "dumb" },
});
expect(adapter.oomScoreWrapperSelected).toBe(true);
} finally {
restoreLinuxShell();
if (originalPlatform) {
Object.defineProperty(process, "platform", originalPlatform);
}
@@ -1,4 +1,5 @@
// Supervisor adapter test support builds mock process handles for adapter tests.
import fs from "node:fs";
import { expect, vi } from "vitest";
/**
@@ -11,6 +12,22 @@ type WaitResult = {
signal: number | NodeJS.Signals | null;
};
/** Keep Linux adapter wiring tests deterministic on hosts without `/bin/sh`. */
export function mockLinuxOomWrapperShell(): () => void {
const statSync = fs.statSync.bind(fs);
const fileStats = statSync(process.execPath);
const statSyncMock = vi
.spyOn(fs, "statSync")
.mockImplementation((target, options) =>
String(target) === "/bin/sh" ? fileStats : statSync(target, options as never),
);
return () => {
statSyncMock.mockRestore();
// The production helper memoizes shell availability; clear it for later tests.
vi.resetModules();
};
}
/** Assert fallback SIGKILL resolves only after the grace timer expires. */
export async function expectWaitStaysPendingUntilSigkillFallback(
waitPromise: Promise<WaitResult>,