@@ -555,6 +555,55 @@ describe("OpenSSHMasterPool", () => {
555555 pool . clearAll ( ) ;
556556 } ) ;
557557
558+ test ( "ensureReadyMaster schedules idle cleanup after bootstrapping a shard" , async ( ) => {
559+ const pool = new OpenSSHMasterPool ( {
560+ maxSessionsPerShard : 1 ,
561+ maxShardsPerHost : 1 ,
562+ sleep : ( ) => Promise . resolve ( ) ,
563+ spawnProcess : ( ( _command : string , args ?: readonly string [ ] ) => {
564+ const proc = new FakeChildProcess ( ) ;
565+ const normalizedArgs = [ ...( args ?? [ ] ) ] ;
566+
567+ if ( normalizedArgs . includes ( "-M" ) ) {
568+ const controlPathArg = normalizedArgs . find ( ( arg ) => arg . startsWith ( "ControlPath=" ) ) ;
569+ if ( controlPathArg ) {
570+ masterProcesses . set ( controlPathArg . slice ( "ControlPath=" . length ) , proc ) ;
571+ }
572+ return proc as never ;
573+ }
574+
575+ const controlPathIndex = normalizedArgs . indexOf ( "-S" ) ;
576+ const controlPath =
577+ controlPathIndex >= 0 ? normalizedArgs [ controlPathIndex + 1 ] : undefined ;
578+ queueMicrotask ( ( ) => {
579+ if ( normalizedArgs . includes ( "check" ) && controlPath && masterProcesses . has ( controlPath ) ) {
580+ proc . exitCode = 0 ;
581+ }
582+ proc . emit ( "close" , proc . exitCode ?? 1 , null ) ;
583+ } ) ;
584+ return proc as never ;
585+ } ) as unknown as typeof spawnProcess ,
586+ } ) ;
587+
588+ const config : SSHConnectionConfig = { host : "remote.example.com" , port : 22 } ;
589+ await pool . ensureReadyMaster ( config , { maxWaitMs : 0 , timeoutMs : 1000 } ) ;
590+
591+ const internals = pool as unknown as {
592+ hostGroups : Map <
593+ string ,
594+ { shards : Array < { inflight : number ; idleTimer ?: ReturnType < typeof setTimeout > } > }
595+ > ;
596+ } ;
597+ const shard = [ ...internals . hostGroups . values ( ) ] [ 0 ] ?. shards [ 0 ] ;
598+ if ( ! shard ) {
599+ throw new Error ( "Expected a tracked shard" ) ;
600+ }
601+ expect ( shard . inflight ) . toBe ( 0 ) ;
602+ expect ( shard . idleTimer ) . toBeDefined ( ) ;
603+
604+ pool . clearAll ( ) ;
605+ } ) ;
606+
558607 test ( "retries transient shard startup failures within the maxWait budget" , async ( ) => {
559608 let startupAttempts = 0 ;
560609 const pool = new OpenSSHMasterPool ( {
0 commit comments