aboutsummaryrefslogtreecommitdiff
path: root/test/bun.js/spawn.test.ts
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-10-11 20:25:16 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-10-11 20:25:16 -0700
commit36adee4dc80c0aeb4d46bf56775af2a7a512b576 (patch)
treee9863b18e42ddb18e9c66d9ad69afc3b1e009eda /test/bun.js/spawn.test.ts
parent9fe1ad93cb8a8c0d398061a3c4548e0d8ef99f70 (diff)
downloadbun-36adee4dc80c0aeb4d46bf56775af2a7a512b576.tar.gz
bun-36adee4dc80c0aeb4d46bf56775af2a7a512b576.tar.zst
bun-36adee4dc80c0aeb4d46bf56775af2a7a512b576.zip
Make `Bun.spawn` work on Linux
Diffstat (limited to '')
-rw-r--r--test/bun.js/spawn.test.ts277
1 files changed, 153 insertions, 124 deletions
diff --git a/test/bun.js/spawn.test.ts b/test/bun.js/spawn.test.ts
index e03de2662..b8e0459c5 100644
--- a/test/bun.js/spawn.test.ts
+++ b/test/bun.js/spawn.test.ts
@@ -1,141 +1,170 @@
import { readableStreamToText, spawn, write } from "bun";
import { describe, expect, it } from "bun:test";
-import { rmdirSync, unlinkSync, rmSync } from "node:fs";
-
-describe("spawn", () => {
- const hugeString = "hello".repeat(10000).slice();
-
- it("Bun.file() works as stdout", async () => {
- rmSync("/tmp/out.123.txt", { force: true });
- const { exited } = spawn({
- cmd: ["echo", "hello"],
- stdout: Bun.file("/tmp/out.123.txt"),
- });
-
- await exited;
- expect(await Bun.file("/tmp/out.123.txt").text()).toBe("hello\n");
- });
-
- it("Bun.file() works as stdin", async () => {
- await write(Bun.file("/tmp/out.456.txt"), "hello there!");
- const { stdout } = spawn({
- cmd: ["cat"],
- stdout: "pipe",
- stdin: Bun.file("/tmp/out.456.txt"),
- });
-
- expect(await readableStreamToText(stdout)).toBe("hello there!");
- });
-
- it("Bun.file() works as stdin and stdout", async () => {
- await write(Bun.file("/tmp/out.456.txt"), "hello!");
- await write(Bun.file("/tmp/out.123.txt"), "wrong!");
-
- const { exited } = spawn({
- cmd: ["cat"],
- stdout: Bun.file("/tmp/out.123.txt"),
- stdin: Bun.file("/tmp/out.456.txt"),
- });
-
- await exited;
- expect(await Bun.file("/tmp/out.456.txt").text()).toBe("hello!");
- expect(await Bun.file("/tmp/out.123.txt").text()).toBe("hello!");
- });
+import { gcTick as _gcTick } from "gc";
+import { rmdirSync, unlinkSync, rmSync, writeFileSync } from "node:fs";
+
+for (let [gcTick, label] of [
+ [_gcTick, "gcTick"],
+ [() => {}, "no gc tick"],
+]) {
+ describe(label, () => {
+ describe("spawn", () => {
+ const hugeString = "hello".repeat(10000).slice();
+
+ it("Bun.file() works as stdout", async () => {
+ rmSync("/tmp/out.123.txt", { force: true });
+ gcTick();
+ const { exited } = spawn({
+ cmd: ["echo", "hello"],
+ stdout: Bun.file("/tmp/out.123.txt"),
+ });
- it("stdout can be read", async () => {
- await Bun.write("/tmp/out.txt", hugeString);
- const { stdout } = spawn({
- cmd: ["cat", "/tmp/out.txt"],
- stdout: "pipe",
- });
+ await exited;
+ gcTick();
+ expect(await Bun.file("/tmp/out.123.txt").text()).toBe("hello\n");
+ });
- const text = await readableStreamToText(stdout);
- expect(text).toBe(hugeString);
- });
+ it("Bun.file() works as stdin", async () => {
+ await write(Bun.file("/tmp/out.456.txt"), "hello there!");
+ gcTick();
+ const { stdout } = spawn({
+ cmd: ["cat"],
+ stdout: "pipe",
+ stdin: Bun.file("/tmp/out.456.txt"),
+ });
+ gcTick();
+ expect(await readableStreamToText(stdout)).toBe("hello there!");
+ });
- it("stdin can be read and stdout can be written", async () => {
- const { stdout, stdin, exited } = spawn({
- cmd: ["bash", import.meta.dir + "/bash-echo.sh"],
- stdout: "pipe",
- stdin: "pipe",
- stderr: "inherit",
- });
+ it("Bun.file() works as stdin and stdout", async () => {
+ writeFileSync("/tmp/out.456.txt", "hello!");
+ gcTick();
+ writeFileSync("/tmp/out.123.txt", "wrong!");
+ gcTick();
- await stdin.write(hugeString);
- await stdin.end();
+ const { exited } = spawn({
+ cmd: ["cat"],
+ stdout: Bun.file("/tmp/out.123.txt"),
+ stdin: Bun.file("/tmp/out.456.txt"),
+ });
+ gcTick();
+ await exited;
+ expect(await Bun.file("/tmp/out.456.txt").text()).toBe("hello!");
+ gcTick();
+ expect(await Bun.file("/tmp/out.123.txt").text()).toBe("hello!");
+ });
- const text = await readableStreamToText(stdout);
- expect(text.trim()).toBe(hugeString);
- await exited;
- });
+ it("stdout can be read", async () => {
+ await Bun.write("/tmp/out.txt", hugeString);
+ gcTick();
+ const { stdout } = spawn({
+ cmd: ["cat", "/tmp/out.txt"],
+ stdout: "pipe",
+ });
+ gcTick();
- describe("pipe", () => {
- function huge() {
- return spawn({
- cmd: ["echo", hugeString],
- stdout: "pipe",
- stdin: "pipe",
- stderr: "inherit",
+ const text = await readableStreamToText(stdout);
+ gcTick();
+ expect(text).toBe(hugeString);
});
- }
- function helloWorld() {
- return spawn({
- cmd: ["echo", "hello"],
- stdout: "pipe",
- stdin: "pipe",
+ it("stdin can be read and stdout can be written", async () => {
+ const proc = spawn({
+ cmd: ["bash", import.meta.dir + "/bash-echo.sh"],
+ stdout: "pipe",
+ stdin: "pipe",
+ stderr: "inherit",
+ });
+ proc.stdin.write(hugeString);
+ await proc.stdin.end(true);
+ var text = "";
+ var reader = proc.stdout.getReader();
+ var done = false;
+ while (!done) {
+ var { value, done } = await reader.read();
+ if (value) text += new TextDecoder().decode(value);
+ if (done && text.length === 0) {
+ reader.releaseLock();
+ reader = proc.stdout.getReader();
+ done = false;
+ }
+ }
+
+ expect(text.trim().length).toBe(hugeString.length);
+ expect(text.trim()).toBe(hugeString);
+ gcTick();
+ await proc.exited;
});
- }
-
- const fixtures = [
- [helloWorld, "hello"],
- [huge, hugeString],
- ];
-
- for (const [callback, fixture] of fixtures) {
- describe(fixture.slice(0, 12), () => {
- describe("should should allow reading stdout", () => {
- it("before exit", async () => {
- const process = callback();
- const output = await readableStreamToText(process.stdout);
- const expected = fixture + "\n";
- expect(output.length).toBe(expected.length);
- expect(output).toBe(expected);
-
- await process.exited;
- });
- it("before exit (chunked)", async () => {
- const process = callback();
- var output = "";
- var reader = process.stdout.getReader();
- var done = false;
- while (!done) {
- var { value, done } = await reader.read();
- if (value) output += new TextDecoder().decode(value);
- }
-
- const expected = fixture + "\n";
- expect(output.length).toBe(expected.length);
- expect(output).toBe(expected);
-
- await process.exited;
+ describe("pipe", () => {
+ function huge() {
+ return spawn({
+ cmd: ["echo", hugeString],
+ stdout: "pipe",
+ stdin: "pipe",
+ stderr: "inherit",
});
+ }
- it("after exit", async () => {
- const process = callback();
- await process.stdin.end();
-
- const output = await readableStreamToText(process.stdout);
- const expected = fixture + "\n";
-
- expect(output.length).toBe(expected.length);
- expect(output).toBe(expected);
-
- await process.exited;
+ function helloWorld() {
+ return spawn({
+ cmd: ["echo", "hello"],
+ stdout: "pipe",
+ stdin: "pipe",
});
- });
+ }
+
+ const fixtures = [
+ [helloWorld, "hello"],
+ [huge, hugeString],
+ ];
+
+ for (const [callback, fixture] of fixtures) {
+ describe(fixture.slice(0, 12), () => {
+ describe("should should allow reading stdout", () => {
+ it("before exit", async () => {
+ const process = callback();
+ const output = await readableStreamToText(process.stdout);
+ const expected = fixture + "\n";
+ expect(output.length).toBe(expected.length);
+ expect(output).toBe(expected);
+
+ await process.exited;
+ });
+
+ it("before exit (chunked)", async () => {
+ const process = callback();
+ var output = "";
+ var reader = process.stdout.getReader();
+ var done = false;
+ while (!done) {
+ var { value, done } = await reader.read();
+ if (value) output += new TextDecoder().decode(value);
+ }
+
+ const expected = fixture + "\n";
+ expect(output.length).toBe(expected.length);
+ expect(output).toBe(expected);
+
+ await process.exited;
+ });
+
+ it("after exit", async () => {
+ const process = callback();
+ await process.stdin.end();
+
+ const output = await readableStreamToText(process.stdout);
+ const expected = fixture + "\n";
+
+ expect(output.length).toBe(expected.length);
+ expect(output).toBe(expected);
+
+ await process.exited;
+ });
+ });
+ });
+ }
});
- }
+ });
});
-});
+}