67 lines
1.9 KiB
JavaScript
67 lines
1.9 KiB
JavaScript
import test from 'brittle'
|
|
import net from 'node:net'
|
|
import {
|
|
bindFallbackEnabled,
|
|
isAddrInUse,
|
|
listenTcpWithFallback,
|
|
readListeningTcpPort,
|
|
BARE_OS_BIND_FALLBACK_ENV
|
|
} from './lib/posix/bare-os-bind-fallback.js'
|
|
|
|
test('bindFallbackEnabled', (t) => {
|
|
t.ok(bindFallbackEnabled({}))
|
|
t.ok(bindFallbackEnabled({ [BARE_OS_BIND_FALLBACK_ENV]: '1' }))
|
|
t.absent(bindFallbackEnabled({ [BARE_OS_BIND_FALLBACK_ENV]: '0' }))
|
|
t.absent(bindFallbackEnabled({ [BARE_OS_BIND_FALLBACK_ENV]: 'false' }))
|
|
})
|
|
|
|
test('isAddrInUse', (t) => {
|
|
t.ok(isAddrInUse(Object.assign(new Error('x'), { code: 'EADDRINUSE' })))
|
|
t.absent(isAddrInUse(Object.assign(new Error('x'), { code: 'ENOENT' })))
|
|
t.ok(isAddrInUse(new Error('listen EADDRINUSE: address already in use')))
|
|
})
|
|
|
|
test('listenTcpWithFallback picks ephemeral when preferred port busy', async (t) => {
|
|
const hog = net.createServer()
|
|
await new Promise((resolve, reject) => {
|
|
hog.once('error', reject)
|
|
hog.listen(0, '127.0.0.1', resolve)
|
|
})
|
|
const hogPort = readListeningTcpPort(hog, 0)
|
|
t.ok(Number.isFinite(hogPort) && hogPort > 0)
|
|
|
|
const srv = net.createServer()
|
|
const { port } = await listenTcpWithFallback(
|
|
srv,
|
|
hogPort,
|
|
'127.0.0.1',
|
|
{}
|
|
)
|
|
t.not(port, hogPort)
|
|
t.ok(port > 0)
|
|
|
|
await new Promise((resolve) => srv.close(resolve))
|
|
await new Promise((resolve) => hog.close(resolve))
|
|
})
|
|
|
|
test('listenTcpWithFallback strict env rethrows EADDRINUSE', async (t) => {
|
|
const hog = net.createServer()
|
|
await new Promise((resolve, reject) => {
|
|
hog.once('error', reject)
|
|
hog.listen(0, '127.0.0.1', resolve)
|
|
})
|
|
const hogPort = readListeningTcpPort(hog, 0)
|
|
|
|
const srv = net.createServer()
|
|
try {
|
|
await listenTcpWithFallback(srv, hogPort, '127.0.0.1', {
|
|
[BARE_OS_BIND_FALLBACK_ENV]: '0'
|
|
})
|
|
t.fail('expected EADDRINUSE')
|
|
} catch (e) {
|
|
t.ok(isAddrInUse(e))
|
|
}
|
|
|
|
await new Promise((resolve) => hog.close(resolve))
|
|
})
|