Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add test helper for closing server as promise #2604

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion test/fetch/407-statuscode-window-null.js
Original file line number Diff line number Diff line change
@@ -6,13 +6,15 @@ const { once } = require('events')
const { test } = require('node:test')
const assert = require('node:assert')

const { closeServerAsPromise } = require('../utils/node-http')

test('Receiving a 407 status code w/ a window option present should reject', async (t) => {
const server = createServer((req, res) => {
res.statusCode = 407
res.end()
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

// if init.window exists, the spec tells us to set request.window to 'no-window',
6 changes: 4 additions & 2 deletions test/fetch/abort.js
Original file line number Diff line number Diff line change
@@ -7,6 +7,8 @@ const { fetch } = require('../..')
const { createServer } = require('http')
const { once } = require('events')

const { closeServerAsPromise } = require('../utils/node-http')

const { AbortController: NPMAbortController } = require('abort-controller')

test('Allow the usage of custom implementation of AbortController', async (t) => {
@@ -19,7 +21,7 @@ test('Allow the usage of custom implementation of AbortController', async (t) =>
res.end(JSON.stringify(body))
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0)
await once(server, 'listening')
@@ -40,7 +42,7 @@ test('Allow the usage of custom implementation of AbortController', async (t) =>
test('allows aborting with custom errors', async (t) => {
const server = createServer().listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

await t.test('Using AbortSignal.timeout with cause', async () => {
4 changes: 3 additions & 1 deletion test/fetch/abort2.js
Original file line number Diff line number Diff line change
@@ -6,6 +6,8 @@ const { fetch } = require('../..')
const { createServer } = require('http')
const { once } = require('events')

const { closeServerAsPromise } = require('../utils/node-http')

/* global AbortController */

test('parallel fetch with the same AbortController works as expected', async (t) => {
@@ -19,7 +21,7 @@ test('parallel fetch with the same AbortController works as expected', async (t)
res.end(JSON.stringify(body))
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

const abortController = new AbortController()

56 changes: 28 additions & 28 deletions test/fetch/client-fetch.js
Original file line number Diff line number Diff line change
@@ -15,6 +15,8 @@ const { gzipSync } = require('zlib')
const { promisify } = require('util')
const { randomFillSync, createHash } = require('crypto')

const { closeServerAsPromise } = require('../utils/node-http')

setGlobalDispatcher(new Agent({
keepAliveTimeout: 1,
keepAliveMaxTimeout: 1
@@ -41,7 +43,7 @@ test('request json', (t, done) => {
const server = createServer((req, res) => {
res.end(JSON.stringify(obj))
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const body = await fetch(`http://localhost:${server.address().port}`)
@@ -57,7 +59,7 @@ test('request text', (t, done) => {
const server = createServer((req, res) => {
res.end(JSON.stringify(obj))
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const body = await fetch(`http://localhost:${server.address().port}`)
@@ -73,7 +75,7 @@ test('request arrayBuffer', (t, done) => {
const server = createServer((req, res) => {
res.end(JSON.stringify(obj))
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const body = await fetch(`http://localhost:${server.address().port}`)
@@ -90,7 +92,7 @@ test('should set type of blob object to the value of the `Content-Type` header f
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify(obj))
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const response = await fetch(`http://localhost:${server.address().port}`)
@@ -104,7 +106,7 @@ test('pre aborted with readable request body', (t, done) => {

const server = createServer((req, res) => {
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const ac = new AbortController()
@@ -129,7 +131,7 @@ test('pre aborted with closed readable request body', (t, done) => {

const server = createServer((req, res) => {
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const ac = new AbortController()
@@ -163,7 +165,7 @@ test('unsupported formData 1', (t, done) => {
res.setHeader('content-type', 'asdasdsad')
res.end()
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
fetch(`http://localhost:${server.address().port}`)
@@ -193,7 +195,7 @@ test('multipart formdata not base64', async (t) => {
res.write(formRaw)
res.end()
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

const listen = promisify(server.listen.bind(server))
await listen(0)
@@ -221,7 +223,7 @@ test('multipart formdata base64', (t, done) => {
}
res.end()
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
fetch(`http://localhost:${server.address().port}`)
@@ -268,7 +270,7 @@ test('busboy emit error', async (t) => {
res.write(formRaw)
res.end()
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

const listen = promisify(server.listen.bind(server))
await listen(0)
@@ -296,7 +298,7 @@ test('urlencoded formData', (t, done) => {
res.setHeader('content-type', 'application/x-www-form-urlencoded')
res.end('field1=value1&field2=value2')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
fetch(`http://localhost:${server.address().port}`)
@@ -316,7 +318,7 @@ test('text with BOM', (t, done) => {
res.setHeader('content-type', 'application/x-www-form-urlencoded')
res.end('\uFEFFtest=\uFEFF')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
fetch(`http://localhost:${server.address().port}`)
@@ -335,7 +337,7 @@ test('formData with BOM', (t, done) => {
res.setHeader('content-type', 'application/x-www-form-urlencoded')
res.end('\uFEFFtest=\uFEFF')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
fetch(`http://localhost:${server.address().port}`)
@@ -353,7 +355,7 @@ test('locked blob body', (t, done) => {
const server = createServer((req, res) => {
res.end()
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const res = await fetch(`http://localhost:${server.address().port}`)
@@ -371,7 +373,7 @@ test('disturbed blob body', (t, done) => {
const server = createServer((req, res) => {
res.end()
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const res = await fetch(`http://localhost:${server.address().port}`)
@@ -403,7 +405,7 @@ test('redirect with body', (t, done) => {
res.end(String(count))
}
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const res = await fetch(`http://localhost:${server.address().port}`, {
@@ -431,7 +433,7 @@ test('redirect with stream', (t, done) => {
}
}, 50)
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const res = await fetch(`http://localhost:${server.address().port}`, {
@@ -485,7 +487,7 @@ test('post FormData with Blob', (t, done) => {
const server = createServer((req, res) => {
req.pipe(res)
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const res = await fetch(`http://localhost:${server.address().port}`, {
@@ -506,7 +508,7 @@ test('post FormData with File', (t, done) => {
const server = createServer((req, res) => {
req.pipe(res)
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const res = await fetch(`http://localhost:${server.address().port}`, {
@@ -537,7 +539,7 @@ test('custom agent', (t, done) => {
const server = createServer((req, res) => {
res.end(JSON.stringify(obj))
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const dispatcher = new Client('http://localhost:' + server.address().port, {
@@ -549,7 +551,6 @@ test('custom agent', (t, done) => {
ok(true)
return oldDispatch.call(this, options, handler)
}
t.after(server.close.bind(server))
const body = await fetch(`http://localhost:${server.address().port}`, {
dispatcher
})
@@ -565,7 +566,7 @@ test('custom agent node fetch', (t, done) => {
const server = createServer((req, res) => {
res.end(JSON.stringify(obj))
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const dispatcher = new Client('http://localhost:' + server.address().port, {
@@ -577,7 +578,6 @@ test('custom agent node fetch', (t, done) => {
ok(true)
return oldDispatch.call(this, options, handler)
}
t.after(server.close.bind(server))
const body = await nodeFetch.fetch(`http://localhost:${server.address().port}`, {
dispatcher
})
@@ -591,7 +591,7 @@ test('error on redirect', (t, done) => {
res.statusCode = 302
res.end()
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const errorCause = await fetch(`http://localhost:${server.address().port}`, {
@@ -610,7 +610,7 @@ test('fetching with Request object - issue #1527', async (t) => {
res.end()
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

const body = JSON.stringify({ foo: 'bar' })
@@ -641,7 +641,7 @@ test('do not decode redirect body', (t, done) => {
res.setHeader('content-encoding', 'gzip')
res.end(gzipSync(JSON.stringify(obj)))
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const body = await fetch(`http://localhost:${server.address().port}/resource`)
@@ -661,7 +661,7 @@ test('decode non-redirect body with location header', (t, done) => {
res.setHeader('content-encoding', 'gzip')
res.end(gzipSync(JSON.stringify(obj)))
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const body = await fetch(`http://localhost:${server.address().port}/resource`)
@@ -687,7 +687,7 @@ test('Receiving non-Latin1 headers', async (t) => {
res.end()
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

const url = `http://localhost:${server.address().port}`
3 changes: 2 additions & 1 deletion test/fetch/content-length.js
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ const { createServer } = require('http')
const { once } = require('events')
const { Blob } = require('buffer')
const { fetch, FormData } = require('../..')
const { closeServerAsPromise } = require('../utils/node-http')

// https://github.com/nodejs/undici/issues/1783
test('Content-Length is set when using a FormData body with fetch', async (t) => {
@@ -17,7 +18,7 @@ test('Content-Length is set when using a FormData body with fetch', async (t) =>
}).listen(0)

await once(server, 'listening')
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

const fd = new FormData()
fd.set('file', new Blob(['hello world 👋'], { type: 'text/plain' }), 'readme.md')
7 changes: 4 additions & 3 deletions test/fetch/cookies.js
Original file line number Diff line number Diff line change
@@ -6,14 +6,15 @@ const { test } = require('node:test')
const assert = require('node:assert')
const { tspl } = require('@matteo.collina/tspl')
const { fetch, Headers } = require('../..')
const { closeServerAsPromise } = require('../utils/node-http')

test('Can receive set-cookie headers from a server using fetch - issue #1262', async (t) => {
const server = createServer((req, res) => {
res.setHeader('set-cookie', 'name=value; Domain=example.com')
res.end()
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

const response = await fetch(`http://localhost:${server.address().port}`)
@@ -33,7 +34,7 @@ test('Can send cookies to a server with fetch - issue #1463', async (t) => {
res.end()
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

const headersInit = [
@@ -55,7 +56,7 @@ test('Cookie header is delimited with a semicolon rather than a comma - issue #1
res.end()
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

await fetch(`http://localhost:${server.address().port}`, {
5 changes: 3 additions & 2 deletions test/fetch/encoding.js
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ const { createServer } = require('http')
const { once } = require('events')
const { fetch } = require('../..')
const { createBrotliCompress, createGzip, createDeflate } = require('zlib')
const { closeServerAsPromise } = require('../utils/node-http')

test('content-encoding header is case-iNsENsITIve', async (t) => {
const contentCodings = 'GZiP, bR'
@@ -24,7 +25,7 @@ test('content-encoding header is case-iNsENsITIve', async (t) => {
brotli.end()
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

const response = await fetch(`http://localhost:${server.address().port}`)
@@ -50,7 +51,7 @@ test('response decompression according to content-encoding should be handled in
gzip.end()
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

const response = await fetch(`http://localhost:${server.address().port}`)
3 changes: 2 additions & 1 deletion test/fetch/fetch-leak.js
Original file line number Diff line number Diff line change
@@ -5,13 +5,14 @@ const assert = require('node:assert')
const { tspl } = require('@matteo.collina/tspl')
const { fetch } = require('../..')
const { createServer } = require('http')
const { closeServerAsPromise } = require('../utils/node-http')

test('do not leak', (t, done) => {
const { ok } = tspl(t, { plan: 1 })
const server = createServer((req, res) => {
res.end()
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

let url
let isDone = false
3 changes: 2 additions & 1 deletion test/fetch/fetch-timeouts.js
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ const { fetch, Agent } = require('../..')
const timers = require('../../lib/timers')
const { createServer } = require('http')
const FakeTimers = require('@sinonjs/fake-timers')
const { closeServerAsPromise } = require('../utils/node-http')

test('Fetch very long request, timeout overridden so no error', (t, done) => {
const minutes = 6
@@ -29,7 +30,7 @@ test('Fetch very long request, timeout overridden so no error', (t, done) => {
}, msToDelay)
clock.tick(msToDelay + 1)
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
fetch(`http://localhost:${server.address().port}`, {
3 changes: 2 additions & 1 deletion test/fetch/headers.js
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ const { kGuard } = require('../../lib/fetch/symbols')
const { once } = require('events')
const { fetch } = require('../..')
const { createServer } = require('http')
const { closeServerAsPromise } = require('../utils/node-http')

test('Headers initialization', async (t) => {
await t.test('allows undefined', () => {
@@ -685,7 +686,7 @@ test('Headers.prototype.getSetCookie', async (t) => {
}).listen(0)

await once(server, 'listening')
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

const res = await fetch(`http://localhost:${server.address().port}`)
const entries = Object.fromEntries(res.headers.entries())
26 changes: 10 additions & 16 deletions test/fetch/http2.js
Original file line number Diff line number Diff line change
@@ -12,6 +12,8 @@ const pem = require('https-pem')

const { Client, fetch, Headers } = require('../..')

const { closeClientAndServerAsPromise } = require('../utils/node-http')

const nodeVersion = Number(process.version.split('v')[1].split('.')[0])

test('[Fetch] Issue#2311', async (t) => {
@@ -62,8 +64,7 @@ test('[Fetch] Issue#2311', async (t) => {

const responseBody = await response.text()

t.after(server.close.bind(server))
t.after(() => client.close())
t.after(closeClientAndServerAsPromise(client, server))

strictEqual(responseBody, expectedBody)
})
@@ -110,8 +111,7 @@ test('[Fetch] Simple GET with h2', async (t) => {

const responseBody = await response.text()

t.after(server.close.bind(server))
t.after(() => client.close())
t.after(closeClientAndServerAsPromise(client, server))

strictEqual(responseBody, expectedRequestBody)
strictEqual(response.headers.get('x-method'), 'GET')
@@ -171,8 +171,7 @@ test('[Fetch] Should handle h2 request with body (string or buffer)', async (t)

const responseBody = await response.text()

t.after(server.close.bind(server))
t.after(() => client.close())
t.after(closeClientAndServerAsPromise(client, server))

strictEqual(Buffer.concat(requestBody).toString('utf-8'), expectedBody)
strictEqual(responseBody, expectedRequestBody)
@@ -218,8 +217,7 @@ test(
allowH2: true
})

t.after(server.close.bind(server))
t.after(() => client.close())
t.after(closeClientAndServerAsPromise(client, server))

const response = await fetch(
`https://localhost:${server.address().port}/`,
@@ -281,8 +279,7 @@ test('Should handle h2 request with body (Blob)', { skip: !Blob }, async (t) =>
allowH2: true
})

t.after(server.close.bind(server))
t.after(() => client.close())
t.after(closeClientAndServerAsPromise(client, server))

const response = await fetch(
`https://localhost:${server.address().port}/`,
@@ -348,8 +345,7 @@ test(
allowH2: true
})

t.after(server.close.bind(server))
t.after(() => client.close())
t.after(closeClientAndServerAsPromise(client, server))

const response = await fetch(
`https://localhost:${server.address().port}/`,
@@ -407,8 +403,7 @@ test('Issue#2415', async (t) => {

await response.text()

t.after(server.close.bind(server))
t.after(() => client.close())
t.after(closeClientAndServerAsPromise(client, server))

doesNotThrow(() => new Headers(response.headers))
})
@@ -449,8 +444,7 @@ test('Issue #2386', async (t) => {
allowH2: true
})

t.after(server.close.bind(server))
t.after(() => client.close())
t.after(closeClientAndServerAsPromise(client, server))

await fetch(
`https://localhost:${server.address().port}/`,
15 changes: 8 additions & 7 deletions test/fetch/integrity.js
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ const { createHash, getHashes } = require('crypto')
const { gzipSync } = require('zlib')
const { fetch, setGlobalDispatcher, Agent } = require('../..')
const { once } = require('events')
const { closeServerAsPromise } = require('../utils/node-http')

const supportedHashes = getHashes()

@@ -23,7 +24,7 @@ test('request with correct integrity checksum', (t, done) => {
res.end(body)
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const response = await fetch(`http://localhost:${server.address().port}`, {
@@ -42,7 +43,7 @@ test('request with wrong integrity checksum', async (t) => {
res.end(body)
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

const expectedError = new TypeError('fetch failed', {
@@ -63,7 +64,7 @@ test('request with integrity checksum on encoded body', (t, done) => {
res.end(gzipSync(body))
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const response = await fetch(`http://localhost:${server.address().port}`, {
@@ -79,7 +80,7 @@ test('request with a totally incorrect integrity', async (t) => {
res.end()
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

await assert.doesNotReject(fetch(`http://localhost:${server.address().port}`, {
@@ -95,7 +96,7 @@ test('request with mixed in/valid integrities', async (t) => {
res.end(body)
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

await assert.doesNotReject(fetch(`http://localhost:${server.address().port}`, {
@@ -111,7 +112,7 @@ test('request with sha384 hash', { skip: !supportedHashes.includes('sha384') },
res.end(body)
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

// request should succeed
@@ -133,7 +134,7 @@ test('request with sha512 hash', { skip: !supportedHashes.includes('sha512') },
res.end(body)
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

// request should succeed
3 changes: 2 additions & 1 deletion test/fetch/issue-2009.js
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ const { tspl } = require('@matteo.collina/tspl')
const { fetch } = require('../..')
const { createServer } = require('http')
const { once } = require('events')
const { closeServerAsPromise } = require('../utils/node-http')

test('issue 2009', async (t) => {
const { doesNotReject } = tspl(t, { plan: 10 })
@@ -16,7 +17,7 @@ test('issue 2009', async (t) => {
res.socket.end()
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

for (let i = 0; i < 10; i++) {
3 changes: 2 additions & 1 deletion test/fetch/issue-2021.js
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ const assert = require('node:assert')
const { once } = require('events')
const { createServer } = require('http')
const { fetch } = require('../..')
const { closeServerAsPromise } = require('../utils/node-http')

// https://github.com/nodejs/undici/issues/2021
test('content-length header is removed on redirect', async (t) => {
@@ -18,7 +19,7 @@ test('content-length header is removed on redirect', async (t) => {
res.end()
}).listen(0).unref()

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

const body = 'a+b+c'
3 changes: 2 additions & 1 deletion test/fetch/issue-2171.js
Original file line number Diff line number Diff line change
@@ -5,11 +5,12 @@ const { once } = require('events')
const { createServer } = require('http')
const { test } = require('node:test')
const assert = require('node:assert')
const { closeServerAsPromise } = require('../utils/node-http')

test('error reason is forwarded - issue #2171', { skip: !AbortSignal.timeout }, async (t) => {
const server = createServer(() => {}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

const timeout = AbortSignal.timeout(100)
3 changes: 2 additions & 1 deletion test/fetch/issue-2318.js
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ const { tspl } = require('@matteo.collina/tspl')
const { once } = require('events')
const { createServer } = require('http')
const { fetch } = require('../..')
const { closeServerAsPromise } = require('../utils/node-http')

test('Undici overrides user-provided `Host` header', async (t) => {
const { strictEqual } = tspl(t, { plan: 1 })
@@ -15,7 +16,7 @@ test('Undici overrides user-provided `Host` header', async (t) => {
res.end()
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

await fetch(`http://localhost:${server.address().port}`, {
7 changes: 4 additions & 3 deletions test/fetch/redirect.js
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ const assert = require('node:assert')
const { createServer } = require('http')
const { once } = require('events')
const { fetch } = require('../..')
const { closeServerAsPromise } = require('../utils/node-http')

// https://github.com/nodejs/undici/issues/1776
test('Redirecting with a body does not cancel the current request - #1776', async (t) => {
@@ -21,7 +22,7 @@ test('Redirecting with a body does not cancel the current request - #1776', asyn
res.end()
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

const resp = await fetch(`http://localhost:${server.address().port}/redirect`)
@@ -42,7 +43,7 @@ test('Redirecting with an empty body does not throw an error - #2027', async (t)
res.end()
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

const resp = await fetch(`http://localhost:${server.address().port}/redirect`, { method: 'PUT', body: '' })
@@ -65,7 +66,7 @@ test('Redirecting with a body does not fail to write body - #2543', async (t) =>
}
}).listen(0)

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

const resp = await fetch(`http://localhost:${server.address().port}/redirect`, {
5 changes: 3 additions & 2 deletions test/fetch/relative-url.js
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ const {
Request,
fetch
} = require('../..')
const { closeServerAsPromise } = require('../utils/node-http')

afterEach(() => setGlobalOrigin(undefined))

@@ -80,7 +81,7 @@ test('fetch', async (t) => {
}).listen(0)

setGlobalOrigin(`http://localhost:${server.address().port}`)
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

await assert.doesNotReject(fetch('/relative/path'))
@@ -93,7 +94,7 @@ test('fetch', async (t) => {
}).listen(0)

setGlobalOrigin(`http://localhost:${server.address().port}`)
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
await once(server, 'listening')

const response = await fetch('/relative/path')
9 changes: 5 additions & 4 deletions test/fetch/resource-timing.js
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ const { tspl } = require('@matteo.collina/tspl')
const { createServer } = require('http')
const { nodeMajor, nodeMinor } = require('../../lib/core/util')
const { fetch } = require('../..')
const { closeServerAsPromise } = require('../utils/node-http')

const {
PerformanceObserver,
@@ -46,7 +47,7 @@ test('should create a PerformanceResourceTiming after each fetch request', { ski
strictEqual('ok', await body.text())
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
})

test('should include encodedBodySize in performance entry', { skip }, (t, done) => {
@@ -71,7 +72,7 @@ test('should include encodedBodySize in performance entry', { skip }, (t, done)
strictEqual('ok', await body.text())
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
})

test('timing entries should be in order', { skip }, (t, done) => {
@@ -107,7 +108,7 @@ test('timing entries should be in order', { skip }, (t, done) => {
strictEqual('ok', await body.text())
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
})

test('redirect timing entries should be included when redirecting', { skip }, (t, done) => {
@@ -139,5 +140,5 @@ test('redirect timing entries should be included when redirecting', { skip }, (t
strictEqual('ok', await body.text())
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))
})
3 changes: 2 additions & 1 deletion test/fetch/user-agent.js
Original file line number Diff line number Diff line change
@@ -5,14 +5,15 @@ const assert = require('assert')
const events = require('events')
const http = require('http')
const undici = require('../../')
const { closeServerAsPromise } = require('../utils/node-http')

const nodeBuild = require('../../undici-fetch.js')

test('user-agent defaults correctly', async (t) => {
const server = http.createServer((req, res) => {
res.end(JSON.stringify({ userAgentHeader: req.headers['user-agent'] }))
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0)
await events.once(server, 'listening')
17 changes: 9 additions & 8 deletions test/node-test/abort-controller.js
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ const { createServer } = require('http')
const { createReadStream } = require('fs')
const { wrapWithAsyncIterable } = require('../utils/async-iterators')
const { tspl } = require('@matteo.collina/tspl')
const { closeServerAsPromise } = require('../utils/node-http')

const controllers = [{
AbortControllerImpl: NPMAbortController,
@@ -26,7 +27,7 @@ for (const { AbortControllerImpl, controllerName } of controllers) {
const server = createServer((req, res) => {
p.fail()
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
@@ -54,7 +55,7 @@ for (const { AbortControllerImpl, controllerName } of controllers) {
count += 1
res.end('hello')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
@@ -91,7 +92,7 @@ for (const { AbortControllerImpl, controllerName } of controllers) {
res.setHeader('content-type', 'text/plain')
res.end('hello world')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
@@ -115,7 +116,7 @@ for (const { AbortControllerImpl, controllerName } of controllers) {
abortController.abort()
res.end('hello world')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
@@ -137,7 +138,7 @@ for (const { AbortControllerImpl, controllerName } of controllers) {
res.writeHead(200, { 'content-type': 'text/plain' })
res.write('hello')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
@@ -167,7 +168,7 @@ for (const { AbortControllerImpl, controllerName } of controllers) {
res.setHeader('content-type', 'text/plain')
res.end('hello world')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
@@ -197,7 +198,7 @@ for (const { AbortControllerImpl, controllerName } of controllers) {
abortController.abort()
res.end('hello world')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
@@ -225,7 +226,7 @@ for (const { AbortControllerImpl, controllerName } of controllers) {
res.writeHead(200, { 'content-type': 'text/plain' })
res.write('hello')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
17 changes: 9 additions & 8 deletions test/node-test/abort-event-emitter.js
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ const { createReadStream } = require('fs')
const { Readable } = require('stream')
const { tspl } = require('@matteo.collina/tspl')
const { wrapWithAsyncIterable } = require('../utils/async-iterators')
const { closeServerAsPromise } = require('../utils/node-http')

test('Abort before sending request (no body)', async (t) => {
const p = tspl(t, { plan: 4 })
@@ -21,7 +22,7 @@ test('Abort before sending request (no body)', async (t) => {
res.end('hello')
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
@@ -70,7 +71,7 @@ test('Abort before sending request (no body) async iterator', async (t) => {
res.end('hello')
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
@@ -113,7 +114,7 @@ test('Abort while waiting response (no body)', async (t) => {
res.setHeader('content-type', 'text/plain')
res.end('hello world')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
@@ -137,7 +138,7 @@ test('Abort while waiting response (write headers started) (no body)', async (t)
ee.emit('abort')
res.end('hello world')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
@@ -159,7 +160,7 @@ test('Abort while waiting response (write headers and write body started) (no bo
res.writeHead(200, { 'content-type': 'text/plain' })
res.write('hello')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
@@ -188,7 +189,7 @@ function waitingWithBody (body, type) {
res.setHeader('content-type', 'text/plain')
res.end('hello world')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
@@ -218,7 +219,7 @@ function writeHeadersStartedWithBody (body, type) {
ee.emit('abort')
res.end('hello world')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
@@ -246,7 +247,7 @@ function writeBodyStartedWithBody (body, type) {
res.writeHead(200, { 'content-type': 'text/plain' })
res.write('hello')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
27 changes: 14 additions & 13 deletions test/node-test/agent.js
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ const {
} = require('../..')
const importFresh = require('import-fresh')
const { tspl } = require('@matteo.collina/tspl')
const { closeServerAsPromise } = require('../utils/node-http')

describe('setGlobalDispatcher', () => {
after(() => {
@@ -50,7 +51,7 @@ test('agent should call callback after closing internal pools', async (t) => {
res.end(wanted)
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const dispatcher = new Agent()
@@ -102,7 +103,7 @@ test('agent should close internal pools', async (t) => {
res.end(wanted)
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const dispatcher = new Agent()
@@ -143,7 +144,7 @@ test('agent should destroy internal pools and call callback', async (t) => {
res.end(wanted)
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const dispatcher = new Agent()
@@ -205,7 +206,7 @@ test('agent should destroy internal pools', async t => {
res.end(wanted)
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const dispatcher = new Agent()
@@ -246,7 +247,7 @@ test('multiple connections', async t => {
})
res.end('ok')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const origin = `http://localhost:${server.address().port}`
@@ -365,7 +366,7 @@ test('with globalAgent', async t => {
res.end(wanted)
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
request(`http://localhost:${server.address().port}`)
@@ -400,7 +401,7 @@ test('with local agent', async t => {
res.end(wanted)
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

const dispatcher = new Agent({
connect: {
@@ -451,7 +452,7 @@ test('with globalAgent', async t => {
res.end(wanted)
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
stream(
@@ -492,7 +493,7 @@ test('with a local agent', async t => {
res.end(wanted)
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

const dispatcher = new Agent()

@@ -552,7 +553,7 @@ test('with globalAgent', async t => {
res.end(wanted)
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const bufs = []
@@ -593,7 +594,7 @@ test('with a local agent', async t => {
res.end(wanted)
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

const dispatcher = new Agent()

@@ -734,7 +735,7 @@ test('drain', async t => {
res.end('asd')
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
p.strictEqual(dispatcher.dispatch({
@@ -761,7 +762,7 @@ test('global api', async t => {
req.pipe(res)
})

t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, async () => {
const origin = `http://localhost:${server.address().port}`
5 changes: 3 additions & 2 deletions test/node-test/async_hooks.js
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ const { createHook, executionAsyncId } = require('async_hooks')
const { readFile } = require('fs')
const { PassThrough } = require('stream')
const { tspl } = require('@matteo.collina/tspl')
const { closeServerAsPromise } = require('../utils/node-http')

const transactions = new Map()

@@ -154,7 +155,7 @@ test('async hooks client is destroyed', async (t) => {
res.write('asd')
})
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
@@ -189,7 +190,7 @@ test('async hooks pipeline handler', async (t) => {
const server = createServer((req, res) => {
res.end('hello')
})
t.after(server.close.bind(server))
t.after(closeServerAsPromise(server))

server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
6 changes: 3 additions & 3 deletions test/debug.js → test/node-test/debug.js
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

debug.js is using node:test so move to node-test

Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ test('debug#websocket', async t => {
const assert = tspl(t, { plan: 5 })
const child = spawn(
process.execPath,
[join(__dirname, 'fixtures/websocket.js')],
[join(__dirname, '../fixtures/websocket.js')],
{
env: {
NODE_DEBUG: 'websocket'
@@ -40,7 +40,7 @@ test('debug#fetch', async t => {
const assert = tspl(t, { plan: 10 })
const child = spawn(
process.execPath,
[join(__dirname, 'fixtures/fetch.js')],
[join(__dirname, '../fixtures/fetch.js')],
{
env: {
NODE_DEBUG: 'fetch'
@@ -67,7 +67,7 @@ test('debug#undici', async t => {
const assert = tspl(t, { plan: 10 })
const child = spawn(
process.execPath,
[join(__dirname, 'fixtures/undici.js')],
[join(__dirname, '../fixtures/undici.js')],
{
env: {
NODE_DEBUG: 'undici'
19 changes: 19 additions & 0 deletions test/utils/node-http.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const util = require('node:util')

function closeServerAsPromise (server) {
return () => util.promisify(server.close.bind(server))()
}

function closeClientAndServerAsPromise (client, server) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When testing http2 server/client, all sessions must be closed before closing the server. ref: https://nodejs.org/api/http2.html#serverclosecallback_1

const closeClient = util.promisify(client.close.bind(client))
const closeServer = util.promisify(server.close.bind(server))
return async () => {
await closeClient()
await closeServer()
}
}

module.exports = {
closeServerAsPromise,
closeClientAndServerAsPromise
}