diff --git a/tests/boundary/cli/doctorHopperDiscovery.test.ts b/tests/boundary/cli/doctorHopperDiscovery.test.ts index a637f73914..0e7fdeacb9 100644 --- a/tests/boundary/cli/doctorHopperDiscovery.test.ts +++ b/tests/boundary/cli/doctorHopperDiscovery.test.ts @@ -1,5 +1,5 @@ -import { access, chmod, mkdir, writeFile } from "node:fs/promises"; -import { join } from "node:path"; +import { access, chmod, mkdir, readFile, writeFile } from "node:fs/promises"; +import { delimiter, join } from "node:path"; import { expect } from "vitest"; @@ -18,11 +18,35 @@ cliTest.skipIf(!["darwin", "linux"].includes(process.platform))( '#!/bin/sh\nprintf launched > "$REA_HOPPER_TEST_MARKER"\nexit 99\n', ); await chmod(launcher, 0o700); + const loaderMarker = join(home, "loader-checked-launcher"); + if (process.platform === "linux") { + // A shell fixture needs controlled loader diagnostics on Linux. This + // checks discovery and path preservation, not actual Hopper compatibility. + const loader = join(home, "bin", "ldd"); + await writeFile( + loader, + [ + "#!/bin/sh", + 'test "$#" -eq 1 || exit 87', + 'test "$1" = "$HOPPER_LAUNCHER_PATH" || exit 88', + 'printf "%s" "$1" > "$REA_HOPPER_LDD_TEST_MARKER"', + 'printf "%s\\n" "libc.so.6 => /fixture/libc.so.6 (0x1)"', + "", + ].join("\n"), + ); + await chmod(loader, 0o700); + } const result = await cli.run({ arguments: ["doctor", "--provider", "hopper", "--json"], cwd: home, environment: { + ...(process.platform === "linux" + ? { + PATH: [join(home, "bin"), process.env.PATH ?? ""].join(delimiter), + REA_HOPPER_LDD_TEST_MARKER: loaderMarker, + } + : {}), HOME: home, USERPROFILE: home, HOPPER_LAUNCHER_PATH: launcher, @@ -55,5 +79,7 @@ cliTest.skipIf(!["darwin", "linux"].includes(process.platform))( await expect(access(launchMarker)).rejects.toMatchObject({ code: "ENOENT", }); + if (process.platform === "linux") + expect(await readFile(loaderMarker, "utf8")).toBe(launcher); }, ); diff --git a/tests/boundary/providers/RizinDebugSessionCoverage.part2.test.ts b/tests/boundary/providers/RizinDebugSessionCoverage.part2.test.ts index 13b6c6dcf1..ba63901845 100644 --- a/tests/boundary/providers/RizinDebugSessionCoverage.part2.test.ts +++ b/tests/boundary/providers/RizinDebugSessionCoverage.part2.test.ts @@ -19,7 +19,8 @@ it.skipIf(process.platform === "win32")( "stops the session when the provider closes its stdin pipe", async () => { const provider = await makeProvider( - 'printf "\\000"; exec 0<&-; while :; do :; done', + // Readiness must guarantee that the child's stdin is already closed. + 'exec 0<&-; printf "\\000"; while :; do :; done', "#!/bin/sh", ); const { manager, sessionId } = await start(provider, {