Skip to content

Commit ec33fb2

Browse files
committed
test(daemon): pin the dead-pid replacement on a port the fresh daemon cannot reuse
The fresh stand-in binds before the dead port is picked, and the test asserts the replacement spawn ran and the one dead probe failed; it skips when the host recycled the exited pid.
1 parent 3646f1b commit ec33fb2

1 file changed

Lines changed: 12 additions & 8 deletions

File tree

‎src/daemon-client/__tests__/daemon-client-stalled-probe.test.ts‎

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -218,9 +218,6 @@ test('sendToDaemon replaces a daemon whose process is gone after a single probe'
218218
await gone.wait.catch(() => {});
219219
const deadPid = gone.child.pid;
220220
assert.ok(deadPid, 'spawned child should have a pid');
221-
const unused = net.createServer();
222-
const deadPort = await listenOnLoopback(unused);
223-
await closeLoopbackServer(unused);
224221
const fresh = net.createServer((socket) => {
225222
socket.setEncoding('utf8');
226223
socket.on('data', () => {
@@ -246,7 +243,12 @@ test('sendToDaemon replaces a daemon whose process is gone after a single probe'
246243
};
247244

248245
try {
246+
// Bound before the dead port is picked, so the port the dead daemon recorded cannot be
247+
// handed back to the fresh one.
249248
const freshPort = await listenOnLoopback(fresh);
249+
const unused = net.createServer();
250+
const deadPort = await listenOnLoopback(unused);
251+
await closeLoopbackServer(unused);
250252
writeInfo(deadPort, deadPid);
251253
mockSpawnDaemon.mockImplementation(() => {
252254
writeInfo(freshPort, process.pid);
@@ -255,15 +257,17 @@ test('sendToDaemon replaces a daemon whose process is gone after a single probe'
255257
probeAnswers.length = 0;
256258
probedPorts.length = 0;
257259
mockEmitDiagnostic.mockClear();
260+
if (isProcessAlive(deadPid)) {
261+
t.skip('the host recycled the exited stand-in pid before the probe');
262+
return;
263+
}
258264

259265
const response = await sendSmoke(stateDir);
260266

261267
assert.deepEqual(response, { ok: true, data: { via: 'fresh-daemon' } });
262-
assert.equal(
263-
probedPorts.filter((port) => port === deadPort).length,
264-
1,
265-
'a daemon whose pid is gone gets no patient retry',
266-
);
268+
assert.equal(mockSpawnDaemon.mock.calls.length, 1, 'the dead daemon was replaced');
269+
const deadProbes = probeAnswers.filter((_, index) => probedPorts[index] === deadPort);
270+
assert.deepEqual(deadProbes, [false], 'a daemon whose pid is gone gets no patient retry');
267271
assert.equal(
268272
mockEmitDiagnostic.mock.calls.some(([event]) => event.phase === 'daemon_probe_recovered'),
269273
false,

0 commit comments

Comments
 (0)