diff --git a/tests/boundary/process/darwinProcessRunTokenReader.test.ts b/tests/boundary/process/darwinProcessRunTokenReader.test.ts index 6e5e264bb3..dcdddc3afa 100644 --- a/tests/boundary/process/darwinProcessRunTokenReader.test.ts +++ b/tests/boundary/process/darwinProcessRunTokenReader.test.ts @@ -41,12 +41,22 @@ import { electronActiveObservationInputSchema } from "../../../src/domain/javasc const execFileAsync = promisify(execFile); const onDarwin = process.platform === "darwin"; +// Readiness files are polled by another process; expose only complete JSON. +const publishFixtureStateSource = ` +const publishFixtureState = (file, value) => { + const pending = file + "." + process.pid + ".pending"; + fs.writeFileSync(pending, JSON.stringify(value)); + fs.renameSync(pending, file); +}; +`; + const writeBlockingCompiler = async (directory: string) => { const executable = join(directory, "fake-xcrun"); const statePath = join(directory, "compile-state.json"); const releasePath = join(directory, "release-compiler"); const source = `#!/usr/bin/env node const fs = process.getBuiltinModule("node:fs"); +${publishFixtureStateSource} const path = process.getBuiltinModule("node:path"); const statePath = ${JSON.stringify(statePath)}; const releasePath = ${JSON.stringify(releasePath)}; @@ -59,7 +69,7 @@ state.output = process.argv[outputIndex + 1]; state.root = path.dirname(state.output); state.arguments = process.argv.slice(2); state.releasePath = releasePath; -fs.writeFileSync(statePath, JSON.stringify(state)); +publishFixtureState(statePath, state); if (state.calls === 1) { const timer = setInterval(() => { if (!fs.existsSync(releasePath)) return; @@ -80,9 +90,10 @@ const writeBlockingIdentityCompiler = async (directory: string) => { const statePath = join(directory, "identity-helper-state.json"); const helperSource = `#!/usr/bin/env node const fs = process.getBuiltinModule("node:fs"); -fs.writeFileSync(${JSON.stringify(statePath)}, JSON.stringify({ +${publishFixtureStateSource} +publishFixtureState(${JSON.stringify(statePath)}, { root: process.getBuiltinModule("node:path").dirname(fs.realpathSync(process.argv[1])), -})); +}); setInterval(() => {}, 1000); `; const compilerSource = `#!/usr/bin/env node @@ -413,13 +424,14 @@ const writeCacheRecordingCompiler = async (directory: string) => { const statePath = join(directory, "cache-compile-state.json"); const source = `#!/usr/bin/env node const fs = process.getBuiltinModule("node:fs"); +${publishFixtureStateSource} const path = process.getBuiltinModule("node:path"); const flagIndex = process.argv.indexOf("-module-cache-path"); const cache = flagIndex === -1 ? undefined : process.argv[flagIndex + 1]; -fs.writeFileSync(${JSON.stringify(statePath)}, JSON.stringify({ +publishFixtureState(${JSON.stringify(statePath)}, { arguments: process.argv.slice(2), moduleCacheEnvironment: process.env.CLANG_MODULE_CACHE_PATH ?? null, -})); +}); if (cache !== undefined) { fs.mkdirSync(cache, { recursive: true }); fs.writeFileSync(path.join(cache, "written-into-cache"), "kept"); @@ -628,6 +640,33 @@ it.skipIf(!onDarwin)( }); try { await host.prepare?.(AbortSignal.timeout(180_000)); + const current = (await host.listProcesses()).find( + ({ pid }) => pid === process.pid, + ); + if (current === undefined) + throw new Error("Current process missing from host snapshot"); + if (host.processIdentities === undefined) + throw new Error("Darwin host omitted native identity inspection"); + const identity = (await host.processIdentities([current])).get( + process.pid, + ); + expect(identity).toMatchObject({ + state: "readable", + relation: { + state: "observed", + parentPid: process.ppid, + processGroupId: current.processGroupId, + }, + }); + if (identity?.state !== "readable") + throw new Error("Current native identity unavailable"); + expect(identity.identity).not.toBe(""); + expect( + (await host.processIdentities([current])).get(process.pid), + ).toMatchObject({ + state: "readable", + identity: identity.identity, + }); const entries = await readdir(cachePath); expect( entries.some( @@ -705,6 +744,7 @@ const writeTemporaryObjectCompiler = async (directory: string) => { const statePath = join(directory, "temporary-state.json"); const source = `#!/usr/bin/env node const fs = process.getBuiltinModule("node:fs"); +${publishFixtureStateSource} const os = process.getBuiltinModule("node:os"); const path = process.getBuiltinModule("node:path"); const { spawn } = process.getBuiltinModule("node:child_process"); @@ -721,7 +761,7 @@ process.on("SIGINT", () => { process.exit(130); }); const output = process.argv[process.argv.indexOf("-o") + 1]; -fs.writeFileSync(${JSON.stringify(statePath)}, JSON.stringify({ root: path.dirname(output), temporary })); +publishFixtureState(${JSON.stringify(statePath)}, { root: path.dirname(output), temporary }); setInterval(() => {}, 1000); `; await writeFile(executable, source);