mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 02:48:50 +00:00
120 lines
4.3 KiB
TypeScript
120 lines
4.3 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import { bunExe, isWindows } from "harness";
|
|
import { exec } from "node:child_process";
|
|
|
|
const SIZE = 262145;
|
|
|
|
// https://github.com/oven-sh/bun/issues/5319
|
|
describe("child_process.exec", () => {
|
|
const shell = Bun.which(isWindows ? "powershell" : "bash");
|
|
|
|
describe.each(["stdout", "stderr"])("%s", io => {
|
|
let script;
|
|
if (isWindows) {
|
|
if (io === "stdout") {
|
|
script = `[Console]::Out.Write.Invoke('=' * ${SIZE})`;
|
|
} else {
|
|
script = `[Console]::Error.Write.Invoke('=' * ${SIZE})`;
|
|
}
|
|
} else {
|
|
if (io === "stdout") {
|
|
script = `printf '=%.0s' {1..${SIZE}}`;
|
|
} else {
|
|
script = `printf '=%.0s' {1..${SIZE}} 1>&2`;
|
|
}
|
|
}
|
|
|
|
test("no encoding", async () => {
|
|
const { resolve, reject, promise } = Promise.withResolvers();
|
|
exec(script, { maxBuffer: 1024 * 1024 * 10, encoding: "buffer", shell }, (err, stdout, stderr) => {
|
|
if (err) {
|
|
reject(err);
|
|
} else {
|
|
resolve({ stdout, stderr });
|
|
}
|
|
});
|
|
const { stdout, stderr } = await promise;
|
|
const out = io === "stdout" ? stdout : stderr;
|
|
const other = io === "stdout" ? stderr : stdout;
|
|
expect(out).toHaveLength(SIZE);
|
|
expect(out).toBeInstanceOf(Buffer);
|
|
expect(other).toEqual(Buffer.alloc(0));
|
|
});
|
|
|
|
test("Infinity maxBuffer", async () => {
|
|
const { resolve, reject, promise } = Promise.withResolvers();
|
|
exec(script, { maxBuffer: Infinity, shell }, (err, stdout, stderr) => {
|
|
if (err) {
|
|
reject(err);
|
|
} else {
|
|
resolve({ stdout, stderr });
|
|
}
|
|
});
|
|
const { stdout, stderr } = await promise;
|
|
const out = io === "stdout" ? stdout : stderr;
|
|
const other = io === "stdout" ? stderr : stdout;
|
|
expect(out).toHaveLength(SIZE);
|
|
expect(other).toBe("");
|
|
});
|
|
|
|
test("large output", async () => {
|
|
const { resolve, reject, promise } = Promise.withResolvers();
|
|
exec(script, { maxBuffer: 1024 * 1024 * 10, shell }, (err, stdout, stderr) => {
|
|
if (err) {
|
|
reject(err);
|
|
} else {
|
|
resolve({ stdout, stderr });
|
|
}
|
|
});
|
|
const { stdout, stderr } = await promise;
|
|
const out = io === "stdout" ? stdout : stderr;
|
|
const other = io === "stdout" ? stderr : stdout;
|
|
expect(out).toHaveLength(SIZE);
|
|
expect(other).toBe("");
|
|
});
|
|
|
|
test("exceeding maxBuffer should throw", async () => {
|
|
const { resolve, reject, promise } = Promise.withResolvers();
|
|
exec(script, { maxBuffer: 1024 * 100, shell }, (err, stdout, stderr) => {
|
|
resolve({ stdout, stderr, err });
|
|
});
|
|
const { stdout, stderr, err } = await promise;
|
|
expect(err.message).toContain("maxBuffer length exceeded");
|
|
expect(err.message).toContain(io);
|
|
const out = io === "stdout" ? stdout : stderr;
|
|
const other = io === "stdout" ? stderr : stdout;
|
|
expect(out.trim()).toHaveLength(1024 * 100);
|
|
expect(other).toBe("");
|
|
});
|
|
|
|
test("exceeding maxBuffer should truncate output length", async () => {
|
|
const { resolve, reject, promise } = Promise.withResolvers();
|
|
exec(script, { maxBuffer: 1024 * 255 - 1, shell }, (err, stdout, stderr) => {
|
|
resolve({ stdout, stderr, err });
|
|
});
|
|
const { stdout, stderr, err } = await promise;
|
|
expect(err.message).toContain("maxBuffer length exceeded");
|
|
expect(err.message).toContain(io);
|
|
const out = (io === "stdout" ? stdout : stderr).trim();
|
|
const other = (io === "stdout" ? stderr : stdout).trim();
|
|
expect(out.length).toBeLessThanOrEqual(1024 * 255 - 1);
|
|
expect(out.length).toBeGreaterThan(1024 * 100);
|
|
expect(other).toBe("");
|
|
});
|
|
});
|
|
});
|
|
|
|
test("exec with verbatim arguments", async () => {
|
|
const { resolve, reject, promise } = Promise.withResolvers();
|
|
|
|
const fixture = require.resolve("./fixtures/child-process-echo-argv.js");
|
|
const child = exec(`${bunExe()} ${fixture} tasklist /FI "IMAGENAME eq chrome.exe"`, (err, stdout, stderr) => {
|
|
if (err) return reject(err);
|
|
return resolve({ stdout, stderr });
|
|
});
|
|
expect(!!child).toBe(true);
|
|
|
|
const { stdout } = await promise;
|
|
expect(stdout.trim().split("\n")).toEqual([`tasklist`, `/FI`, `IMAGENAME eq chrome.exe`]);
|
|
});
|