Files

72 lines
2.8 KiB
JavaScript
Raw Permalink Normal View History

/**
* 覆盖网络 S3 · 实例端口区间单测(不连外网、只在本机回环上 bind)。
* 运行:node --test test/instance-port.test.mjs(已含在 npm test / npm verify 中)
*
* ## 这个测试防的是什么
* `listen(0)` 让**每台 worker 各自**随机取端口,而跨机实例的隧道落点全挤在 Manager 的
* `127.0.0.1` 上 ⇒ 两台 worker 取到同号就撞号,`ssh -R` 失败还是**静默**的,
* Manager 会按该端口拨到**别人的实例**(2026-09-16 实测)。
*
* 所以这里要钉死两件事:
* ① 取到的端口**必须落在配置区间内**(区间隔离的前提)
* ② 起点被占 ⇒ **跳到下一个**,绝不"回落到 `listen(0)`"
*/
import { test } from 'node:test'
import assert from 'node:assert/strict'
import { createServer } from 'node:net'
import { findFreePortInRange, findInstancePort } from '../lib/supervisor/spawn.js'
/** 占住一个回环端口,返回 `{ port, release }`。 */
function holdPort() {
return new Promise((resolve, reject) => {
const server = createServer()
server.once('error', reject)
server.listen(0, '127.0.0.1', () => {
const address = server.address()
const port = typeof address === 'object' && address !== null ? address.port : 0
resolve({ port, release: () => new Promise((r) => server.close(() => r())) })
})
})
}
test('端口区间:取到的端口必须落在区间内', async () => {
// 用打洞拿到的空闲端口当区间起点 ⇒ 测试不依赖"20000 一定空着"这种环境假设
const { port, release } = await holdPort()
try {
const got = await findFreePortInRange(port, 200)
assert.ok(got >= port && got < port + 200, `越界:${got} 不在 [${port}, ${port + 200})`)
} finally {
await release()
}
})
test('端口区间:起点被占用 ⇒ 跳过它,不回落到 listen(0)', async () => {
const { port, release } = await holdPort()
try {
const got = await findFreePortInRange(port, 200)
assert.notEqual(got, port, '起点被占却仍返回了它 ⇒ 会撞号')
assert.ok(got >= port && got < port + 200)
} finally {
await release()
}
})
test('端口区间:区间耗尽 ⇒ 抛错(禁止静默退回 listen(0))', async () => {
await assert.rejects(() => findFreePortInRange(20000, 0), /区间已耗尽/)
})
test('findInstancePort:未配区间(base<=0)⇒ 退回旧的 listen(0) 行为', async () => {
const got = await findInstancePort(0, 1000)
assert.ok(got > 0 && got < 65536, `应拿到合法端口,实际 ${got}`)
})
test('findInstancePort:配了区间 ⇒ 结果落在区间内', async () => {
const { port, release } = await holdPort()
try {
const got = await findInstancePort(port, 128)
assert.ok(got >= port && got < port + 128, `越界:${got}`)
} finally {
await release()
}
})