Skip to content

Commit

Permalink
client-connect
Browse files Browse the repository at this point in the history
  • Loading branch information
sosukesuzuki committed Jan 11, 2024
1 parent 0cab13b commit 00c7cd2
Showing 1 changed file with 89 additions and 73 deletions.
162 changes: 89 additions & 73 deletions test/client-connect.js → test/node-test/client-connect.js
Original file line number Diff line number Diff line change
@@ -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')
Expand All @@ -24,97 +25,101 @@ 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) => {
recvData += d
})

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) => {
res.end()
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()
Expand All @@ -126,95 +131,100 @@ 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({
path: '/',
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')
Expand All @@ -228,81 +238,87 @@ 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({
path: '/',
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
})

0 comments on commit 00c7cd2

Please sign in to comment.