Skip to content

Commit 4e84603

Browse files
committed
test: consolidate port-change tests into single deterministic test
Replace 3 timing-dependent real-timer tests with one fake-timer test that covers port-change detection, debug logging, and backoff reset.
1 parent 48d7b3e commit 4e84603

1 file changed

Lines changed: 26 additions & 76 deletions

File tree

test/unit/remote/sshProcess.test.ts

Lines changed: 26 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ describe("SshProcessMonitor", () => {
3636
});
3737

3838
afterEach(() => {
39+
vi.useRealTimers();
3940
for (const m of activeMonitors) {
4041
m.dispose();
4142
}
@@ -205,106 +206,55 @@ describe("SshProcessMonitor", () => {
205206
});
206207

207208
it("resets backoff when port changes in log file", async () => {
208-
// Start with port 11111, no process on it
209+
vi.useFakeTimers();
210+
209211
vol.fromJSON({
210212
"/logs/ms-vscode-remote.remote-ssh/1-Remote - SSH.log":
211213
"-> socksPort 11111 ->",
212214
});
213-
214-
// No process found initially, then process found after port change
215215
vi.mocked(find).mockResolvedValue([]);
216216

217+
const pollInterval = 100;
217218
const logger = createMockLogger();
218219
const monitor = createMonitor({
219220
codeLogDir: "/logs/window1",
220-
discoveryPollIntervalMs: 10,
221-
maxDiscoveryBackoffMs: 5000,
221+
discoveryPollIntervalMs: pollInterval,
222+
maxDiscoveryBackoffMs: 10_000,
222223
logger,
223224
});
224225

225-
// Wait for several search attempts with backoff growing
226-
await new Promise((r) => setTimeout(r, 80));
227-
228-
// Now change the port in the log — simulates VS Code reconnection
229-
vol.fromJSON({
230-
"/logs/ms-vscode-remote.remote-ssh/1-Remote - SSH.log":
231-
"-> socksPort 22222 ->",
232-
});
233-
234-
// After port change, make find return a process
235-
vi.mocked(find).mockResolvedValue([
236-
{ pid: 555, ppid: 1, name: "ssh", cmd: "ssh" },
237-
]);
238-
239-
// The process should be found quickly since backoff resets on port change
240-
const pid = await waitForEvent(monitor.onPidChange, 2000);
241-
expect(pid).toBe(555);
226+
const pids: Array<number | undefined> = [];
227+
monitor.onPidChange((pid) => pids.push(pid));
242228

243-
// Verify port change was logged
229+
// Backoff doubles each iteration: 100, 200, 400, 800, 1600, ...
230+
// Total after 5 iterations = pollInterval * (2^5 - 1) = 3100ms
231+
const fiveIterationsMs = pollInterval * (2 ** 5 - 1);
232+
await vi.advanceTimersByTimeAsync(fiveIterationsMs - 1);
244233
expect(logger.debug).toHaveBeenCalledWith(
245-
"SSH port changed in log file: 11111 -> 22222",
234+
"No process found listening on port 11111",
246235
);
247-
});
248236

249-
it("logs when port found but no process listening", async () => {
237+
// Change port, simulates VS Code reconnection after sleep/wake
250238
vol.fromJSON({
251239
"/logs/ms-vscode-remote.remote-ssh/1-Remote - SSH.log":
252-
"-> socksPort 12345 ->",
253-
});
254-
255-
vi.mocked(find).mockResolvedValue([]);
256-
257-
const logger = createMockLogger();
258-
const monitor = createMonitor({
259-
codeLogDir: "/logs/window1",
260-
logger,
240+
"-> socksPort 22222 ->",
261241
});
262242

263-
// Wait for at least one search attempt
264-
await new Promise((r) => setTimeout(r, 30));
265-
monitor.dispose();
266-
243+
// Trigger next iteration: detects port change, resets backoff, no pid
244+
await vi.advanceTimersByTimeAsync(1);
267245
expect(logger.debug).toHaveBeenCalledWith(
268-
"No process found listening on port 12345",
246+
"SSH port changed in log file: 11111 -> 22222",
269247
);
270-
});
271-
272-
it("detects port change across search attempts", async () => {
273-
vol.fromJSON({
274-
"/logs/ms-vscode-remote.remote-ssh/1-Remote - SSH.log":
275-
"-> socksPort 11111 ->",
276-
});
277-
278-
// First attempt: port 11111 with no process
279-
// After port changes: port 22222 with process
280-
let callCount = 0;
281-
vi.mocked(find).mockImplementation(() => {
282-
callCount++;
283-
if (callCount >= 3) {
284-
return Promise.resolve([
285-
{ pid: 777, ppid: 1, name: "ssh", cmd: "ssh" },
286-
]);
287-
}
288-
return Promise.resolve([]);
289-
});
290248

291-
const logger = createMockLogger();
292-
const monitor = createMonitor({
293-
codeLogDir: "/logs/window1",
294-
logger,
295-
});
296-
297-
// Wait for first attempts with port 11111
298-
await new Promise((r) => setTimeout(r, 30));
299-
300-
// Change port
301-
vol.fromJSON({
302-
"/logs/ms-vscode-remote.remote-ssh/1-Remote - SSH.log":
303-
"-> socksPort 22222 ->",
304-
});
249+
// Process becomes available
250+
vi.mocked(find).mockResolvedValue([
251+
{ pid: 555, ppid: 1, name: "ssh", cmd: "ssh" },
252+
]);
305253

306-
const pid = await waitForEvent(monitor.onPidChange, 2000);
307-
expect(pid).toBe(777);
254+
// With reset backoff, process found within 2 poll intervals.
255+
// Without reset, backoff would be pollInterval * 2^5 = 3200ms.
256+
await vi.advanceTimersByTimeAsync(pollInterval * 2);
257+
expect(pids).toContain(555);
308258
});
309259

310260
it("does not fire event when same process is found after stale check", async () => {

0 commit comments

Comments
 (0)