Skip to content

Commit e84e186

Browse files
author
pavelhov
committed
test: preserve PowerShell utility environment in Windows fixtures
1 parent 91b682e commit e84e186

1 file changed

Lines changed: 3 additions & 58 deletions

File tree

‎tests/codex-composed-acceptance.test.ts‎

Lines changed: 3 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import {
2121
} from "node:fs";
2222
import { tmpdir } from "node:os";
2323
import { join, relative, resolve } from "node:path";
24-
import { pathToFileURL } from "node:url";
2524

2625
import {
2726
canonicalizeCodexHome,
@@ -104,11 +103,11 @@ class Fixture {
104103

105104
env(home = this.homeA, userprofile = this.userprofileA): Record<string, string> {
106105
// Windows identity/ACL probes launch OS utilities. Preserve their lookup
107-
// environment, including the account name used by windows-secret-acl,
108-
// while keeping every application home explicitly isolated.
106+
// environment: ACL account names and PowerShell module/execution settings
107+
// used by Add-Type. Every application home remains explicitly isolated.
109108
const windowsEnv = process.platform === "win32"
110109
? Object.fromEntries(Object.entries(process.env).filter(([key, value]) =>
111-
/^(PATH|PATHEXT|SYSTEMROOT|WINDIR|COMSPEC|TEMP|TMP|USERNAME|USERDOMAIN)$/i.test(key) && value !== undefined))
110+
/^(PATH|PATHEXT|SYSTEMROOT|WINDIR|COMSPEC|TEMP|TMP|USERNAME|USERDOMAIN|PSModulePath|PSExecutionPolicyPreference)$/i.test(key) && value !== undefined))
112111
: {};
113112
return {
114113
...windowsEnv,
@@ -297,61 +296,7 @@ afterEach(async () => {
297296
while (roots.length) await roots.pop()!.cleanup();
298297
});
299298

300-
type WindowsProbeResult = { variant: string; stage: string; exit: number | null; elapsedMs: number; stdoutPresent: boolean; stderrPresent: boolean; killed: boolean };
301-
302-
async function diagnoseWindowsFixtureEnvironment(fx: Fixture): Promise<void> {
303-
const strict = fx.env();
304-
// These children execute only fixed OS identity/compiler probes, never the
305-
// CLI, profiles, network requests, or application credential readers.
306-
const inherited = { ...process.env, ...strict };
307-
const groups: Record<string, RegExp> = {
308-
powershell: /^(PSModulePath|PSExecutionPolicyPreference)$/i,
309-
programLocations: /^(ProgramFiles(?:\(x86\))?|ProgramW6432|CommonProgramFiles(?:\(x86\))?|CommonProgramW6432|ProgramData|ALLUSERSPROFILE)$/i,
310-
system: /^(SystemDrive|OS|PROCESSOR_ARCHITECTURE|PROCESSOR_ARCHITEW6432|PROCESSOR_IDENTIFIER|PROCESSOR_LEVEL|PROCESSOR_REVISION|NUMBER_OF_PROCESSORS|COMPUTERNAME|LOGONSERVER|PUBLIC|HOMEDRIVE|HOMEPATH)$/i,
311-
};
312-
const expressions = {
313-
sid: "$ErrorActionPreference='Stop'; $null=[System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value",
314-
compiler: "$ErrorActionPreference='Stop'; Add-Type -TypeDefinition 'public static class CcxProbe { public static int Value() { return 1; } }'; $null=[CcxProbe]::Value()",
315-
};
316-
const results: WindowsProbeResult[] = [];
317-
const probe = async (variant: string, stage: string, env: Record<string, string | undefined>): Promise<WindowsProbeResult> => {
318-
const command = stage === "resolver"
319-
? [process.execPath, "--eval", [
320-
`const { resolveEffectiveUserIdentity, resolveCodexCoordinatorDatabasePath } = await import(${JSON.stringify(pathToFileURL(resolve(repoRoot, "src/codex/user-identity.ts")).href)});`,
321-
"try { resolveCodexCoordinatorDatabasePath(resolveEffectiveUserIdentity(), process.env.CODEX_HOME); } catch { process.exitCode = 1; }",
322-
].join("\n")]
323-
: ["powershell.exe", "-NoLogo", "-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(expressions[stage as keyof typeof expressions], "utf16le").toString("base64")];
324-
const started = Date.now();
325-
const child = Bun.spawn(command, { cwd: fx.root, env, stdout: "pipe", stderr: "pipe" });
326-
fx.children.push(child);
327-
let killed = false;
328-
const timer = setTimeout(() => { killed = true; child.kill(); }, stage === "resolver" ? 25_000 : 12_000);
329-
try {
330-
const [exit, stdout, stderr] = await Promise.all([child.exited, new Response(child.stdout).text(), new Response(child.stderr).text()]);
331-
const result = { variant, stage, exit, elapsedMs: Date.now() - started, stdoutPresent: !!stdout, stderrPresent: !!stderr, killed };
332-
results.push(result);
333-
return result;
334-
} finally {
335-
clearTimeout(timer);
336-
}
337-
};
338-
for (const stage of ["sid", "compiler", "resolver"]) {
339-
const baseline = await probe("strict", stage, strict);
340-
const contrast = await probe("inherited", stage, inherited);
341-
if (baseline.exit !== 0 && contrast.exit === 0) {
342-
for (const [name, pattern] of Object.entries(groups)) {
343-
const group = Object.fromEntries(Object.entries(process.env).filter(([key]) => pattern.test(key)));
344-
await probe(name, stage, { ...strict, ...group });
345-
}
346-
}
347-
}
348-
console.log(`CCX_WINDOWS_FIXTURE_PROBES ${JSON.stringify(results)}`);
349-
}
350-
351299
describe("WP13 composed toggle acceptance", () => {
352-
test.skipIf(process.platform !== "win32")("Windows fixture OS environment diagnostic", async () => {
353-
await diagnoseWindowsFixtureEnvironment(fixture());
354-
}, 300_000);
355300

356301
/** RED: remove `shouldSyncCodexOnStart` or the under-lock desired-state read; an OFF row writes native bytes. */
357302
test("A-reduced: real CLI and HTTP entry points preserve an OFF Codex home", async () => {

0 commit comments

Comments
 (0)