From 00c7cd278dc71c3468dc911e3fad8759af90bdac Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Thu, 4 Jan 2024 01:28:46 +0900 Subject: [PATCH 01/11] `client-connect` --- test/{ => node-test}/client-connect.js | 162 ++++++++++++++----------- 1 file changed, 89 insertions(+), 73 deletions(-) rename test/{ => node-test}/client-connect.js (61%) diff --git a/test/client-connect.js b/test/node-test/client-connect.js similarity index 61% rename from test/client-connect.js rename to test/node-test/client-connect.js index 7c8ca5ee6e1..430e40a4bc5 100644 --- a/test/client-connect.js +++ b/test/node-test/client-connect.js @@ -1,16 +1,17 @@ 'use strict' -const { test } = require('tap') -const { Client, errors } = require('..') +const { test } = require('node:test') +const { Client, errors } = require('../..') const http = require('http') const EE = require('events') -const { kBusy } = require('../lib/core/symbols') +const { kBusy } = require('../../lib/core/symbols') +const { tspl } = require('@matteo.collina/tspl') -test('basic connect', (t) => { - t.plan(3) +test('basic connect', async (t) => { + const p = tspl(t, { plan: 3 }) const server = http.createServer((c) => { - t.fail() + p.ok(0) }) server.on('connect', (req, socket, firstBodyChunk) => { socket.write('HTTP/1.1 200 Connection established\r\n\r\n') @@ -24,20 +25,20 @@ test('basic connect', (t) => { socket.end(data) }) }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) const signal = new EE() const promise = client.connect({ signal, path: '/' }) - t.equal(signal.listenerCount('abort'), 1) + p.strictEqual(signal.listenerCount('abort'), 1) const { socket } = await promise - t.equal(signal.listenerCount('abort'), 0) + p.strictEqual(signal.listenerCount('abort'), 0) let recvData = '' socket.on('data', (d) => { @@ -45,68 +46,72 @@ test('basic connect', (t) => { }) socket.on('end', () => { - t.equal(recvData.toString(), 'Body') + p.strictEqual(recvData.toString(), 'Body') }) socket.write('Body') socket.end() }) + + await p.completed }) -test('connect error', (t) => { - t.plan(1) +test('connect error', async (t) => { + const p = tspl(t, { plan: 1 }) const server = http.createServer((c) => { - t.fail() + p.ok(0) }) server.on('connect', (req, socket, firstBodyChunk) => { socket.destroy() }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) try { await client.connect({ path: '/' }) } catch (err) { - t.ok(err) + p.ok(err) } }) + + await p.completed }) test('connect invalid opts', (t) => { - t.plan(6) + const p = tspl(t, { plan: 6 }) const client = new Client('http://localhost:5432') client.connect(null, err => { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid opts') + p.ok(err instanceof errors.InvalidArgumentError) + p.strictEqual(err.message, 'invalid opts') }) try { client.connect(null, null) - t.fail() + p.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid opts') + p.ok(err instanceof errors.InvalidArgumentError) + p.strictEqual(err.message, 'invalid opts') } try { client.connect({ path: '/' }, null) - t.fail() + p.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid callback') + p.ok(err instanceof errors.InvalidArgumentError) + p.strictEqual(err.message, 'invalid callback') } }) -test('connect wait for empty pipeline', (t) => { - t.plan(7) +test('connect wait for empty pipeline', async (t) => { + const p = tspl(t, { plan: 7 }) let canConnect = false const server = http.createServer((req, res) => { @@ -114,7 +119,7 @@ test('connect wait for empty pipeline', (t) => { canConnect = true }) server.on('connect', (req, socket, firstBodyChunk) => { - t.equal(canConnect, true) + p.strictEqual(canConnect, true) socket.write('HTTP/1.1 200 Connection established\r\n\r\n') let data = firstBodyChunk.toString() @@ -126,69 +131,72 @@ test('connect wait for empty pipeline', (t) => { socket.end(data) }) }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 3 }) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) client.request({ path: '/', method: 'GET' }, (err) => { - t.error(err) + p.ifError(err) }) client.once('connect', () => { process.nextTick(() => { - t.equal(client[kBusy], false) + p.strictEqual(client[kBusy], false) client.connect({ path: '/' }, (err, { socket }) => { - t.error(err) + p.ifError(err) let recvData = '' socket.on('data', (d) => { recvData += d }) socket.on('end', () => { - t.equal(recvData.toString(), 'Body') + p.strictEqual(recvData.toString(), 'Body') }) socket.write('Body') socket.end() }) - t.equal(client[kBusy], true) + p.strictEqual(client[kBusy], true) client.request({ path: '/', method: 'GET' }, (err) => { - t.error(err) + p.ifError(err) }) }) }) }) + await p.completed }) -test('connect aborted', (t) => { - t.plan(6) +test('connect aborted', async (t) => { + const p = tspl(t, { plan: 6 }) const server = http.createServer((req, res) => { - t.fail() + p.ok(0) }) server.on('connect', (req, c, firstBodyChunk) => { - t.fail() + p.ok(0) }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 3 }) - t.teardown(client.destroy.bind(client)) + t.after(() => { + client.destroy() + }) const signal = new EE() client.connect({ @@ -196,25 +204,27 @@ test('connect aborted', (t) => { signal, opaque: 'asd' }, (err, { opaque }) => { - t.equal(opaque, 'asd') - t.equal(signal.listenerCount('abort'), 0) - t.type(err, errors.RequestAbortedError) + p.strictEqual(opaque, 'asd') + p.strictEqual(signal.listenerCount('abort'), 0) + p.ok(err instanceof errors.RequestAbortedError) }) - t.equal(client[kBusy], true) - t.equal(signal.listenerCount('abort'), 1) + p.strictEqual(client[kBusy], true) + p.strictEqual(signal.listenerCount('abort'), 1) signal.emit('abort') client.close(() => { - t.pass() + p.ok(1) }) }) + + await p.completed }) -test('basic connect error', (t) => { - t.plan(2) +test('basic connect error', async (t) => { + const p = tspl(t, { plan: 2 }) const server = http.createServer((c) => { - t.fail() + p.ok(0) }) server.on('connect', (req, socket, firstBodyChunk) => { socket.write('HTTP/1.1 200 Connection established\r\n\r\n') @@ -228,42 +238,44 @@ test('basic connect error', (t) => { socket.end(data) }) }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) const _err = new Error() client.connect({ path: '/' }, (err, { socket }) => { - t.error(err) + p.ifError(err) socket.on('error', (err) => { - t.equal(err, _err) + p.strictEqual(err, _err) }) throw _err }) }) + + await p.completed }) -test('connect invalid signal', (t) => { - t.plan(2) +test('connect invalid signal', async (t) => { + const p = tspl(t, { plan: 2 }) const server = http.createServer((req, res) => { - t.fail() + p.ok(0) }) server.on('connect', (req, c, firstBodyChunk) => { - t.fail() + p.ok(0) }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) client.on('disconnect', () => { - t.fail() + p.ok(0) }) client.connect({ @@ -271,38 +283,42 @@ test('connect invalid signal', (t) => { signal: 'error', opaque: 'asd' }, (err, { opaque }) => { - t.equal(opaque, 'asd') - t.type(err, errors.InvalidArgumentError) + p.strictEqual(opaque, 'asd') + p.ok(err instanceof errors.InvalidArgumentError) }) }) + + await p.completed }) -test('connect aborted after connect', (t) => { - t.plan(3) +test('connect aborted after connect', async (t) => { + const p = tspl(t, { plan: 3 }) const signal = new EE() const server = http.createServer((req, res) => { - t.fail() + p.ok(0) }) server.on('connect', (req, c, firstBodyChunk) => { signal.emit('abort') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 3 }) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) client.connect({ path: '/', signal, opaque: 'asd' }, (err, { opaque }) => { - t.equal(opaque, 'asd') - t.type(err, errors.RequestAbortedError) + p.strictEqual(opaque, 'asd') + p.ok(err instanceof errors.RequestAbortedError) }) - t.equal(client[kBusy], true) + p.strictEqual(client[kBusy], true) }) + + await p.completed }) From 4f4bfb168e163816fe4eecaa30f8744870415b08 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Thu, 4 Jan 2024 01:35:31 +0900 Subject: [PATCH 02/11] `client-dispatch` --- test/{ => node-test}/client-dispatch.js | 414 +++++++++++++----------- 1 file changed, 228 insertions(+), 186 deletions(-) rename test/{ => node-test}/client-dispatch.js (61%) diff --git a/test/client-dispatch.js b/test/node-test/client-dispatch.js similarity index 61% rename from test/client-dispatch.js rename to test/node-test/client-dispatch.js index 781118cc058..d375daede8f 100644 --- a/test/client-dispatch.js +++ b/test/node-test/client-dispatch.js @@ -1,14 +1,16 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') +const assert = require('node:assert/strict') const http = require('http') -const { Client, Pool, errors } = require('..') +const { Client, Pool, errors } = require('../..') const stream = require('stream') const { createSecureServer } = require('node:http2') const pem = require('https-pem') +const { tspl } = require('@matteo.collina/tspl') test('dispatch invalid opts', (t) => { - t.plan(14) + const p = tspl(t, { plan: 14 }) const client = new Client('http://localhost:5000') @@ -19,8 +21,8 @@ test('dispatch invalid opts', (t) => { upgrade: 1 }, null) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'handler must be an object') + p.ok(err instanceof errors.InvalidArgumentError) + p.strictEqual(err.message, 'handler must be an object') } try { @@ -30,8 +32,8 @@ test('dispatch invalid opts', (t) => { upgrade: 1 }, 'asd') } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'handler must be an object') + p.ok(err instanceof errors.InvalidArgumentError) + p.strictEqual(err.message, 'handler must be an object') } client.dispatch({ @@ -40,8 +42,8 @@ test('dispatch invalid opts', (t) => { upgrade: 1 }, { onError (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'upgrade must be a string') + p.ok(err instanceof errors.InvalidArgumentError) + p.strictEqual(err.message, 'upgrade must be a string') } }) @@ -51,8 +53,8 @@ test('dispatch invalid opts', (t) => { headersTimeout: 'asd' }, { onError (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid headersTimeout') + p.ok(err instanceof errors.InvalidArgumentError) + p.strictEqual(err.message, 'invalid headersTimeout') } }) @@ -62,8 +64,8 @@ test('dispatch invalid opts', (t) => { bodyTimeout: 'asd' }, { onError (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid bodyTimeout') + p.ok(err instanceof errors.InvalidArgumentError) + p.strictEqual(err.message, 'invalid bodyTimeout') } }) @@ -74,33 +76,33 @@ test('dispatch invalid opts', (t) => { bodyTimeout: 'asd' }, { onError (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid bodyTimeout') + p.ok(err instanceof errors.InvalidArgumentError) + p.strictEqual(err.message, 'invalid bodyTimeout') } }) client.dispatch(null, { onError (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'opts must be an object.') + p.ok(err instanceof errors.InvalidArgumentError) + p.strictEqual(err.message, 'opts must be an object.') } }) }) -test('basic dispatch get', (t) => { - t.plan(11) +test('basic dispatch get', async (t) => { + const p = tspl(t, { plan: 11 }) const server = http.createServer((req, res) => { - t.equal('/', req.url) - t.equal('GET', req.method) - t.equal(`localhost:${server.address().port}`, req.headers.host) - t.equal(undefined, req.headers.foo) - t.equal('bar', req.headers.bar) - t.equal('', req.headers.baz) - t.equal(undefined, req.headers['content-length']) + p.strictEqual('/', req.url) + p.strictEqual('GET', req.method) + p.strictEqual(`localhost:${server.address().port}`, req.headers.host) + p.strictEqual(undefined, req.headers.foo) + p.strictEqual('bar', req.headers.bar) + p.strictEqual('', req.headers.baz) + p.strictEqual(undefined, req.headers['content-length']) res.end('hello') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) const reqHeaders = { foo: undefined, @@ -110,7 +112,7 @@ test('basic dispatch get', (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) const bufs = [] client.dispatch({ @@ -121,39 +123,41 @@ test('basic dispatch get', (t) => { onConnect () { }, onHeaders (statusCode, headers) { - t.equal(statusCode, 200) - t.equal(Array.isArray(headers), true) + p.strictEqual(statusCode, 200) + p.strictEqual(Array.isArray(headers), true) }, onData (buf) { bufs.push(buf) }, onComplete (trailers) { - t.same(trailers, []) - t.equal('hello', Buffer.concat(bufs).toString('utf8')) + p.deepStrictEqual(trailers, []) + p.strictEqual('hello', Buffer.concat(bufs).toString('utf8')) }, onError () { - t.fail() + p.ok(0) } }) }) + + await p.completed }) -test('trailers dispatch get', (t) => { - t.plan(12) +test('trailers dispatch get', async (t) => { + const p = tspl(t, { plan: 12 }) const server = http.createServer((req, res) => { - t.equal('/', req.url) - t.equal('GET', req.method) - t.equal(`localhost:${server.address().port}`, req.headers.host) - t.equal(undefined, req.headers.foo) - t.equal('bar', req.headers.bar) - t.equal(undefined, req.headers['content-length']) + p.strictEqual('/', req.url) + p.strictEqual('GET', req.method) + p.strictEqual(`localhost:${server.address().port}`, req.headers.host) + p.strictEqual(undefined, req.headers.foo) + p.strictEqual('bar', req.headers.bar) + p.strictEqual(undefined, req.headers['content-length']) res.addTrailers({ 'Content-MD5': 'test' }) res.setHeader('Content-Type', 'text/plain') res.setHeader('Trailer', 'Content-MD5') res.end('hello') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) const reqHeaders = { foo: undefined, @@ -162,7 +166,7 @@ test('trailers dispatch get', (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) const bufs = [] client.dispatch({ @@ -173,42 +177,44 @@ test('trailers dispatch get', (t) => { onConnect () { }, onHeaders (statusCode, headers) { - t.equal(statusCode, 200) - t.equal(Array.isArray(headers), true) + p.strictEqual(statusCode, 200) + p.strictEqual(Array.isArray(headers), true) { const contentTypeIdx = headers.findIndex(x => x.toString() === 'Content-Type') - t.equal(headers[contentTypeIdx + 1].toString(), 'text/plain') + p.strictEqual(headers[contentTypeIdx + 1].toString(), 'text/plain') } }, onData (buf) { bufs.push(buf) }, onComplete (trailers) { - t.equal(Array.isArray(trailers), true) + p.strictEqual(Array.isArray(trailers), true) { const contentMD5Idx = trailers.findIndex(x => x.toString() === 'Content-MD5') - t.equal(trailers[contentMD5Idx + 1].toString(), 'test') + p.strictEqual(trailers[contentMD5Idx + 1].toString(), 'test') } - t.equal('hello', Buffer.concat(bufs).toString('utf8')) + p.strictEqual('hello', Buffer.concat(bufs).toString('utf8')) }, onError () { - t.fail() + p.ok(0) } }) }) + + await p.completed }) -test('dispatch onHeaders error', (t) => { - t.plan(1) +test('dispatch onHeaders error', async (t) => { + const p = tspl(t, { plan: 1 }) const server = http.createServer((req, res) => { res.end() }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) const _err = new Error() client.dispatch({ @@ -221,29 +227,31 @@ test('dispatch onHeaders error', (t) => { throw _err }, onData (buf) { - t.fail() + p.ok(0) }, onComplete (trailers) { - t.fail() + p.ok(0) }, onError (err) { - t.equal(err, _err) + p.strictEqual(err, _err) } }) }) + + await p.completed }) -test('dispatch onComplete error', (t) => { - t.plan(2) +test('dispatch onComplete error', async (t) => { + const p = tspl(t, { plan: 2 }) const server = http.createServer((req, res) => { res.end() }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) const _err = new Error() client.dispatch({ @@ -253,32 +261,34 @@ test('dispatch onComplete error', (t) => { onConnect () { }, onHeaders (statusCode, headers) { - t.pass() + p.ok(1) }, onData (buf) { - t.fail() + p.ok(0) }, onComplete (trailers) { throw _err }, onError (err) { - t.equal(err, _err) + p.strictEqual(err, _err) } }) }) + + await p.completed }) -test('dispatch onData error', (t) => { - t.plan(2) +test('dispatch onData error', async (t) => { + const p = tspl(t, { plan: 2 }) const server = http.createServer((req, res) => { res.end('ad') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) const _err = new Error() client.dispatch({ @@ -288,32 +298,34 @@ test('dispatch onData error', (t) => { onConnect () { }, onHeaders (statusCode, headers) { - t.pass() + p.ok(1) }, onData (buf) { throw _err }, onComplete (trailers) { - t.fail() + p.ok(0) }, onError (err) { - t.equal(err, _err) + p.strictEqual(err, _err) } }) }) + + await p.completed }) -test('dispatch onConnect error', (t) => { - t.plan(1) +test('dispatch onConnect error', async (t) => { + const p = tspl(t, { plan: 1 }) const server = http.createServer((req, res) => { res.end('ad') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) const _err = new Error() client.dispatch({ @@ -324,26 +336,28 @@ test('dispatch onConnect error', (t) => { throw _err }, onHeaders (statusCode, headers) { - t.fail() + p.ok(0) }, onData (buf) { - t.fail() + p.ok(0) }, onComplete (trailers) { - t.fail() + p.ok(0) }, onError (err) { - t.equal(err, _err) + p.strictEqual(err, _err) } }) }) + + await p.completed }) -test('connect call onUpgrade once', (t) => { - t.plan(2) +test('connect call onUpgrade once', async (t) => { + const p = tspl(t, { plan: 2 }) const server = http.createServer((c) => { - t.fail() + p.ok(0) }) server.on('connect', (req, socket, firstBodyChunk) => { socket.write('HTTP/1.1 200 Connection established\r\n\r\n') @@ -357,11 +371,11 @@ test('connect call onUpgrade once', (t) => { socket.end(data) }) }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) let recvData = '' let count = 0 @@ -375,43 +389,45 @@ test('connect call onUpgrade once', (t) => { t.pass('should not throw') }, onUpgrade (statusCode, headers, socket) { - t.equal(count++, 0) + p.strictEqual(count++, 0) socket.on('data', (d) => { recvData += d }) socket.on('end', () => { - t.equal(recvData.toString(), 'Body') + p.strictEqual(recvData.toString(), 'Body') }) socket.write('Body') socket.end() }, onData (buf) { - t.fail() + p.ok(0) }, onComplete (trailers) { - t.fail() + p.ok(0) }, onError () { - t.fail() + p.ok(0) } }) }) + + await p.completed }) -test('dispatch onConnect missing', (t) => { - t.plan(1) +test('dispatch onConnect missing', async (t) => { + const p = tspl(t, { plan: 1 }) const server = http.createServer((req, res) => { res.end('ad') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) client.dispatch({ path: '/', @@ -427,23 +443,25 @@ test('dispatch onConnect missing', (t) => { t.pass('should not throw') }, onError (err) { - t.equal(err.code, 'UND_ERR_INVALID_ARG') + p.strictEqual(err.code, 'UND_ERR_INVALID_ARG') } }) }) + + await p.completed }) -test('dispatch onHeaders missing', (t) => { - t.plan(1) +test('dispatch onHeaders missing', async (t) => { + const p = tspl(t, { plan: 1 }) const server = http.createServer((req, res) => { res.end('ad') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) client.dispatch({ path: '/', @@ -452,29 +470,31 @@ test('dispatch onHeaders missing', (t) => { onConnect () { }, onData (buf) { - t.fail('should not throw') + p.ok(0, 'should not throw') }, onComplete (trailers) { - t.fail('should not throw') + p.ok(0, 'should not throw') }, onError (err) { - t.equal(err.code, 'UND_ERR_INVALID_ARG') + p.strictEqual(err.code, 'UND_ERR_INVALID_ARG') } }) }) + + await p.completed }) -test('dispatch onData missing', (t) => { - t.plan(1) +test('dispatch onData missing', async (t) => { + const p = tspl(t, { plan: 1 }) const server = http.createServer((req, res) => { res.end('ad') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) client.dispatch({ path: '/', @@ -483,29 +503,31 @@ test('dispatch onData missing', (t) => { onConnect () { }, onHeaders (statusCode, headers) { - t.fail('should not throw') + p.ok(0, 'should not throw') }, onComplete (trailers) { - t.fail('should not throw') + p.ok(0, 'should not throw') }, onError (err) { - t.equal(err.code, 'UND_ERR_INVALID_ARG') + p.strictEqual(err.code, 'UND_ERR_INVALID_ARG') } }) }) + + await p.completed }) -test('dispatch onComplete missing', (t) => { - t.plan(1) +test('dispatch onComplete missing', async (t) => { + const p = tspl(t, { plan: 1 }) const server = http.createServer((req, res) => { res.end('ad') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) client.dispatch({ path: '/', @@ -514,29 +536,31 @@ test('dispatch onComplete missing', (t) => { onConnect () { }, onHeaders (statusCode, headers) { - t.fail() + p.ok(0) }, onData (buf) { - t.fail() + p.ok(0) }, onError (err) { - t.equal(err.code, 'UND_ERR_INVALID_ARG') + p.strictEqual(err.code, 'UND_ERR_INVALID_ARG') } }) }) + + await p.completed }) -test('dispatch onError missing', (t) => { - t.plan(1) +test('dispatch onError missing', async (t) => { + const p = tspl(t, { plan: 1 }) const server = http.createServer((req, res) => { res.end('ad') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) try { client.dispatch({ @@ -546,32 +570,34 @@ test('dispatch onError missing', (t) => { onConnect () { }, onHeaders (statusCode, headers) { - t.fail() + p.ok(0) }, onData (buf) { - t.fail() + p.ok(0) }, onComplete (trailers) { - t.fail() + p.ok(0) } }) } catch (err) { - t.equal(err.code, 'UND_ERR_INVALID_ARG') + p.strictEqual(err.code, 'UND_ERR_INVALID_ARG') } }) + + await p.completed }) -test('dispatch CONNECT onUpgrade missing', (t) => { - t.plan(2) +test('dispatch CONNECT onUpgrade missing', async (t) => { + const p = tspl(t, { plan: 2 }) const server = http.createServer((req, res) => { res.end('ad') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + t.after(() => client.destroy.bind(client)()) client.dispatch({ path: '/', @@ -583,24 +609,26 @@ test('dispatch CONNECT onUpgrade missing', (t) => { onHeaders (statusCode, headers) { }, onError (err) { - t.equal(err.code, 'UND_ERR_INVALID_ARG') - t.equal(err.message, 'invalid onUpgrade method') + p.strictEqual(err.code, 'UND_ERR_INVALID_ARG') + p.strictEqual(err.message, 'invalid onUpgrade method') } }) }) + + await p.completed }) -test('dispatch upgrade onUpgrade missing', (t) => { - t.plan(2) +test('dispatch upgrade onUpgrade missing', async (t) => { + const p = tspl(t, { plan: 2 }) const server = http.createServer((req, res) => { res.end('ad') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) client.dispatch({ path: '/', @@ -612,24 +640,26 @@ test('dispatch upgrade onUpgrade missing', (t) => { onHeaders (statusCode, headers) { }, onError (err) { - t.equal(err.code, 'UND_ERR_INVALID_ARG') - t.equal(err.message, 'invalid onUpgrade method') + p.strictEqual(err.code, 'UND_ERR_INVALID_ARG') + p.strictEqual(err.message, 'invalid onUpgrade method') } }) }) + + await p.completed }) -test('dispatch pool onError missing', (t) => { - t.plan(2) +test('dispatch pool onError missing', async (t) => { + const p = tspl(t, { plan: 2 }) const server = http.createServer((req, res) => { res.end('ad') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) try { client.dispatch({ @@ -639,22 +669,24 @@ test('dispatch pool onError missing', (t) => { }, { }) } catch (err) { - t.equal(err.code, 'UND_ERR_INVALID_ARG') - t.equal(err.message, 'invalid onError method') + p.strictEqual(err.code, 'UND_ERR_INVALID_ARG') + p.strictEqual(err.message, 'invalid onError method') } }) + + await p.completed }) -test('dispatch onBodySent not a function', (t) => { - t.plan(2) +test('dispatch onBodySent not a function', async (t) => { + const p = tspl(t, { plan: 2 }) const server = http.createServer((req, res) => { res.end('ad') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) client.dispatch({ path: '/', @@ -665,24 +697,26 @@ test('dispatch onBodySent not a function', (t) => { onHeaders () {}, onData () {}, onError (err) { - t.equal(err.code, 'UND_ERR_INVALID_ARG') - t.equal(err.message, 'invalid onBodySent method') + p.strictEqual(err.code, 'UND_ERR_INVALID_ARG') + p.strictEqual(err.message, 'invalid onBodySent method') } }) }) + + await p.completed }) -test('dispatch onBodySent buffer', (t) => { - t.plan(3) +test('dispatch onBodySent buffer', async (t) => { + const p = tspl(t, { plan: 3 }) const server = http.createServer((req, res) => { res.end('ad') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) const body = 'hello 🚀' client.dispatch({ path: '/', @@ -690,10 +724,10 @@ test('dispatch onBodySent buffer', (t) => { body }, { onBodySent (chunk) { - t.equal(chunk.toString(), body) + p.strictEqual(chunk.toString(), body) }, onRequestSent () { - t.pass() + p.ok(1) }, onError (err) { throw err @@ -702,24 +736,26 @@ test('dispatch onBodySent buffer', (t) => { onHeaders () {}, onData () {}, onComplete () { - t.pass() + p.ok(1) } }) }) + + await p.completed }) -test('dispatch onBodySent stream', (t) => { - t.plan(8) +test('dispatch onBodySent stream', async (t) => { + const p = tspl(t, { plan: 8 }) const server = http.createServer((req, res) => { res.end('ad') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) const chunks = ['he', 'llo', 'world', '🚀'] const toSendBytes = chunks.reduce((a, b) => a + Buffer.byteLength(b), 0) const body = stream.Readable.from(chunks) server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) let sentBytes = 0 let currentChunk = 0 client.dispatch({ @@ -728,11 +764,11 @@ test('dispatch onBodySent stream', (t) => { body }, { onBodySent (chunk) { - t.equal(chunks[currentChunk++], chunk) + p.strictEqual(chunks[currentChunk++], chunk) sentBytes += Buffer.byteLength(chunk) }, onRequestSent () { - t.pass() + p.ok(1) }, onError (err) { throw err @@ -741,24 +777,26 @@ test('dispatch onBodySent stream', (t) => { onHeaders () {}, onData () {}, onComplete () { - t.equal(currentChunk, chunks.length) - t.equal(sentBytes, toSendBytes) - t.pass() + p.strictEqual(currentChunk, chunks.length) + p.strictEqual(sentBytes, toSendBytes) + p.ok(1) } }) }) + + await p.completed }) test('dispatch onBodySent async-iterable', (t) => { const server = http.createServer((req, res) => { res.end('ad') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) const chunks = ['he', 'llo', 'world', '🚀'] const toSendBytes = chunks.reduce((a, b) => a + Buffer.byteLength(b), 0) server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(client.close.bind(client)) let sentBytes = 0 let currentChunk = 0 client.dispatch({ @@ -767,7 +805,7 @@ test('dispatch onBodySent async-iterable', (t) => { body: chunks }, { onBodySent (chunk) { - t.equal(chunks[currentChunk++], chunk) + assert.strictEqual(chunks[currentChunk++], chunk) sentBytes += Buffer.byteLength(chunk) }, onError (err) { @@ -777,9 +815,8 @@ test('dispatch onBodySent async-iterable', (t) => { onHeaders () {}, onData () {}, onComplete () { - t.equal(currentChunk, chunks.length) - t.equal(sentBytes, toSendBytes) - t.end() + assert.strictEqual(currentChunk, chunks.length) + assert.strictEqual(sentBytes, toSendBytes) } }) }) @@ -789,11 +826,11 @@ test('dispatch onBodySent throws error', (t) => { const server = http.createServer((req, res) => { res.end('ended') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) const body = 'hello' client.dispatch({ path: '/', @@ -804,9 +841,8 @@ test('dispatch onBodySent throws error', (t) => { throw new Error('fail') }, onError (err) { - t.type(err, Error) - t.equal(err.message, 'fail') - t.end() + assert.ok(err instanceof Error) + assert.strictEqual(err.message, 'fail') }, onConnect () {}, onHeaders () {}, @@ -816,17 +852,18 @@ test('dispatch onBodySent throws error', (t) => { }) }) -test('dispatches in expected order', (t) => { +test('dispatches in expected order', async (t) => { const server = http.createServer((req, res) => { res.end('ended') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) + + const p = tspl(t, { plan: 1 }) server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.plan(1) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) const dispatches = [] @@ -852,16 +889,18 @@ test('dispatches in expected order', (t) => { }, onComplete () { dispatches.push('onComplete') - t.same(dispatches, ['onConnect', 'onBodySent', 'onResponseStarted', 'onHeaders', 'onData', 'onComplete']) + p.deepStrictEqual(dispatches, ['onConnect', 'onBodySent', 'onResponseStarted', 'onHeaders', 'onData', 'onComplete']) }, onError (err) { - t.error(err) + p.ifError(err) } }) }) + + await p.completed }) -test('dispatches in expected order for http2', (t) => { +test('dispatches in expected order for http2', async (t) => { const server = createSecureServer(pem) server.on('stream', (stream) => { stream.respond({ @@ -871,7 +910,9 @@ test('dispatches in expected order for http2', (t) => { stream.end('ended') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) + + const p = tspl(t, { plan: 1 }) server.listen(0, () => { const client = new Pool(`https://localhost:${server.address().port}`, { @@ -881,8 +922,7 @@ test('dispatches in expected order for http2', (t) => { allowH2: true }) - t.plan(1) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) const dispatches = [] @@ -908,11 +948,13 @@ test('dispatches in expected order for http2', (t) => { }, onComplete () { dispatches.push('onComplete') - t.same(dispatches, ['onConnect', 'onBodySent', 'onResponseStarted', 'onHeaders', 'onData', 'onComplete']) + p.deepStrictEqual(dispatches, ['onConnect', 'onBodySent', 'onResponseStarted', 'onHeaders', 'onData', 'onComplete']) }, onError (err) { - t.error(err) + p.ifError(err) } }) }) + + await p.completed }) From 74d6d7e5389ba2e9e8f77abcc58a264ded8a121f Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Fri, 5 Jan 2024 01:01:18 +0900 Subject: [PATCH 03/11] `client-errors` --- test/{ => node-test}/client-errors.js | 700 ++++++++++++++------------ 1 file changed, 374 insertions(+), 326 deletions(-) rename test/{ => node-test}/client-errors.js (57%) diff --git a/test/client-errors.js b/test/node-test/client-errors.js similarity index 57% rename from test/client-errors.js rename to test/node-test/client-errors.js index cec7f37d62a..585a467f456 100644 --- a/test/client-errors.js +++ b/test/node-test/client-errors.js @@ -1,72 +1,78 @@ 'use strict' -const { test } = require('tap') -const { Client, Pool, errors } = require('..') +const { test } = require('node:test') +const assert = require('node:assert') +const { Client, Pool, errors } = require('../..') const { createServer } = require('http') const https = require('https') const pem = require('https-pem') const net = require('net') const { Readable } = require('stream') +const { tspl } = require('@matteo.collina/tspl') -const { kSocket } = require('../lib/core/symbols') -const { wrapWithAsyncIterable, maybeWrapStream, consts } = require('./utils/async-iterators') +const { kSocket } = require('../../lib/core/symbols') +const { wrapWithAsyncIterable, maybeWrapStream, consts } = require('../utils/async-iterators') class IteratorError extends Error {} -test('GET errors and reconnect with pipelining 1', (t) => { - t.plan(9) +test('GET errors and reconnect with pipelining 1', async (t) => { + const p = tspl(t, { plan: 9 }) const server = createServer() server.once('request', (req, res) => { - t.pass('first request received, destroying') + // first request received, destroying + p.ok(1) res.socket.destroy() server.once('request', (req, res) => { - t.equal('/', req.url) - t.equal('GET', req.method) + p.strictEqual('/', req.url) + p.strictEqual('GET', req.method) res.setHeader('content-type', 'text/plain') res.end('hello') }) }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 1 }) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) client.request({ path: '/', method: 'GET', idempotent: false, opaque: 'asd' }, (err, data) => { - t.type(err, Error) // we are expecting an error - t.equal(data.opaque, 'asd') + p.ok(err instanceof Error) // we are expecting an error + p.strictEqual(data.opaque, 'asd') }) client.request({ path: '/', method: 'GET' }, (err, { statusCode, headers, body }) => { - t.error(err) - t.equal(statusCode, 200) - t.equal(headers['content-type'], 'text/plain') + p.ifError(err) + p.strictEqual(statusCode, 200) + p.strictEqual(headers['content-type'], 'text/plain') const bufs = [] body.on('data', (buf) => { bufs.push(buf) }) body.on('end', () => { - t.equal('hello', Buffer.concat(bufs).toString('utf8')) + p.strictEqual('hello', Buffer.concat(bufs).toString('utf8')) }) }) }) + + await p.completed }) -test('GET errors and reconnect with pipelining 3', (t) => { +test('GET errors and reconnect with pipelining 3', async (t) => { const server = createServer() const requestsThatWillError = 3 let requests = 0 - t.plan(6 + requestsThatWillError * 3) + const p = tspl(t, { plan: 6 + requestsThatWillError * 3 }) server.on('request', (req, res) => { if (requests++ < requestsThatWillError) { - t.pass('request received, destroying') + // request received, destroying + p.ok(1) // socket might not be there if it was destroyed by another // pipelined request @@ -74,53 +80,55 @@ test('GET errors and reconnect with pipelining 3', (t) => { res.socket.destroy() } } else { - t.equal('/', req.url) - t.equal('GET', req.method) + p.strictEqual('/', req.url) + p.strictEqual('GET', req.method) res.setHeader('content-type', 'text/plain') res.end('hello') } }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 3 }) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) // all of these will error for (let i = 0; i < 3; i++) { client.request({ path: '/', method: 'GET', idempotent: false, opaque: 'asd' }, (err, data) => { - t.type(err, Error) // we are expecting an error - t.equal(data.opaque, 'asd') + p.ok(err instanceof Error) // we are expecting an error + p.strictEqual(data.opaque, 'asd') }) } // this will be queued up client.request({ path: '/', method: 'GET', idempotent: false }, (err, { statusCode, headers, body }) => { - t.error(err) - t.equal(statusCode, 200) - t.equal(headers['content-type'], 'text/plain') + p.ifError(err) + p.strictEqual(statusCode, 200) + p.strictEqual(headers['content-type'], 'text/plain') const bufs = [] body.on('data', (buf) => { bufs.push(buf) }) body.on('end', () => { - t.equal('hello', Buffer.concat(bufs).toString('utf8')) + p.strictEqual('hello', Buffer.concat(bufs).toString('utf8')) }) }) }) + + await p.completed }) function errorAndPipelining (type) { - test(`POST with a ${type} that errors and pipelining 1 should reconnect`, (t) => { - t.plan(12) + test(`POST with a ${type} that errors and pipelining 1 should reconnect`, async (t) => { + const p = tspl(t, { plan: 12 }) const server = createServer() server.once('request', (req, res) => { - t.equal('/', req.url) - t.equal('POST', req.method) - t.equal('42', req.headers['content-length']) + p.strictEqual('/', req.url) + p.strictEqual('POST', req.method) + p.strictEqual('42', req.headers['content-length']) const bufs = [] req.on('data', (buf) => { @@ -130,21 +138,21 @@ function errorAndPipelining (type) { req.on('aborted', () => { // we will abruptly close the connection here // but this will still end - t.equal('a string', Buffer.concat(bufs).toString('utf8')) + p.strictEqual('a string', Buffer.concat(bufs).toString('utf8')) }) server.once('request', (req, res) => { - t.equal('/', req.url) - t.equal('GET', req.method) + p.strictEqual('/', req.url) + p.strictEqual('GET', req.method) res.setHeader('content-type', 'text/plain') res.end('hello') }) }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) client.request({ path: '/', @@ -161,24 +169,26 @@ function errorAndPipelining (type) { } }), type) }, (err, data) => { - t.equal(err.message, 'kaboom') - t.equal(data.opaque, 'asd') + p.strictEqual(err.message, 'kaboom') + p.strictEqual(data.opaque, 'asd') }) // this will be queued up client.request({ path: '/', method: 'GET', idempotent: false }, (err, { statusCode, headers, body }) => { - t.error(err) - t.equal(statusCode, 200) - t.equal(headers['content-type'], 'text/plain') + p.ifError(err) + p.strictEqual(statusCode, 200) + p.strictEqual(headers['content-type'], 'text/plain') const bufs = [] body.on('data', (buf) => { bufs.push(buf) }) body.on('end', () => { - t.equal('hello', Buffer.concat(bufs).toString('utf8')) + p.strictEqual('hello', Buffer.concat(bufs).toString('utf8')) }) }) }) + + await p.completed }) } @@ -186,14 +196,14 @@ errorAndPipelining(consts.STREAM) errorAndPipelining(consts.ASYNC_ITERATOR) function errorAndChunkedEncodingPipelining (type) { - test(`POST with chunked encoding, ${type} body that errors and pipelining 1 should reconnect`, (t) => { - t.plan(12) + test(`POST with chunked encoding, ${type} body that errors and pipelining 1 should reconnect`, async (t) => { + const p = tspl(t, { plan: 12 }) const server = createServer() server.once('request', (req, res) => { - t.equal('/', req.url) - t.equal('POST', req.method) - t.equal(req.headers['content-length'], undefined) + p.strictEqual('/', req.url) + p.strictEqual('POST', req.method) + p.strictEqual(req.headers['content-length'], undefined) const bufs = [] req.on('data', (buf) => { @@ -203,21 +213,21 @@ function errorAndChunkedEncodingPipelining (type) { req.on('aborted', () => { // we will abruptly close the connection here // but this will still end - t.equal('a string', Buffer.concat(bufs).toString('utf8')) + p.strictEqual('a string', Buffer.concat(bufs).toString('utf8')) }) server.once('request', (req, res) => { - t.equal('/', req.url) - t.equal('GET', req.method) + p.strictEqual('/', req.url) + p.strictEqual('GET', req.method) res.setHeader('content-type', 'text/plain') res.end('hello') }) }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) client.request({ path: '/', @@ -230,322 +240,323 @@ function errorAndChunkedEncodingPipelining (type) { } }), type) }, (err, data) => { - t.equal(err.message, 'kaboom') - t.equal(data.opaque, 'asd') + p.strictEqual(err.message, 'kaboom') + p.strictEqual(data.opaque, 'asd') }) // this will be queued up client.request({ path: '/', method: 'GET' }, (err, { statusCode, headers, body }) => { - t.error(err) - t.equal(statusCode, 200) - t.equal(headers['content-type'], 'text/plain') + p.ifError(err) + p.strictEqual(statusCode, 200) + p.strictEqual(headers['content-type'], 'text/plain') const bufs = [] body.on('data', (buf) => { bufs.push(buf) }) body.on('end', () => { - t.equal('hello', Buffer.concat(bufs).toString('utf8')) + p.strictEqual('hello', Buffer.concat(bufs).toString('utf8')) }) }) }) + await p.completed }) } errorAndChunkedEncodingPipelining(consts.STREAM) errorAndChunkedEncodingPipelining(consts.ASYNC_ITERATOR) -test('invalid options throws', (t) => { +test('invalid options throws', (t, done) => { try { new Client({ port: 'foobar', protocol: 'https:' }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'Invalid URL: port must be a valid integer or a string representation of an integer.') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'Invalid URL: port must be a valid integer or a string representation of an integer.') } try { new Client(new URL('http://asd:200/somepath')) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid url') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'invalid url') } try { new Client(new URL('http://asd:200?q=asd')) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid url') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'invalid url') } try { new Client(new URL('http://asd:200#asd')) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid url') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'invalid url') } try { new Client(new URL('http://localhost:200'), { // eslint-disable-line socketPath: 1 }) - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid socketPath') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'invalid socketPath') } try { new Client(new URL('http://localhost:200'), { // eslint-disable-line keepAliveTimeout: 'asd' }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid keepAliveTimeout') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'invalid keepAliveTimeout') } try { new Client(new URL('http://localhost:200'), { // eslint-disable-line localAddress: 123 }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'localAddress must be valid string IP address') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'localAddress must be valid string IP address') } try { new Client(new URL('http://localhost:200'), { // eslint-disable-line localAddress: 'abcd123' }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'localAddress must be valid string IP address') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'localAddress must be valid string IP address') } try { new Client(new URL('http://localhost:200'), { // eslint-disable-line keepAliveMaxTimeout: 'asd' }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid keepAliveMaxTimeout') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'invalid keepAliveMaxTimeout') } try { new Client(new URL('http://localhost:200'), { // eslint-disable-line keepAliveMaxTimeout: 0 }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid keepAliveMaxTimeout') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'invalid keepAliveMaxTimeout') } try { new Client(new URL('http://localhost:200'), { // eslint-disable-line keepAliveTimeoutThreshold: 'asd' }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid keepAliveTimeoutThreshold') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'invalid keepAliveTimeoutThreshold') } try { new Client({ // eslint-disable-line protocol: 'asd' }) - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'Invalid URL protocol: the URL must start with `http:` or `https:`.') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'Invalid URL protocol: the URL must start with `http:` or `https:`.') } try { new Client({ // eslint-disable-line hostname: 1 }) - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'Invalid URL protocol: the URL must start with `http:` or `https:`.') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'Invalid URL protocol: the URL must start with `http:` or `https:`.') } try { new Client(new URL('http://localhost:200'), { // eslint-disable-line maxHeaderSize: 'asd' }) - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid maxHeaderSize') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'invalid maxHeaderSize') } try { new Client(1) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'Invalid URL: The URL argument must be a non-null object.') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'Invalid URL: The URL argument must be a non-null object.') } try { const client = new Client(new URL('http://localhost:200')) // eslint-disable-line client.destroy(null, null) - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid callback') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'invalid callback') } try { const client = new Client(new URL('http://localhost:200')) // eslint-disable-line client.close(null, null) - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid callback') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'invalid callback') } try { new Client(new URL('http://localhost:200'), { maxKeepAliveTimeout: 1e3 }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'unsupported maxKeepAliveTimeout, use keepAliveMaxTimeout instead') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'unsupported maxKeepAliveTimeout, use keepAliveMaxTimeout instead') } try { new Client(new URL('http://localhost:200'), { keepAlive: false }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'unsupported keepAlive, use pipelining=0 instead') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'unsupported keepAlive, use pipelining=0 instead') } try { new Client(new URL('http://localhost:200'), { idleTimeout: 30e3 }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'unsupported idleTimeout, use keepAliveTimeout instead') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'unsupported idleTimeout, use keepAliveTimeout instead') } try { new Client(new URL('http://localhost:200'), { socketTimeout: 30e3 }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'unsupported socketTimeout, use headersTimeout & bodyTimeout instead') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'unsupported socketTimeout, use headersTimeout & bodyTimeout instead') } try { new Client(new URL('http://localhost:200'), { requestTimeout: 30e3 }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'unsupported requestTimeout, use headersTimeout & bodyTimeout instead') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'unsupported requestTimeout, use headersTimeout & bodyTimeout instead') } try { new Client(new URL('http://localhost:200'), { connectTimeout: -1 }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid connectTimeout') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'invalid connectTimeout') } try { new Client(new URL('http://localhost:200'), { connectTimeout: Infinity }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid connectTimeout') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'invalid connectTimeout') } try { new Client(new URL('http://localhost:200'), { connectTimeout: 'asd' }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'invalid connectTimeout') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'invalid connectTimeout') } try { new Client(new URL('http://localhost:200'), { connect: 'asd' }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'connect must be a function or an object') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'connect must be a function or an object') } try { new Client(new URL('http://localhost:200'), { connect: -1 }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'connect must be a function or an object') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'connect must be a function or an object') } try { new Pool(new URL('http://localhost:200'), { connect: 'asd' }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'connect must be a function or an object') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'connect must be a function or an object') } try { new Pool(new URL('http://localhost:200'), { connect: -1 }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'connect must be a function or an object') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'connect must be a function or an object') } try { new Client(new URL('http://localhost:200'), { maxCachedSessions: -10 }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'maxCachedSessions must be a positive integer or zero') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'maxCachedSessions must be a positive integer or zero') } try { new Client(new URL('http://localhost:200'), { maxCachedSessions: 'foo' }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'maxCachedSessions must be a positive integer or zero') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'maxCachedSessions must be a positive integer or zero') } try { new Client(new URL('http://localhost:200'), { maxRequestsPerClient: 'foo' }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'maxRequestsPerClient must be a positive number') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'maxRequestsPerClient must be a positive number') } try { new Client(new URL('http://localhost:200'), { autoSelectFamilyAttemptTimeout: 'foo' }) // eslint-disable-line - t.fail() + assert.ok(0) } catch (err) { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'autoSelectFamilyAttemptTimeout must be a positive number') + assert.ok(err instanceof errors.InvalidArgumentError) + assert.strictEqual(err.message, 'autoSelectFamilyAttemptTimeout must be a positive number') } - t.end() + done() }) -test('POST which fails should error response', (t) => { - t.plan(6) +test('POST which fails should error response', async (t) => { + const p = tspl(t, { plan: 6 }) const server = createServer() server.on('request', (req, res) => { @@ -553,15 +564,15 @@ test('POST which fails should error response', (t) => { res.destroy() }) }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) function checkError (err) { // Different platforms error with different codes... - t.ok( + p.ok( err.code === 'EPIPE' || err.code === 'ECONNRESET' || err.code === 'UND_ERR_SOCKET' || @@ -631,10 +642,12 @@ test('POST which fails should error response', (t) => { }) } }) + + await p.completed }) -test('client destroy cleanup', (t) => { - t.plan(3) +test('client destroy cleanup', async (t) => { + const p = tspl(t, { plan: 3 }) const _err = new Error('kaboom') let client @@ -642,20 +655,20 @@ test('client destroy cleanup', (t) => { server.once('request', (req, res) => { req.once('data', () => { client.destroy(_err, (err) => { - t.error(err) + p.ifError(err) }) }) }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) const body = new Readable({ read () {} }) body.push('asd') body.on('error', (err) => { - t.equal(err, _err) + p.strictEqual(err, _err) }) client.request({ @@ -663,22 +676,24 @@ test('client destroy cleanup', (t) => { method: 'POST', body }, (err, data) => { - t.equal(err, _err) + p.strictEqual(err, _err) }) }) + + await p.completed }) -test('throwing async-iterator causes error', (t) => { - t.plan(1) +test('throwing async-iterator causes error', async (t) => { + const p = tspl(t, { plan: 1 }) const server = createServer((req, res) => { res.end(Buffer.alloc(4 + 1, 'a')) }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) client.request({ method: 'POST', @@ -688,13 +703,15 @@ test('throwing async-iterator causes error', (t) => { throw new IteratorError('bad iterator') })() }, (err) => { - t.type(err, IteratorError) + p.ok(err instanceof IteratorError) }) }) + + await p.completed }) -test('client async-iterator destroy cleanup', (t) => { - t.plan(2) +test('client async-iterator destroy cleanup', async (t) => { + const p = tspl(t, { plan: 2 }) const _err = new Error('kaboom') let client @@ -702,15 +719,15 @@ test('client async-iterator destroy cleanup', (t) => { server.once('request', (req, res) => { req.once('data', () => { client.destroy(_err, (err) => { - t.error(err) + p.ifError(err) }) }) }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) const body = wrapWithAsyncIterable(['asd'], true) @@ -719,13 +736,15 @@ test('client async-iterator destroy cleanup', (t) => { method: 'POST', body }, (err, data) => { - t.equal(err, _err) + p.strictEqual(err, _err) }) }) + + await p.completed }) -test('GET errors body', (t) => { - t.plan(2) +test('GET errors body', async (t) => { + const p = tspl(t, { plan: 2 }) const server = createServer() server.once('request', (req, res) => { @@ -734,40 +753,42 @@ test('GET errors body', (t) => { res.destroy() }, 19) }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) client.request({ path: '/', method: 'GET' }, (err, { statusCode, headers, body }) => { - t.error(err) + p.ifError(err) body.resume() body.on('error', err => ( - t.ok(err) + p.ok(err) )) }) }) + + await p.completed }) -test('validate request body', (t) => { - t.plan(6) +test('validate request body', async (t) => { + const p = tspl(t, { plan: 6 }) const server = createServer((req, res) => { res.end('asd') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) client.request({ path: '/', method: 'POST', body: /asdasd/ }, (err, data) => { - t.type(err, errors.InvalidArgumentError) + p.ok(err instanceof errors.InvalidArgumentError) }) client.request({ @@ -775,7 +796,7 @@ test('validate request body', (t) => { method: 'POST', body: 0 }, (err, data) => { - t.type(err, errors.InvalidArgumentError) + p.ok(err instanceof errors.InvalidArgumentError) }) client.request({ @@ -783,7 +804,7 @@ test('validate request body', (t) => { method: 'POST', body: false }, (err, data) => { - t.type(err, errors.InvalidArgumentError) + p.ok(err instanceof errors.InvalidArgumentError) }) client.request({ @@ -791,7 +812,7 @@ test('validate request body', (t) => { method: 'POST', body: '' }, (err, data) => { - t.error(err) + p.ifError(err) data.body.resume() }) @@ -800,7 +821,7 @@ test('validate request body', (t) => { method: 'POST', body: new Uint8Array() }, (err, data) => { - t.error(err) + p.ifError(err) data.body.resume() }) @@ -809,46 +830,50 @@ test('validate request body', (t) => { method: 'POST', body: Buffer.alloc(10) }, (err, data) => { - t.error(err) + p.ifError(err) data.body.resume() }) }) + + await p.completed }) -test('parser error', (t) => { - t.plan(2) +test('parser error', async (t) => { + const p = tspl(t, { plan: 2 }) const server = net.createServer() server.once('connection', (socket) => { socket.write('asd\n\r213123') }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) client.request({ path: '/', method: 'GET' }, (err) => { - t.ok(err) + p.ok(err) client.close((err) => { - t.error(err) + p.ifError(err) }) }) }) + + await p.completed }) function socketFailWrite (type) { - test(`socket fail while writing ${type} request body`, (t) => { - t.plan(2) + test(`socket fail while writing ${type} request body`, async (t) => { + const p = tspl(t, { plan: 2 }) const server = createServer() server.once('request', (req, res) => { }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) const preBody = new Readable({ read () {} }) preBody.push('asd') @@ -864,32 +889,34 @@ function socketFailWrite (type) { method: 'POST', body }, (err) => { - t.ok(err) + p.ok(err) }) client.close((err) => { - t.error(err) + p.ifError(err) }) }) + + await p.completed }) } socketFailWrite(consts.STREAM) socketFailWrite(consts.ASYNC_ITERATOR) function socketFailEndWrite (type) { - test(`socket fail while ending ${type} request body`, (t) => { - t.plan(3) + test(`socket fail while ending ${type} request body`, async (t) => { + const p = tspl(t, { plan: 3 }) const server = createServer() server.once('request', (req, res) => { res.end() }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 2 }) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) const _err = new Error('kaboom') client.on('connect', () => { @@ -906,86 +933,90 @@ function socketFailEndWrite (type) { method: 'POST', body }, (err) => { - t.equal(err, _err) + p.strictEqual(err, _err) }) client.close((err) => { - t.error(err) + p.ifError(err) client.close((err) => { - t.type(err, errors.ClientDestroyedError) + p.ok(err instanceof errors.ClientDestroyedError) }) }) }) + + await p.completed }) } socketFailEndWrite(consts.STREAM) socketFailEndWrite(consts.ASYNC_ITERATOR) -test('queued request should not fail on socket destroy', (t) => { - t.plan(4) +test('queued request should not fail on socket destroy', async (t) => { + const p = tspl(t, { plan: 4 }) const server = createServer() server.on('request', (req, res) => { res.end() }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 1 }) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) client.request({ path: '/', method: 'GET' }, (err, data) => { - t.error(err) + p.ifError(err) data.body.resume().on('error', () => { - t.pass() + p.ok(1) }) client[kSocket].destroy() client.request({ path: '/', method: 'GET' }, (err, data) => { - t.error(err) + p.ifError(err) data.body.resume().on('end', () => { - t.pass() + p.ok(1) }) }) }) }) + + await p.completed }) -test('queued request should fail on client destroy', (t) => { - t.plan(6) +test('queued request should fail on client destroy', async (t) => { + const p = tspl(t, { plan: 6 }) const server = createServer() server.on('request', (req, res) => { res.end() }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 1 }) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) let requestErrored = false client.request({ path: '/', method: 'GET' }, (err, data) => { - t.error(err) + p.ifError(err) data.body.resume() .on('error', () => { - t.pass() + p.ok(1) }) client.destroy((err) => { - t.error(err) - t.equal(requestErrored, true) + p.ifError(err) + p.strictEqual(requestErrored, true) }) }) client.request({ @@ -994,26 +1025,28 @@ test('queued request should fail on client destroy', (t) => { opaque: 'asd' }, (err, data) => { requestErrored = true - t.ok(err) - t.equal(data.opaque, 'asd') + p.ok(err) + p.strictEqual(data.opaque, 'asd') }) }) + + await p.completed }) -test('retry idempotent inflight', (t) => { - t.plan(3) +test('retry idempotent inflight', async (t) => { + const p = tspl(t, { plan: 3 }) const server = createServer() server.on('request', (req, res) => { res.end() }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 3 }) - t.teardown(client.close.bind(client)) + t.after(() => client.close.bind(client)()) client.request({ path: '/', @@ -1024,87 +1057,91 @@ test('retry idempotent inflight', (t) => { } }) }, (err) => { - t.ok(err) + p.ok(err) }) client.request({ path: '/', method: 'GET' }, (err, data) => { - t.error(err) + p.ifError(err) data.body.resume() }) client.request({ path: '/', method: 'GET' }, (err, data) => { - t.error(err) + p.ifError(err) data.body.resume() }) }) + + await p.completed }) -test('invalid opts', (t) => { - t.plan(2) +test('invalid opts', async (t) => { + const p = tspl(t, { plan: 2 }) const client = new Client('http://localhost:5000') client.request(null, (err) => { - t.type(err, errors.InvalidArgumentError) + p.ok(err instanceof errors.InvalidArgumentError) }) client.pipeline(null).on('error', (err) => { - t.type(err, errors.InvalidArgumentError) + p.ok(err instanceof errors.InvalidArgumentError) }) + + await p.completed }) -test('default port for http and https', (t) => { - t.plan(4) +test('default port for http and https', async (t) => { + const p = tspl(t, { plan: 4 }) try { new Client(new URL('http://localhost:80')) // eslint-disable-line - t.pass('Should not throw') + p.ok('Should not throw') } catch (err) { - t.fail(err) + p.fail(err) } try { new Client(new URL('http://localhost')) // eslint-disable-line - t.pass('Should not throw') + p.ok('Should not throw') } catch (err) { - t.fail(err) + p.fail(err) } try { new Client(new URL('https://localhost:443')) // eslint-disable-line - t.pass('Should not throw') + p.ok('Should not throw') } catch (err) { - t.fail(err) + p.fail(err) } try { new Client(new URL('https://localhost')) // eslint-disable-line - t.pass('Should not throw') + p.ok('Should not throw') } catch (err) { - t.fail(err) + p.fail(err) } }) -test('CONNECT throws in next tick', (t) => { - t.plan(3) +test('CONNECT throws in next tick', async (t) => { + const p = tspl(t, { plan: 3 }) const server = createServer() server.on('request', (req, res) => { res.end() }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) client.request({ path: '/', method: 'GET' }, (err, data) => { - t.error(err) + p.ifError(err) data.body .on('end', () => { let ticked = false @@ -1112,53 +1149,57 @@ test('CONNECT throws in next tick', (t) => { path: '/', method: 'CONNECT' }, (err) => { - t.ok(err) - t.strictSame(ticked, true) + p.ok(err) + p.strictEqual(ticked, true) }) ticked = true }) .resume() }) }) + + await p.completed }) -test('invalid signal', (t) => { - t.plan(8) +test('invalid signal', async (t) => { + const p = tspl(t, { plan: 8 }) const client = new Client('http://localhost:3333') - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) let ticked = false client.request({ path: '/', method: 'GET', signal: {}, opaque: 'asd' }, (err, { opaque }) => { - t.equal(ticked, true) - t.equal(opaque, 'asd') - t.type(err, errors.InvalidArgumentError) + p.strictEqual(ticked, true) + p.strictEqual(opaque, 'asd') + p.ok(err instanceof errors.InvalidArgumentError) }) client.pipeline({ path: '/', method: 'GET', signal: {} }, () => {}) .on('error', (err) => { - t.equal(ticked, true) - t.type(err, errors.InvalidArgumentError) + p.strictEqual(ticked, true) + p.ok(err instanceof errors.InvalidArgumentError) }) client.stream({ path: '/', method: 'GET', signal: {}, opaque: 'asd' }, () => {}, (err, { opaque }) => { - t.equal(ticked, true) - t.equal(opaque, 'asd') - t.type(err, errors.InvalidArgumentError) + p.strictEqual(ticked, true) + p.strictEqual(opaque, 'asd') + p.ok(err instanceof errors.InvalidArgumentError) }) ticked = true + + await p.completed }) -test('invalid body chunk does not crash', (t) => { - t.plan(1) +test('invalid body chunk does not crash', async (t) => { + const p = tspl(t, { plan: 1 }) const server = createServer() server.on('request', (req, res) => { res.end() }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) client.request({ path: '/', @@ -1170,26 +1211,30 @@ test('invalid body chunk does not crash', (t) => { }), method: 'GET' }, (err) => { - t.equal(err.code, 'ERR_INVALID_ARG_TYPE') + p.strictEqual(err.code, 'ERR_INVALID_ARG_TYPE') }) }) + + await p.completed }) -test('socket errors', t => { - t.plan(2) +test('socket errors', async (t) => { + const p = tspl(t, { plan: 2 }) const client = new Client('http://localhost:5554') - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) client.request({ path: '/', method: 'GET' }, (err, data) => { - t.ok(err) + p.ok(err) // TODO: Why UND_ERR_SOCKET? - t.ok(err.code === 'ECONNREFUSED' || err.code === 'UND_ERR_SOCKET', err.code) - t.end() + p.ok(err.code === 'ECONNREFUSED' || err.code === 'UND_ERR_SOCKET', err.code) + p.end() }) + + await p.completed }) -test('headers overflow', t => { - t.plan(2) +test('headers overflow', (t, done) => { + const p = tspl(t, { plan: 2 }) const server = createServer() server.on('request', (req, res) => { res.writeHead(200, { @@ -1198,64 +1243,65 @@ test('headers overflow', t => { }) res.end() }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { maxHeaderSize: 10 }) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) client.request({ path: '/', method: 'GET' }, (err, data) => { - t.ok(err) - t.equal(err.code, 'UND_ERR_HEADERS_OVERFLOW') - t.end() + p.ok(err) + p.strictEqual(err.code, 'UND_ERR_HEADERS_OVERFLOW') + done() }) }) }) -test('SocketError should expose socket details (net)', (t) => { - t.plan(8) +test('SocketError should expose socket details (net)', async (t) => { + const p = tspl(t, { plan: 8 }) const server = createServer() server.once('request', (req, res) => { res.destroy() }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) client.request({ path: '/', method: 'GET' }, (err, data) => { - t.ok(err instanceof errors.SocketError) + p.ok(err instanceof errors.SocketError) if (err.socket.remoteFamily === 'IPv4') { - t.equal(err.socket.remoteFamily, 'IPv4') - t.equal(err.socket.localAddress, '127.0.0.1') - t.equal(err.socket.remoteAddress, '127.0.0.1') + p.strictEqual(err.socket.remoteFamily, 'IPv4') + p.strictEqual(err.socket.localAddress, '127.0.0.1') + p.strictEqual(err.socket.remoteAddress, '127.0.0.1') } else { - t.equal(err.socket.remoteFamily, 'IPv6') - t.equal(err.socket.localAddress, '::1') - t.equal(err.socket.remoteAddress, '::1') + p.strictEqual(err.socket.remoteFamily, 'IPv6') + p.strictEqual(err.socket.localAddress, '::1') + p.strictEqual(err.socket.remoteAddress, '::1') } - t.type(err.socket.localPort, 'number') - t.type(err.socket.remotePort, 'number') - t.type(err.socket.bytesWritten, 'number') - t.type(err.socket.bytesRead, 'number') + p.ok(typeof err.socket.localPort === 'number') + p.ok(typeof err.socket.remotePort === 'number') + p.ok(typeof err.socket.bytesWritten === 'number') + p.ok(typeof err.socket.bytesRead === 'number') }) }) + await p.completed }) -test('SocketError should expose socket details (tls)', (t) => { - t.plan(8) +test('SocketError should expose socket details (tls)', async (t) => { + const p = tspl(t, { plan: 8 }) const server = https.createServer(pem) server.once('request', (req, res) => { res.destroy() }) - t.teardown(server.close.bind(server)) + t.after(server.close.bind(server)) server.listen(0, () => { const client = new Client(`https://localhost:${server.address().port}`, { @@ -1263,23 +1309,25 @@ test('SocketError should expose socket details (tls)', (t) => { rejectUnauthorized: false } }) - t.teardown(client.destroy.bind(client)) + t.after(client.destroy.bind(client)) client.request({ path: '/', method: 'GET' }, (err, data) => { - t.ok(err instanceof errors.SocketError) + p.ok(err instanceof errors.SocketError) if (err.socket.remoteFamily === 'IPv4') { - t.equal(err.socket.remoteFamily, 'IPv4') - t.equal(err.socket.localAddress, '127.0.0.1') - t.equal(err.socket.remoteAddress, '127.0.0.1') + p.strictEqual(err.socket.remoteFamily, 'IPv4') + p.strictEqual(err.socket.localAddress, '127.0.0.1') + p.strictEqual(err.socket.remoteAddress, '127.0.0.1') } else { - t.equal(err.socket.remoteFamily, 'IPv6') - t.equal(err.socket.localAddress, '::1') - t.equal(err.socket.remoteAddress, '::1') + p.strictEqual(err.socket.remoteFamily, 'IPv6') + p.strictEqual(err.socket.localAddress, '::1') + p.strictEqual(err.socket.remoteAddress, '::1') } - t.type(err.socket.localPort, 'number') - t.type(err.socket.remotePort, 'number') - t.type(err.socket.bytesWritten, 'number') - t.type(err.socket.bytesRead, 'number') + p.ok(typeof err.socket.localPort === 'number') + p.ok(typeof err.socket.remotePort === 'number') + p.ok(typeof err.socket.bytesWritten === 'number') + p.ok(typeof err.socket.bytesRead === 'number') }) }) + + await p.completed }) From c643b85684bce8f7253a638de78bfc2126d384b3 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Fri, 5 Jan 2024 01:07:58 +0900 Subject: [PATCH 04/11] Use `done` instead of `t.end` --- test/node-test/client-dispatch.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/node-test/client-dispatch.js b/test/node-test/client-dispatch.js index d375daede8f..abaa8aeca33 100644 --- a/test/node-test/client-dispatch.js +++ b/test/node-test/client-dispatch.js @@ -787,7 +787,7 @@ test('dispatch onBodySent stream', async (t) => { await p.completed }) -test('dispatch onBodySent async-iterable', (t) => { +test('dispatch onBodySent async-iterable', (t, done) => { const server = http.createServer((req, res) => { res.end('ad') }) @@ -796,7 +796,7 @@ test('dispatch onBodySent async-iterable', (t) => { const toSendBytes = chunks.reduce((a, b) => a + Buffer.byteLength(b), 0) server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.after(client.close.bind(client)) + t.after(() => client.close.bind(client)()) let sentBytes = 0 let currentChunk = 0 client.dispatch({ @@ -817,12 +817,13 @@ test('dispatch onBodySent async-iterable', (t) => { onComplete () { assert.strictEqual(currentChunk, chunks.length) assert.strictEqual(sentBytes, toSendBytes) + done() } }) }) }) -test('dispatch onBodySent throws error', (t) => { +test('dispatch onBodySent throws error', (t, done) => { const server = http.createServer((req, res) => { res.end('ended') }) @@ -843,6 +844,7 @@ test('dispatch onBodySent throws error', (t) => { onError (err) { assert.ok(err instanceof Error) assert.strictEqual(err.message, 'fail') + done() }, onConnect () {}, onHeaders () {}, From 5e1d7012b03f9978ec1fdb6061a31bb75bcee54d Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Sat, 6 Jan 2024 02:10:27 +0900 Subject: [PATCH 05/11] Fix `t.after` --- test/node-test/async_hooks.js | 2 +- test/node-test/client-connect.js | 8 +++--- test/node-test/client-dispatch.js | 42 +++++++++++++++---------------- test/node-test/client-errors.js | 4 +-- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/test/node-test/async_hooks.js b/test/node-test/async_hooks.js index 85970e1e1fe..ccc3250bf39 100644 --- a/test/node-test/async_hooks.js +++ b/test/node-test/async_hooks.js @@ -194,7 +194,7 @@ test('async hooks pipeline handler', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) setCurrentTransaction({ hello: 'world2' }) diff --git a/test/node-test/client-connect.js b/test/node-test/client-connect.js index 430e40a4bc5..64e1dd6b21c 100644 --- a/test/node-test/client-connect.js +++ b/test/node-test/client-connect.js @@ -29,7 +29,7 @@ test('basic connect', async (t) => { server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) const signal = new EE() const promise = client.connect({ @@ -69,7 +69,7 @@ test('connect error', async (t) => { server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) try { await client.connect({ @@ -137,7 +137,7 @@ test('connect wait for empty pipeline', async (t) => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 3 }) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) client.request({ path: '/', @@ -242,7 +242,7 @@ test('basic connect error', async (t) => { server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) const _err = new Error() client.connect({ diff --git a/test/node-test/client-dispatch.js b/test/node-test/client-dispatch.js index abaa8aeca33..503a4f34464 100644 --- a/test/node-test/client-dispatch.js +++ b/test/node-test/client-dispatch.js @@ -112,7 +112,7 @@ test('basic dispatch get', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) const bufs = [] client.dispatch({ @@ -166,7 +166,7 @@ test('trailers dispatch get', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) const bufs = [] client.dispatch({ @@ -214,7 +214,7 @@ test('dispatch onHeaders error', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) const _err = new Error() client.dispatch({ @@ -251,7 +251,7 @@ test('dispatch onComplete error', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) const _err = new Error() client.dispatch({ @@ -288,7 +288,7 @@ test('dispatch onData error', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) const _err = new Error() client.dispatch({ @@ -325,7 +325,7 @@ test('dispatch onConnect error', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) const _err = new Error() client.dispatch({ @@ -375,7 +375,7 @@ test('connect call onUpgrade once', async (t) => { server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) let recvData = '' let count = 0 @@ -427,7 +427,7 @@ test('dispatch onConnect missing', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) client.dispatch({ path: '/', @@ -461,7 +461,7 @@ test('dispatch onHeaders missing', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) client.dispatch({ path: '/', @@ -494,7 +494,7 @@ test('dispatch onData missing', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) client.dispatch({ path: '/', @@ -527,7 +527,7 @@ test('dispatch onComplete missing', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) client.dispatch({ path: '/', @@ -560,7 +560,7 @@ test('dispatch onError missing', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) try { client.dispatch({ @@ -628,7 +628,7 @@ test('dispatch upgrade onUpgrade missing', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) client.dispatch({ path: '/', @@ -659,7 +659,7 @@ test('dispatch pool onError missing', async (t) => { server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) try { client.dispatch({ @@ -686,7 +686,7 @@ test('dispatch onBodySent not a function', async (t) => { server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) client.dispatch({ path: '/', @@ -716,7 +716,7 @@ test('dispatch onBodySent buffer', async (t) => { server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) const body = 'hello 🚀' client.dispatch({ path: '/', @@ -755,7 +755,7 @@ test('dispatch onBodySent stream', async (t) => { const body = stream.Readable.from(chunks) server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) let sentBytes = 0 let currentChunk = 0 client.dispatch({ @@ -796,7 +796,7 @@ test('dispatch onBodySent async-iterable', (t, done) => { const toSendBytes = chunks.reduce((a, b) => a + Buffer.byteLength(b), 0) server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) let sentBytes = 0 let currentChunk = 0 client.dispatch({ @@ -831,7 +831,7 @@ test('dispatch onBodySent throws error', (t, done) => { server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) const body = 'hello' client.dispatch({ path: '/', @@ -865,7 +865,7 @@ test('dispatches in expected order', async (t) => { server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) const dispatches = [] @@ -924,7 +924,7 @@ test('dispatches in expected order for http2', async (t) => { allowH2: true }) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) const dispatches = [] diff --git a/test/node-test/client-errors.js b/test/node-test/client-errors.js index 585a467f456..c0956242c23 100644 --- a/test/node-test/client-errors.js +++ b/test/node-test/client-errors.js @@ -781,7 +781,7 @@ test('validate request body', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) client.request({ path: '/', @@ -1046,7 +1046,7 @@ test('retry idempotent inflight', async (t) => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 3 }) - t.after(() => client.close.bind(client)()) + t.after(() => { client.close() }) client.request({ path: '/', From 7aaff7abfc2b5b0be4adcbc448daa34adf525867 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Sat, 6 Jan 2024 17:03:47 +0900 Subject: [PATCH 06/11] Update `return client.close()` --- test/node-test/async_hooks.js | 2 +- test/node-test/client-connect.js | 8 +++--- test/node-test/client-dispatch.js | 42 +++++++++++++++---------------- test/node-test/client-errors.js | 4 +-- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/test/node-test/async_hooks.js b/test/node-test/async_hooks.js index ccc3250bf39..e670179fec6 100644 --- a/test/node-test/async_hooks.js +++ b/test/node-test/async_hooks.js @@ -194,7 +194,7 @@ test('async hooks pipeline handler', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) setCurrentTransaction({ hello: 'world2' }) diff --git a/test/node-test/client-connect.js b/test/node-test/client-connect.js index 64e1dd6b21c..e25e01d1386 100644 --- a/test/node-test/client-connect.js +++ b/test/node-test/client-connect.js @@ -29,7 +29,7 @@ test('basic connect', async (t) => { server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) const signal = new EE() const promise = client.connect({ @@ -69,7 +69,7 @@ test('connect error', async (t) => { server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) try { await client.connect({ @@ -137,7 +137,7 @@ test('connect wait for empty pipeline', async (t) => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 3 }) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) client.request({ path: '/', @@ -242,7 +242,7 @@ test('basic connect error', async (t) => { server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) const _err = new Error() client.connect({ diff --git a/test/node-test/client-dispatch.js b/test/node-test/client-dispatch.js index 503a4f34464..9d09cde0c1c 100644 --- a/test/node-test/client-dispatch.js +++ b/test/node-test/client-dispatch.js @@ -112,7 +112,7 @@ test('basic dispatch get', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) const bufs = [] client.dispatch({ @@ -166,7 +166,7 @@ test('trailers dispatch get', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) const bufs = [] client.dispatch({ @@ -214,7 +214,7 @@ test('dispatch onHeaders error', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) const _err = new Error() client.dispatch({ @@ -251,7 +251,7 @@ test('dispatch onComplete error', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) const _err = new Error() client.dispatch({ @@ -288,7 +288,7 @@ test('dispatch onData error', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) const _err = new Error() client.dispatch({ @@ -325,7 +325,7 @@ test('dispatch onConnect error', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) const _err = new Error() client.dispatch({ @@ -375,7 +375,7 @@ test('connect call onUpgrade once', async (t) => { server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) let recvData = '' let count = 0 @@ -427,7 +427,7 @@ test('dispatch onConnect missing', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) client.dispatch({ path: '/', @@ -461,7 +461,7 @@ test('dispatch onHeaders missing', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) client.dispatch({ path: '/', @@ -494,7 +494,7 @@ test('dispatch onData missing', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) client.dispatch({ path: '/', @@ -527,7 +527,7 @@ test('dispatch onComplete missing', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) client.dispatch({ path: '/', @@ -560,7 +560,7 @@ test('dispatch onError missing', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) try { client.dispatch({ @@ -628,7 +628,7 @@ test('dispatch upgrade onUpgrade missing', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) client.dispatch({ path: '/', @@ -659,7 +659,7 @@ test('dispatch pool onError missing', async (t) => { server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) try { client.dispatch({ @@ -686,7 +686,7 @@ test('dispatch onBodySent not a function', async (t) => { server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) client.dispatch({ path: '/', @@ -716,7 +716,7 @@ test('dispatch onBodySent buffer', async (t) => { server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) const body = 'hello 🚀' client.dispatch({ path: '/', @@ -755,7 +755,7 @@ test('dispatch onBodySent stream', async (t) => { const body = stream.Readable.from(chunks) server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) let sentBytes = 0 let currentChunk = 0 client.dispatch({ @@ -796,7 +796,7 @@ test('dispatch onBodySent async-iterable', (t, done) => { const toSendBytes = chunks.reduce((a, b) => a + Buffer.byteLength(b), 0) server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) let sentBytes = 0 let currentChunk = 0 client.dispatch({ @@ -831,7 +831,7 @@ test('dispatch onBodySent throws error', (t, done) => { server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) const body = 'hello' client.dispatch({ path: '/', @@ -865,7 +865,7 @@ test('dispatches in expected order', async (t) => { server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) const dispatches = [] @@ -924,7 +924,7 @@ test('dispatches in expected order for http2', async (t) => { allowH2: true }) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) const dispatches = [] diff --git a/test/node-test/client-errors.js b/test/node-test/client-errors.js index c0956242c23..9542247da8f 100644 --- a/test/node-test/client-errors.js +++ b/test/node-test/client-errors.js @@ -781,7 +781,7 @@ test('validate request body', async (t) => { server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) client.request({ path: '/', @@ -1046,7 +1046,7 @@ test('retry idempotent inflight', async (t) => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 3 }) - t.after(() => { client.close() }) + t.after(() => { return client.close() }) client.request({ path: '/', From b36ead756ec36b63a682d9fd19a07d50dede4cd5 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Thu, 11 Jan 2024 22:40:04 +0900 Subject: [PATCH 07/11] Update `client-errors` without `parser error` tests --- test/node-test/client-errors.js | 42 +++++++++++++++++---------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/test/node-test/client-errors.js b/test/node-test/client-errors.js index 9542247da8f..5bb836a6ea8 100644 --- a/test/node-test/client-errors.js +++ b/test/node-test/client-errors.js @@ -13,6 +13,8 @@ const { tspl } = require('@matteo.collina/tspl') const { kSocket } = require('../../lib/core/symbols') const { wrapWithAsyncIterable, maybeWrapStream, consts } = require('../utils/async-iterators') +const { closeServerAsPromise } = require('../utils/node-http') + class IteratorError extends Error {} test('GET errors and reconnect with pipelining 1', async (t) => { @@ -32,7 +34,7 @@ test('GET errors and reconnect with pipelining 1', 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}`, { @@ -86,7 +88,7 @@ test('GET errors and reconnect with pipelining 3', 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}`, { @@ -148,7 +150,7 @@ function errorAndPipelining (type) { 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}`) @@ -223,7 +225,7 @@ function errorAndChunkedEncodingPipelining (type) { 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}`) @@ -564,7 +566,7 @@ test('POST which fails should error response', async (t) => { res.destroy() }) }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -659,7 +661,7 @@ test('client destroy cleanup', async (t) => { }) }) }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { client = new Client(`http://localhost:${server.address().port}`) @@ -689,7 +691,7 @@ test('throwing async-iterator causes error', async (t) => { const server = createServer((req, res) => { res.end(Buffer.alloc(4 + 1, 'a')) }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -723,7 +725,7 @@ test('client async-iterator destroy cleanup', async (t) => { }) }) }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { client = new Client(`http://localhost:${server.address().port}`) @@ -753,7 +755,7 @@ test('GET errors body', async (t) => { res.destroy() }, 19) }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -777,7 +779,7 @@ test('validate request body', async (t) => { const server = createServer((req, res) => { res.end('asd') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -869,7 +871,7 @@ function socketFailWrite (type) { const server = createServer() server.once('request', (req, res) => { }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -910,7 +912,7 @@ function socketFailEndWrite (type) { server.once('request', (req, res) => { res.end() }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { @@ -957,7 +959,7 @@ test('queued request should not fail on socket destroy', async (t) => { server.on('request', (req, res) => { res.end() }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { @@ -996,7 +998,7 @@ test('queued request should fail on client destroy', async (t) => { server.on('request', (req, res) => { res.end() }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { @@ -1040,7 +1042,7 @@ test('retry idempotent inflight', async (t) => { server.on('request', (req, res) => { res.end() }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { @@ -1131,7 +1133,7 @@ test('CONNECT throws in next tick', async (t) => { server.on('request', (req, res) => { res.end() }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -1195,7 +1197,7 @@ test('invalid body chunk does not crash', async (t) => { server.on('request', (req, res) => { res.end() }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -1243,7 +1245,7 @@ test('headers overflow', (t, done) => { }) res.end() }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { @@ -1267,7 +1269,7 @@ test('SocketError should expose socket details (net)', async (t) => { server.once('request', (req, res) => { res.destroy() }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -1301,7 +1303,7 @@ test('SocketError should expose socket details (tls)', async (t) => { server.once('request', (req, res) => { res.destroy() }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`https://localhost:${server.address().port}`, { From 159c39c000c6c9675d6cd3655a27bc7f748c2933 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Thu, 11 Jan 2024 22:56:05 +0900 Subject: [PATCH 08/11] Add FIXME comment --- test/node-test/client-errors.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/node-test/client-errors.js b/test/node-test/client-errors.js index 5bb836a6ea8..daea3712cf0 100644 --- a/test/node-test/client-errors.js +++ b/test/node-test/client-errors.js @@ -847,6 +847,7 @@ test('parser error', async (t) => { server.once('connection', (socket) => { socket.write('asd\n\r213123') }) + // FIXME: use closeServerAsPromise t.after(server.close.bind(server)) server.listen(0, () => { From eca036ca293009c36770ae57a36a38cb3c702bd6 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Thu, 11 Jan 2024 22:58:12 +0900 Subject: [PATCH 09/11] Use `closeServerAsPromise` for `client-dispatch` --- test/node-test/client-dispatch.js | 47 +++++++++++++++---------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/test/node-test/client-dispatch.js b/test/node-test/client-dispatch.js index 9d09cde0c1c..42fbf91b412 100644 --- a/test/node-test/client-dispatch.js +++ b/test/node-test/client-dispatch.js @@ -8,6 +8,7 @@ const stream = require('stream') const { createSecureServer } = require('node:http2') const pem = require('https-pem') const { tspl } = require('@matteo.collina/tspl') +const { closeServerAsPromise, closeClientAndServerAsPromise } = require('../utils/node-http') test('dispatch invalid opts', (t) => { const p = tspl(t, { plan: 14 }) @@ -102,7 +103,7 @@ test('basic dispatch get', async (t) => { p.strictEqual(undefined, req.headers['content-length']) res.end('hello') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) const reqHeaders = { foo: undefined, @@ -157,7 +158,7 @@ test('trailers dispatch get', async (t) => { res.setHeader('Trailer', 'Content-MD5') res.end('hello') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) const reqHeaders = { foo: undefined, @@ -210,7 +211,7 @@ test('dispatch onHeaders error', async (t) => { const server = http.createServer((req, res) => { res.end() }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -247,7 +248,7 @@ test('dispatch onComplete error', async (t) => { const server = http.createServer((req, res) => { res.end() }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -284,7 +285,7 @@ test('dispatch onData error', async (t) => { const server = http.createServer((req, res) => { res.end('ad') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -321,7 +322,7 @@ test('dispatch onConnect error', async (t) => { const server = http.createServer((req, res) => { res.end('ad') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -371,7 +372,7 @@ test('connect call onUpgrade once', async (t) => { socket.end(data) }) }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -423,7 +424,7 @@ test('dispatch onConnect missing', async (t) => { const server = http.createServer((req, res) => { res.end('ad') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -457,7 +458,7 @@ test('dispatch onHeaders missing', async (t) => { const server = http.createServer((req, res) => { res.end('ad') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -490,7 +491,7 @@ test('dispatch onData missing', async (t) => { const server = http.createServer((req, res) => { res.end('ad') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -523,7 +524,7 @@ test('dispatch onComplete missing', async (t) => { const server = http.createServer((req, res) => { res.end('ad') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -556,7 +557,7 @@ test('dispatch onError missing', async (t) => { const server = http.createServer((req, res) => { res.end('ad') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -593,7 +594,7 @@ test('dispatch CONNECT onUpgrade missing', async (t) => { const server = http.createServer((req, res) => { res.end('ad') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -624,7 +625,7 @@ test('dispatch upgrade onUpgrade missing', async (t) => { const server = http.createServer((req, res) => { res.end('ad') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -655,7 +656,7 @@ test('dispatch pool onError missing', async (t) => { const server = http.createServer((req, res) => { res.end('ad') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) @@ -682,7 +683,7 @@ test('dispatch onBodySent not a function', async (t) => { const server = http.createServer((req, res) => { res.end('ad') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) @@ -712,7 +713,7 @@ test('dispatch onBodySent buffer', async (t) => { const server = http.createServer((req, res) => { res.end('ad') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) @@ -749,7 +750,7 @@ test('dispatch onBodySent stream', async (t) => { const server = http.createServer((req, res) => { res.end('ad') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) const chunks = ['he', 'llo', 'world', '🚀'] const toSendBytes = chunks.reduce((a, b) => a + Buffer.byteLength(b), 0) const body = stream.Readable.from(chunks) @@ -791,7 +792,7 @@ test('dispatch onBodySent async-iterable', (t, done) => { const server = http.createServer((req, res) => { res.end('ad') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) const chunks = ['he', 'llo', 'world', '🚀'] const toSendBytes = chunks.reduce((a, b) => a + Buffer.byteLength(b), 0) server.listen(0, () => { @@ -827,7 +828,7 @@ test('dispatch onBodySent throws error', (t, done) => { const server = http.createServer((req, res) => { res.end('ended') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Pool(`http://localhost:${server.address().port}`) @@ -858,7 +859,7 @@ test('dispatches in expected order', async (t) => { const server = http.createServer((req, res) => { res.end('ended') }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) const p = tspl(t, { plan: 1 }) @@ -912,8 +913,6 @@ test('dispatches in expected order for http2', async (t) => { stream.end('ended') }) - t.after(server.close.bind(server)) - const p = tspl(t, { plan: 1 }) server.listen(0, () => { @@ -924,7 +923,7 @@ test('dispatches in expected order for http2', async (t) => { allowH2: true }) - t.after(() => { return client.close() }) + t.after(closeClientAndServerAsPromise(client, server)) const dispatches = [] From 62dd4fff9e79dbab00d02ac6782e54183419ffbb Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Thu, 11 Jan 2024 23:18:19 +0900 Subject: [PATCH 10/11] Use `closeServerAsPromise` for `client-connect` --- test/node-test/client-connect.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/test/node-test/client-connect.js b/test/node-test/client-connect.js index e25e01d1386..a231a10e175 100644 --- a/test/node-test/client-connect.js +++ b/test/node-test/client-connect.js @@ -6,6 +6,7 @@ const http = require('http') const EE = require('events') const { kBusy } = require('../../lib/core/symbols') const { tspl } = require('@matteo.collina/tspl') +const { closeServerAsPromise } = require('../utils/node-http') test('basic connect', async (t) => { const p = tspl(t, { plan: 3 }) @@ -25,7 +26,7 @@ test('basic connect', async (t) => { socket.end(data) }) }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -65,7 +66,7 @@ test('connect error', async (t) => { server.on('connect', (req, socket, firstBodyChunk) => { socket.destroy() }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -131,7 +132,7 @@ test('connect wait for empty pipeline', async (t) => { socket.end(data) }) }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`, { @@ -188,7 +189,7 @@ test('connect aborted', async (t) => { server.on('connect', (req, c, firstBodyChunk) => { p.ok(0) }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { @@ -238,7 +239,7 @@ test('basic connect error', async (t) => { socket.end(data) }) }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -268,7 +269,7 @@ test('connect invalid signal', async (t) => { server.on('connect', (req, c, firstBodyChunk) => { p.ok(0) }) - t.after(server.close.bind(server)) + t.after(closeServerAsPromise(server)) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) @@ -301,6 +302,7 @@ test('connect aborted after connect', async (t) => { server.on('connect', (req, c, firstBodyChunk) => { signal.emit('abort') }) + // FIXME: use closeServerAsPromise t.after(server.close.bind(server)) server.listen(0, () => { From bc3668659331f7b1f8349b2b1f8432efcc764599 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Thu, 11 Jan 2024 23:48:38 +0900 Subject: [PATCH 11/11] Leave some tests on tap --- test/client-connect.js | 38 ++++++++++++++++++++++++++++++++ test/client-errors.js | 28 +++++++++++++++++++++++ test/node-test/client-connect.js | 33 --------------------------- test/node-test/client-errors.js | 26 ---------------------- 4 files changed, 66 insertions(+), 59 deletions(-) create mode 100644 test/client-connect.js create mode 100644 test/client-errors.js diff --git a/test/client-connect.js b/test/client-connect.js new file mode 100644 index 00000000000..4131c6e0a13 --- /dev/null +++ b/test/client-connect.js @@ -0,0 +1,38 @@ +'use strict' + +const { test } = require('tap') +const { Client, errors } = require('..') +const http = require('http') +const EE = require('events') +const { kBusy } = require('../lib/core/symbols') + +// TODO: move to test/node-test/client-connect.js +test('connect aborted after connect', (t) => { + t.plan(3) + + const signal = new EE() + const server = http.createServer((req, res) => { + t.fail() + }) + server.on('connect', (req, c, firstBodyChunk) => { + signal.emit('abort') + }) + t.teardown(server.close.bind(server)) + + server.listen(0, () => { + const client = new Client(`http://localhost:${server.address().port}`, { + pipelining: 3 + }) + t.teardown(client.destroy.bind(client)) + + client.connect({ + path: '/', + signal, + opaque: 'asd' + }, (err, { opaque }) => { + t.equal(opaque, 'asd') + t.type(err, errors.RequestAbortedError) + }) + t.equal(client[kBusy], true) + }) +}) diff --git a/test/client-errors.js b/test/client-errors.js new file mode 100644 index 00000000000..27cc52ba562 --- /dev/null +++ b/test/client-errors.js @@ -0,0 +1,28 @@ +'use strict' + +const { test } = require('tap') +const { Client } = require('..') +const net = require('net') + +// TODO: move to test/node-test/client-connect.js +test('parser error', (t) => { + t.plan(2) + + const server = net.createServer() + server.once('connection', (socket) => { + socket.write('asd\n\r213123') + }) + t.teardown(server.close.bind(server)) + + server.listen(0, () => { + const client = new Client(`http://localhost:${server.address().port}`) + t.teardown(client.destroy.bind(client)) + + client.request({ path: '/', method: 'GET' }, (err) => { + t.ok(err) + client.close((err) => { + t.error(err) + }) + }) + }) +}) diff --git a/test/node-test/client-connect.js b/test/node-test/client-connect.js index a231a10e175..7de9d2e39e3 100644 --- a/test/node-test/client-connect.js +++ b/test/node-test/client-connect.js @@ -291,36 +291,3 @@ test('connect invalid signal', async (t) => { await p.completed }) - -test('connect aborted after connect', async (t) => { - const p = tspl(t, { plan: 3 }) - - const signal = new EE() - const server = http.createServer((req, res) => { - p.ok(0) - }) - server.on('connect', (req, c, firstBodyChunk) => { - signal.emit('abort') - }) - // FIXME: use closeServerAsPromise - t.after(server.close.bind(server)) - - server.listen(0, () => { - const client = new Client(`http://localhost:${server.address().port}`, { - pipelining: 3 - }) - t.after(client.destroy.bind(client)) - - client.connect({ - path: '/', - signal, - opaque: 'asd' - }, (err, { opaque }) => { - p.strictEqual(opaque, 'asd') - p.ok(err instanceof errors.RequestAbortedError) - }) - p.strictEqual(client[kBusy], true) - }) - - await p.completed -}) diff --git a/test/node-test/client-errors.js b/test/node-test/client-errors.js index daea3712cf0..72ae7c7a0fd 100644 --- a/test/node-test/client-errors.js +++ b/test/node-test/client-errors.js @@ -6,7 +6,6 @@ const { Client, Pool, errors } = require('../..') const { createServer } = require('http') const https = require('https') const pem = require('https-pem') -const net = require('net') const { Readable } = require('stream') const { tspl } = require('@matteo.collina/tspl') @@ -840,31 +839,6 @@ test('validate request body', async (t) => { await p.completed }) -test('parser error', async (t) => { - const p = tspl(t, { plan: 2 }) - - const server = net.createServer() - server.once('connection', (socket) => { - socket.write('asd\n\r213123') - }) - // FIXME: use closeServerAsPromise - t.after(server.close.bind(server)) - - server.listen(0, () => { - const client = new Client(`http://localhost:${server.address().port}`) - t.after(client.destroy.bind(client)) - - client.request({ path: '/', method: 'GET' }, (err) => { - p.ok(err) - client.close((err) => { - p.ifError(err) - }) - }) - }) - - await p.completed -}) - function socketFailWrite (type) { test(`socket fail while writing ${type} request body`, async (t) => { const p = tspl(t, { plan: 2 })