@@ -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