import test from 'brittle'
import { waitForSidecarSock, needsReregister } from '../lib/sidecar-wait.js'
// A fake clock + sleep so the poll loop runs instantly and
// deterministically — no real timers, no real filesystem.
function fakeTime () {
let t = 0
return {
now: () => t,
sleep: (ms) => { t += ms; return Promise.resolve() }
}
}
test('returns true immediately when the socket already exists', async (t) => {
const clock = fakeTime()
let calls = 0
const ok = await waitForSidecarSock({
sock: '/x/svc.sock',
exists: () => { calls++; return true },
now: clock.now,
sleep: clock.sleep
})
t.is(ok, true)
t.is(calls, 1, 'checks once, never sleeps')
})
test('waits, then returns true once the socket appears (the boot race)', async (t) => {
const clock = fakeTime()
let checks = 0
// Absent for the first 5 polls, then the sidecar creates its socket.
const ok = await waitForSidecarSock({
sock: '/x/svc.sock',
timeoutMs: 120000,
intervalMs: 1000,
exists: () => ++checks > 5,
now: clock.now,
sleep: clock.sleep
})
t.is(ok, true)
t.is(checks, 6, 'polled until the socket appeared')
t.is(clock.now(), 5000, 'slept 5 intervals while waiting')
})
test('returns false when the deadline passes (sidecar never comes up)', async (t) => {
const clock = fakeTime()
const ok = await waitForSidecarSock({
sock: '/x/svc.sock',
timeoutMs: 3000,
intervalMs: 1000,
exists: () => false,
now: clock.now,
sleep: clock.sleep
})
t.is(ok, false)
})
test('bails out early when shouldStop() flips (daemon shutting down)', async (t) => {
const clock = fakeTime()
let stopping = false
let checks = 0
const ok = await waitForSidecarSock({
sock: '/x/svc.sock',
timeoutMs: 120000,
intervalMs: 1000,
exists: () => { if (++checks >= 3) stopping = true; return false },
shouldStop: () => stopping,
now: clock.now,
sleep: clock.sleep
})
t.is(ok, false, 'stops without waiting for the deadline')
})
test('needsReregister: true when the sidecar has forgotten us', (t) => {
// Sidecar restarted → in-memory registry empty → found:false.
t.is(needsReregister({ found: false }, 1234), true, 'found:false → re-register')
t.is(needsReregister(null, 1234), true, 'null lookup → re-register')
t.is(needsReregister(undefined, 1234), true, 'undefined → re-register')
})
test('needsReregister: true when a stale entry has a different pid', (t) => {
t.is(needsReregister({ found: true, pid: 999 }, 1234), true,
'someone else / previous instance registered → reclaim')
})
test('needsReregister: false when the sidecar already knows this instance', (t) => {
t.is(needsReregister({ found: true, pid: 1234 }, 1234), false,
'our pid registered → no churn')
// pid absent on either side shouldn't force needless re-registration.
t.is(needsReregister({ found: true }, 1234), false, 'no recorded pid → trust found')
t.is(needsReregister({ found: true, pid: 999 }, null), false, 'no self pid → trust found')
})