mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 18:38:55 +00:00
116 lines
2.9 KiB
JavaScript
116 lines
2.9 KiB
JavaScript
import { expect, test } from "bun:test";
|
|
import { nodeExe, tempDirWithFiles } from "harness";
|
|
import net from "node:net";
|
|
|
|
async function nodeRun(callback, clients = 1) {
|
|
const cwd = tempDirWithFiles("server", {
|
|
"index.mjs": `
|
|
import net from "node:net";
|
|
let clients = ${clients};
|
|
const server = net.createServer({ allowHalfOpen: true }, socket => {
|
|
// Listen for data from the client
|
|
socket.on("data", data => {
|
|
console.log(data.toString());
|
|
});
|
|
|
|
socket.on("end", () => {
|
|
console.log("Received FIN");
|
|
if(--clients == 0) {
|
|
server.close();
|
|
}
|
|
});
|
|
socket.on("error", console.error);
|
|
|
|
// start sending FIN
|
|
socket.end();
|
|
});
|
|
server.listen(0, "127.0.0.1", ()=> {
|
|
console.log(server.address().port?.toString());
|
|
})
|
|
`,
|
|
});
|
|
const process = Bun.spawn([nodeExe(), "index.mjs"], {
|
|
cwd,
|
|
stdin: "ignore",
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const reader = process.stdout.getReader();
|
|
let continueReading = true;
|
|
let stdout = "";
|
|
let port = 0;
|
|
do {
|
|
const { done, value } = await reader.read();
|
|
|
|
continueReading = !done;
|
|
const decoder = new TextDecoder();
|
|
if (value) {
|
|
if (!port) {
|
|
port = parseInt(decoder.decode(value), 10);
|
|
callback(port);
|
|
} else {
|
|
stdout += decoder.decode(value);
|
|
}
|
|
}
|
|
} while (continueReading);
|
|
|
|
return {
|
|
stdout,
|
|
stderr: (await Bun.readableStreamToText(process.stderr)).trim(),
|
|
code: await process.exited,
|
|
};
|
|
}
|
|
|
|
async function doHalfOpenRequest(port, allowHalfOpen) {
|
|
const { promise, resolve, reject } = Promise.withResolvers();
|
|
|
|
const client = net.connect({ host: "127.0.0.1", port, allowHalfOpen }, () => {
|
|
client.write("Hello, World");
|
|
});
|
|
client.on("error", reject);
|
|
client.on("close", resolve);
|
|
client.on("end", () => {
|
|
// delay the write response
|
|
setTimeout(() => {
|
|
client.write("Write after end");
|
|
client.end();
|
|
}, 10);
|
|
});
|
|
await promise;
|
|
}
|
|
|
|
test("allowHalfOpen: true should work on client-side", async () => {
|
|
const { promise: portPromise, resolve } = Promise.withResolvers();
|
|
const process = nodeRun(resolve, 1);
|
|
|
|
const port = await portPromise;
|
|
await doHalfOpenRequest(port, true);
|
|
const result = await process;
|
|
expect(result.code).toBe(0);
|
|
expect(result.stderr).toBe("");
|
|
expect(
|
|
result.stdout
|
|
.split("\n")
|
|
.map(s => s.trim())
|
|
.filter(s => s),
|
|
).toEqual(["Hello, World", "Write after end", "Received FIN"]);
|
|
});
|
|
|
|
test("allowHalfOpen: false should work on client-side", async () => {
|
|
const { promise: portPromise, resolve } = Promise.withResolvers();
|
|
const process = nodeRun(resolve, 1);
|
|
|
|
const port = await portPromise;
|
|
await doHalfOpenRequest(port, false);
|
|
const result = await process;
|
|
expect(result.code).toBe(0);
|
|
expect(result.stderr).toBe("");
|
|
expect(
|
|
result.stdout
|
|
.split("\n")
|
|
.map(s => s.trim())
|
|
.filter(s => s),
|
|
).toEqual(["Hello, World", "Received FIN"]);
|
|
});
|