Skip to content

Commit

Permalink
Enable Bun E2E tests (#971)
Browse files Browse the repository at this point in the history
  • Loading branch information
ardatan authored Nov 27, 2023
1 parent 1e3b128 commit b9433d3
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 31 deletions.
18 changes: 16 additions & 2 deletions .github/workflows/deployment-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@ jobs:
strategy:
fail-fast: false
matrix:
plan: ['aws-lambda', 'azure-function', 'cloudflare-workers', 'cloudflare-modules', 'deno']
plan:
[
'aws-lambda',
'azure-function',
'cloudflare-workers',
'cloudflare-modules',
'deno',
'bun',
]
# TODO: Add vercel
name: e2e / ${{ matrix.plan }}

Expand All @@ -28,10 +36,16 @@ jobs:
- name: Install Required Libraries
run: sudo apt update && sudo apt install -y libcurl4-openssl-dev libssl-dev

- uses: denoland/setup-deno@v1
- name: Use Deno
if: matrix.plan == 'deno'
uses: denoland/setup-deno@v1
with:
deno-version: vx.x.x

- name: Use Bun
if: matrix.plan == 'bun'
uses: oven-sh/setup-bun@v1

- name: Cache Node Modules
uses: actions/cache@v3
id: node-modules-cache-deployment-e2e
Expand Down
5 changes: 3 additions & 2 deletions e2e/bun/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
"version": "0.0.74",
"private": true,
"scripts": {
"e2e": "bun wiptest",
"e2e": "bun test",
"start": "bun src/index.ts"
},
"dependencies": {
"@e2e/shared-server": "0.0.74",
"bun-types": "^1.0.0"
"@types/node": "20.10.0",
"bun-types": "1.0.14"
},
"devDependencies": {
"typescript": "5.3.2"
Expand Down
2 changes: 1 addition & 1 deletion e2e/bun/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { createTestServerAdapter } from '@e2e/shared-server';
import { createTestServerAdapter } from '../../shared-server/src/index';

Bun.serve(createTestServerAdapter());
44 changes: 22 additions & 22 deletions e2e/bun/tests/bun.spec.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
import { Server } from 'bun';
import { describe, it } from 'bun:test';
import { assertDeployedEndpoint } from '@e2e/shared-scripts';
import { createTestServerAdapter } from '@e2e/shared-server';

let server: Server;
let url: string;
function beforeEach() {
server = Bun.serve({
fetch: createTestServerAdapter(),
port: 3000,
});
url = `http://${server.hostname}:${server.port}`;
}

function afterEach() {
server.stop();
}
import { createServer } from 'node:http';
import { describe, expect, it } from 'bun:test';
import { assertDeployedEndpoint } from '../../shared-scripts/src/index';
import { createTestServerAdapter } from '../../shared-server/src/index';

describe('Bun', () => {
it('works', async () => {
beforeEach();
const server = Bun.serve({
fetch: createTestServerAdapter(),
port: 3000,
});
try {
await assertDeployedEndpoint(`http://localhost:3000/graphql`);
} catch (e) {
expect(e).toBeUndefined();
}
server.stop(true);
});
it('works with Node compat mode', async () => {
const server = createServer(createTestServerAdapter());
await new Promise<void>(resolve => server.listen(3000, resolve));
try {
await assertDeployedEndpoint(url);
} finally {
afterEach();
await assertDeployedEndpoint(`http://localhost:3000/graphql`);
} catch (e) {
expect(e).toBeUndefined();
}
return new Promise(resolve => server.close(resolve));
});
});
55 changes: 51 additions & 4 deletions packages/server/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ export class ServerAdapterRequestAbortSignal extends EventTarget implements Abor
}
}

let bunNodeCompatModeWarned = false;

export function normalizeNodeRequest(
nodeRequest: NodeRequest,
RequestCtor: typeof Request,
Expand All @@ -125,11 +127,24 @@ export function normalizeNodeRequest(
fullUrl = url.toString();
}

const signal = new ServerAdapterRequestAbortSignal();
let signal: AbortSignal;

// If ponyfilled
if (RequestCtor !== globalThis.Request) {
signal = new ServerAdapterRequestAbortSignal();

if (rawRequest.once) {
rawRequest.once('end', () => (signal as ServerAdapterRequestAbortSignal).sendAbort());
rawRequest.once('close', () => (signal as ServerAdapterRequestAbortSignal).sendAbort());
}
} else {
const controller = new AbortController();
signal = controller.signal;

if (rawRequest.once) {
rawRequest.once('end', () => signal.sendAbort());
rawRequest.once('close', () => signal.sendAbort());
if (rawRequest.once) {
rawRequest.once('end', () => controller.abort());
rawRequest.once('close', () => controller.abort());
}
}

if (nodeRequest.method === 'GET' || nodeRequest.method === 'HEAD') {
Expand Down Expand Up @@ -178,6 +193,38 @@ export function normalizeNodeRequest(
});
}

// Temporary workaround for a bug in Bun Node compat mode
if (globalThis.process?.versions?.bun && isReadable(rawRequest)) {
if (!bunNodeCompatModeWarned) {
bunNodeCompatModeWarned = true;
console.warn(
`You use Bun Node compatibility mode, which is not recommended!
It will affect your performance. Please check our Bun integration recipe, and avoid using 'node:http' for your server implementation.`,
);
}
return new RequestCtor(fullUrl, {
method: nodeRequest.method,
headers: nodeRequest.headers,
body: new ReadableStream({
start(controller) {
rawRequest.on('data', chunk => {
controller.enqueue(chunk);
});
rawRequest.on('error', e => {
controller.error(e);
});
rawRequest.on('end', () => {
controller.close();
});
},
cancel(e) {
rawRequest.destroy(e);
},
}),
signal,
});
}

// perf: instead of spreading the object, we can just pass it as is and it performs better
return new RequestCtor(fullUrl, {
method: nodeRequest.method,
Expand Down

0 comments on commit b9433d3

Please sign in to comment.