@@ -148,14 +148,15 @@ describe("pm2-control", () => {
148148 } ) ;
149149
150150 it ( "waits for the previous PM2 app to disappear before starting a replacement" , async ( ) => {
151+ const previousPid = 999_990 ;
151152 describeProcess
152153 . mockImplementationOnce (
153154 ( _name : string , callback : ( error : Error | null , result : unknown [ ] ) => void ) =>
154- callback ( null , [ { pid : 111 , pm2_env : { status : "online" , restart_time : 0 } } ] )
155+ callback ( null , [ { pid : previousPid , pm2_env : { status : "online" , restart_time : 0 } } ] )
155156 )
156157 . mockImplementationOnce (
157158 ( _name : string , callback : ( error : Error | null , result : unknown [ ] ) => void ) =>
158- callback ( null , [ { pid : 111 , pm2_env : { status : "stopping" , restart_time : 0 } } ] )
159+ callback ( null , [ { pid : previousPid , pm2_env : { status : "stopping" , restart_time : 0 } } ] )
159160 )
160161 . mockImplementationOnce (
161162 ( _name : string , callback : ( error : Error | null , result : unknown [ ] ) => void ) =>
@@ -180,14 +181,15 @@ describe("pm2-control", () => {
180181 } ) ;
181182
182183 it ( "reuses one pm2 session while polling deletion during startup" , async ( ) => {
184+ const previousPid = 999_992 ;
183185 describeProcess
184186 . mockImplementationOnce (
185187 ( _name : string , callback : ( error : Error | null , result : unknown [ ] ) => void ) =>
186- callback ( null , [ { pid : 111 , pm2_env : { status : "online" , restart_time : 0 } } ] )
188+ callback ( null , [ { pid : previousPid , pm2_env : { status : "online" , restart_time : 0 } } ] )
187189 )
188190 . mockImplementationOnce (
189191 ( _name : string , callback : ( error : Error | null , result : unknown [ ] ) => void ) =>
190- callback ( null , [ { pid : 111 , pm2_env : { status : "stopping" , restart_time : 0 } } ] )
192+ callback ( null , [ { pid : previousPid , pm2_env : { status : "stopping" , restart_time : 0 } } ] )
191193 )
192194 . mockImplementationOnce (
193195 ( _name : string , callback : ( error : Error | null , result : unknown [ ] ) => void ) =>
@@ -204,15 +206,55 @@ describe("pm2-control", () => {
204206 expect ( disconnect ) . toHaveBeenCalledTimes ( 1 ) ;
205207 } ) ;
206208
209+ it ( "waits for the previous process pid to exit before starting a replacement" , async ( ) => {
210+ const previousPid = 999_991 ;
211+ const killSpy = vi . spyOn ( process , "kill" ) ;
212+ killSpy
213+ . mockImplementationOnce ( ( ) => true )
214+ . mockImplementationOnce ( ( ) => true )
215+ . mockImplementationOnce ( ( ) => {
216+ const error = new Error ( "process not found" ) as NodeJS . ErrnoException ;
217+ error . code = "ESRCH" ;
218+ throw error ;
219+ } ) ;
220+ describeProcess
221+ . mockImplementationOnce (
222+ ( _name : string , callback : ( error : Error | null , result : unknown [ ] ) => void ) =>
223+ callback ( null , [ { pid : previousPid , pm2_env : { status : "online" , restart_time : 0 } } ] )
224+ )
225+ . mockImplementationOnce (
226+ ( _name : string , callback : ( error : Error | null , result : unknown [ ] ) => void ) =>
227+ callback ( null , [ ] )
228+ ) ;
229+
230+ const pendingStart = startManagedServer ( {
231+ script : "/cli/dist/esm/server-runner.js" ,
232+ cwd : "/repo" ,
233+ waitMs : 10 ,
234+ } ) ;
235+
236+ await expect (
237+ Promise . race ( [
238+ pendingStart . then ( ( ) => "started" ) ,
239+ new Promise ( ( resolve ) => setTimeout ( ( ) => resolve ( "waiting" ) , 20 ) ) ,
240+ ] )
241+ ) . resolves . toBe ( "waiting" ) ;
242+
243+ expect ( start ) . not . toHaveBeenCalled ( ) ;
244+ await pendingStart ;
245+ expect ( killSpy ) . toHaveBeenCalledWith ( previousPid , 0 ) ;
246+ } ) ;
247+
207248 it ( "keeps waiting during startup when delete reports missing but the old app still lingers" , async ( ) => {
249+ const previousPid = 999_993 ;
208250 describeProcess
209251 . mockImplementationOnce (
210252 ( _name : string , callback : ( error : Error | null , result : unknown [ ] ) => void ) =>
211- callback ( null , [ { pid : 111 , pm2_env : { status : "online" , restart_time : 0 } } ] )
253+ callback ( null , [ { pid : previousPid , pm2_env : { status : "online" , restart_time : 0 } } ] )
212254 )
213255 . mockImplementationOnce (
214256 ( _name : string , callback : ( error : Error | null , result : unknown [ ] ) => void ) =>
215- callback ( null , [ { pid : 111 , pm2_env : { status : "stopping" , restart_time : 0 } } ] )
257+ callback ( null , [ { pid : previousPid , pm2_env : { status : "stopping" , restart_time : 0 } } ] )
216258 )
217259 . mockImplementationOnce (
218260 ( _name : string , callback : ( error : Error | null , result : unknown [ ] ) => void ) =>
0 commit comments