mirror of
https://github.com/oven-sh/bun
synced 2026-02-18 14:51:52 +00:00
Update test-macos-app-sandbox.test.ts
This commit is contained in:
@@ -1,33 +1,9 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { copyFileSync } from "fs";
|
||||
import { copyFileSync, rmSync } from "fs";
|
||||
import { homedir } from "os";
|
||||
import { bunEnv, bunExe, isMacOS, tempDir } from "harness";
|
||||
import { join } from "path";
|
||||
|
||||
const infoPlist = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>bun</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>dev.bun.test.bun_sandboxed</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>bun_sandboxed</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>`;
|
||||
|
||||
const entitlementsPlist = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
@@ -45,12 +21,39 @@ const entitlementsPlist = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
</dict>
|
||||
</plist>`;
|
||||
|
||||
async function createSandboxedApp(prefix: string) {
|
||||
function makeInfoPlist(bundleId: string) {
|
||||
return `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>bun</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${bundleId}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>bun_sandboxed</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>`;
|
||||
}
|
||||
|
||||
async function createSandboxedApp(prefix: string, bundleId: string) {
|
||||
const dir = tempDir(prefix, {
|
||||
"entitlements.plist": entitlementsPlist,
|
||||
"bun_sandboxed.app": {
|
||||
"Contents": {
|
||||
"Info.plist": infoPlist,
|
||||
"Info.plist": makeInfoPlist(bundleId),
|
||||
"MacOS": {},
|
||||
},
|
||||
},
|
||||
@@ -65,46 +68,60 @@ async function createSandboxedApp(prefix: string) {
|
||||
await using codesign = Bun.spawn({
|
||||
cmd: ["/usr/bin/codesign", "--entitlements", entitlementsPath, "--force", "-s", "-", appBundlePath],
|
||||
env: bunEnv,
|
||||
stderr: "pipe",
|
||||
stdout: "pipe",
|
||||
stderr: "inherit",
|
||||
});
|
||||
expect(await codesign.exited).toBe(0);
|
||||
|
||||
return { dir, bunPath };
|
||||
return { dir, bunPath, bundleId, containerPath: join(homedir(), "Library", "Containers", bundleId) };
|
||||
}
|
||||
|
||||
// Modeled after Node.js's test/parallel/test-macos-app-sandbox.js
|
||||
describe.skipIf(!isMacOS)("macOS App Sandbox", () => {
|
||||
test.concurrent("bun can execute JavaScript inside the app sandbox", async () => {
|
||||
const { dir, bunPath } = await createSandboxedApp("macos-sandbox-test");
|
||||
const { dir, bunPath, containerPath } = await createSandboxedApp("macos-sandbox-test", "dev.bun.test.sandbox_exec");
|
||||
using _dir = dir;
|
||||
|
||||
await using proc = Bun.spawn({
|
||||
cmd: [bunPath, "-e", "console.log('hello sandbox')"],
|
||||
env: bunEnv,
|
||||
stderr: "pipe",
|
||||
});
|
||||
try {
|
||||
await using proc = Bun.spawn({
|
||||
cmd: [bunPath, "-e", "console.log('hello sandbox')"],
|
||||
env: bunEnv,
|
||||
stdout: "pipe",
|
||||
stderr: "inherit",
|
||||
});
|
||||
|
||||
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
|
||||
const [stdout, exitCode] = await Promise.all([proc.stdout.text(), proc.exited]);
|
||||
|
||||
expect(stdout.trim()).toBe("hello sandbox");
|
||||
expect(exitCode).toBe(0);
|
||||
expect(stdout.trim()).toBe("hello sandbox");
|
||||
expect(exitCode).toBe(0);
|
||||
} finally {
|
||||
rmSync(containerPath, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test.concurrent("sandboxed bun runs inside the sandbox container", async () => {
|
||||
const { dir, bunPath } = await createSandboxedApp("macos-sandbox-test-container");
|
||||
const { dir, bunPath, bundleId, containerPath } = await createSandboxedApp(
|
||||
"macos-sandbox-test-container",
|
||||
"dev.bun.test.sandbox_container",
|
||||
);
|
||||
using _dir = dir;
|
||||
|
||||
// When running inside a macOS App Sandbox, os.homedir() should return
|
||||
// the sandbox container path, not the real home directory.
|
||||
await using proc = Bun.spawn({
|
||||
cmd: [bunPath, "-e", "console.log(require('os').homedir())"],
|
||||
env: bunEnv,
|
||||
stderr: "pipe",
|
||||
});
|
||||
try {
|
||||
// When running inside a macOS App Sandbox, os.homedir() should return
|
||||
// the sandbox container path, not the real home directory.
|
||||
await using proc = Bun.spawn({
|
||||
cmd: [bunPath, "-e", "console.log(require('os').homedir())"],
|
||||
env: bunEnv,
|
||||
stdout: "pipe",
|
||||
stderr: "inherit",
|
||||
});
|
||||
|
||||
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
|
||||
const [stdout, exitCode] = await Promise.all([proc.stdout.text(), proc.exited]);
|
||||
|
||||
expect(stdout.trim()).toContain("Library/Containers/dev.bun.test.bun_sandboxed");
|
||||
expect(exitCode).toBe(0);
|
||||
expect(stdout.trim()).toContain(`Library/Containers/${bundleId}`);
|
||||
expect(exitCode).toBe(0);
|
||||
} finally {
|
||||
rmSync(containerPath, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user