Files
bun.sh/test/js/node/http2/node-echo-server.fixture.js
robobun f83214e0a9 test(http2): refactor tests to use describe.concurrent and await using (#25893)
## Summary
- Use `describe.concurrent` at module scope for parallel test execution
across node/bun executables and padding strategies
- Replace `Bun.spawnSync` with async `Bun.spawn` in memory leak test
- Replace `beforeEach`/`afterEach` server setup with `await using` in
each test
- Add `Symbol.asyncDispose` to `nodeEchoServer` helper for proper
cleanup
- Fix IPv6/IPv4 binding issue by explicitly binding echo server to
127.0.0.1

## Test plan
- [x] Run `bun test test/js/node/http2/node-http2.test.js` - all 245
tests pass (6 skipped)
- [x] Verify tests run faster due to concurrent execution

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-07 23:15:50 -08:00

81 lines
2.5 KiB
JavaScript

const http2 = require("http2");
const fs = require("fs");
const paddingStrategy = process.argv[3];
const server = http2.createSecureServer({
...JSON.parse(process.argv[2]),
rejectUnauthorized: false,
paddingStrategy: paddingStrategy ?? http2.constants.PADDING_STRATEGY_NONE,
});
const setCookie = ["a=b", "c=d; Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly", "e=f"];
server.on("stream", (stream, headers, flags) => {
// errors here are not useful the test should handle on the client side
stream.on("error", err => console.error(err));
if (headers["x-wait-trailer"]) {
const response = { headers, flags };
stream.respond({
"content-type": "text/html",
":status": 200,
"set-cookie": setCookie,
});
stream.on("trailers", (headers, flags) => {
stream.end(JSON.stringify({ ...response, trailers: headers }));
});
} else if (headers["x-no-echo"]) {
let byteLength = 0;
stream.on("data", chunk => {
byteLength += chunk.length;
});
stream.respond({
"content-type": "application/json",
":status": 200,
});
stream.on("end", () => {
stream.end(JSON.stringify(byteLength));
});
} else {
// Store the request information, excluding pseudo-headers in the header echo
const requestData = {
method: headers[":method"],
path: headers[":path"],
headers: Object.fromEntries(Object.entries(headers).map(([key, value]) => [key.toLowerCase(), value])),
body: [],
url: `${baseurl}${headers[":path"]}`,
};
// Collect data from the stream
stream.on("data", chunk => {
requestData.body.push(chunk);
});
// Once all data is received, echo it back
stream.on("end", () => {
if (requestData.body.length > 0) {
requestData.data = Buffer.concat(requestData.body).toString();
try {
requestData.json = JSON.parse(requestData.data); // Convert buffer array to string
} catch (e) {}
}
stream.respond({
"content-type": "application/json",
":status": 200,
// Set security and cache-control headers
"cache-control": "no-store",
"x-content-type-options": "nosniff",
"set-cookie": setCookie,
});
stream.end(JSON.stringify(requestData));
});
}
});
let baseurl = "https://127.0.0.1:";
server.listen(0, "127.0.0.1");
server.on("listening", () => {
const { port, address, family } = server.address();
baseurl = `https://127.0.0.1:${port}`;
process.stdout.write(JSON.stringify({ port, address: "127.0.0.1", family: "IPv4" }));
});