// Test support: the current user's IDs, a fresh temporary directory, and a // plain command runner. It imports no source module, so the repository-level // tests in tests/, which reach src/ only through `#testing`, never touch // internals. import { spawn } from "node:child_process"; import { once } from "node:events"; import { mkdtemp } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import process from "node:process"; import { text } from "node:stream/consumers"; export function currentUid(): number { return process.getuid?.() ?? -1; } export function currentGid(): number { return process.getgid?.() ?? -1; } // The isolation tests switch UIDs, which only root may do. export const IS_ROOT: boolean = currentUid() === 0; // Symlinks and POSIX modes, as these tests use them, need a Unix host. export const IS_WINDOWS: boolean = process.platform === "win32"; export function makeTempDir(): Promise { return mkdtemp(join(tmpdir(), "bot-agents-test-")); } export interface CommandResult { success: boolean; stderr: string; } // Runs a command with stdin closed and only the given environment, and // collects its stderr. export async function runCommand( command: string, args: string[], env: Record, ): Promise { const child = spawn(command, args, { env, stdio: ["ignore", "ignore", "pipe"] }); const [stderr, closed] = await Promise.all([text(child.stderr), once(child, "close")]); const exitCode: unknown = closed[0]; return { success: exitCode === 0, stderr }; }