mirror of
https://github.com/stablyai/orca.git
synced 2026-10-26 08:02:44 +00:00
test(daemon): pin the connection/hello shutdown barriers with a mutation-killing test
The shuttingDown guards in handleConnection and handleFirstMessage had no test that fails when either is deleted — the existing coverage drove routeRequest directly or never sent a hello. Raise only the barrier flag while the listener still accepts, then assert a pre-admitted socket's late valid hello and a brand-new connection are both destroyed unregistered. Verified: deleting either guard fails this test. Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
@@ -55,6 +55,7 @@ type DaemonServerPrivate = {
|
||||
}
|
||||
>
|
||||
idleExit: { isArmed(): boolean } | null
|
||||
shuttingDown: boolean
|
||||
routeRequest(clientId: string, request: DaemonRequest): Promise<unknown>
|
||||
}
|
||||
|
||||
@@ -687,6 +688,42 @@ describe('DaemonServer', () => {
|
||||
expect(daemon.clients.size).toBe(0)
|
||||
})
|
||||
|
||||
it('destroys sockets that connect or hello after the shutdown barrier is raised', async () => {
|
||||
// Why raise only the flag: while the listener is still accepting, the
|
||||
// handleConnection/handleFirstMessage barriers are the only defense
|
||||
// against a socket becoming a client on a half-shut server.
|
||||
await startServer()
|
||||
const daemon = server as unknown as DaemonServerPrivate
|
||||
|
||||
// Admitted before the barrier, hello still unsent.
|
||||
const preBarrier = connect(socketPath)
|
||||
await new Promise<void>((resolve) => preBarrier.once('connect', resolve))
|
||||
const preBarrierClosed = new Promise<void>((resolve) => preBarrier.once('close', resolve))
|
||||
preBarrier.on('error', () => {})
|
||||
|
||||
daemon.shuttingDown = true
|
||||
|
||||
// A valid late hello must be destroyed unanswered, never registered.
|
||||
preBarrier.write(
|
||||
encodeNdjson({
|
||||
type: 'hello',
|
||||
version: PROTOCOL_VERSION,
|
||||
token: readFileSync(tokenPath, 'utf-8').trim(),
|
||||
clientId: 'late-hello',
|
||||
role: 'control'
|
||||
})
|
||||
)
|
||||
await preBarrierClosed
|
||||
expect(daemon.clients.size).toBe(0)
|
||||
|
||||
// A brand-new connection after the barrier is destroyed on arrival.
|
||||
const postBarrier = connect(socketPath)
|
||||
const postBarrierClosed = new Promise<void>((resolve) => postBarrier.once('close', resolve))
|
||||
postBarrier.on('error', () => {})
|
||||
await postBarrierClosed
|
||||
expect(daemon.clients.size).toBe(0)
|
||||
})
|
||||
|
||||
it('never fires while a session is alive and exits after the last session ends', async () => {
|
||||
// Why seed the session before start(): start() is what arms the
|
||||
// countdown, so with a session already present the timer never arms at
|
||||
|
||||
Reference in New Issue
Block a user