@@ -9,10 +9,10 @@ vi.mock("node:child_process", async () => {
99 } ;
1010} ) ;
1111
12- const tryListenOnPortMock = vi . hoisted ( ( ) => vi . fn ( ) ) ;
12+ const probePortUsageMock = vi . hoisted ( ( ) => vi . fn ( ) ) ;
1313
1414vi . mock ( "../infra/ports-probe.js" , ( ) => ( {
15- tryListenOnPort : ( ...args : unknown [ ] ) => tryListenOnPortMock ( ...args ) ,
15+ probePortUsage : ( ...args : unknown [ ] ) => probePortUsageMock ( ...args ) ,
1616} ) ) ;
1717
1818import { execFileSync } from "node:child_process" ;
@@ -33,10 +33,8 @@ describe("gateway --force helpers", () => {
3333 vi . clearAllMocks ( ) ;
3434 originalKill = process . kill . bind ( process ) ;
3535 originalPlatform = process . platform ;
36- tryListenOnPortMock . mockReset ( ) ;
37- tryListenOnPortMock . mockRejectedValue (
38- Object . assign ( new Error ( "in use" ) , { code : "EADDRINUSE" } ) ,
39- ) ;
36+ probePortUsageMock . mockReset ( ) ;
37+ probePortUsageMock . mockResolvedValue ( "busy" ) ;
4038 // Pin to linux so all lsof tests are platform-invariant.
4139 Object . defineProperty ( process , "platform" , { value : "linux" , configurable : true } ) ;
4240 } ) ;
@@ -65,7 +63,7 @@ describe("gateway --force helpers", () => {
6563 } ) ;
6664
6765 it ( "skips lsof when the port is already bindable" , async ( ) => {
68- tryListenOnPortMock . mockResolvedValue ( undefined ) ;
66+ probePortUsageMock . mockResolvedValue ( "free" ) ;
6967
7068 const result = await forceFreePortAndWait ( 18789 , { timeoutMs : 500 , intervalMs : 100 } ) ;
7169
@@ -199,9 +197,7 @@ describe("gateway --force helpers", () => {
199197 }
200198 return "18789/tcp: 4242\n" ;
201199 } ) ;
202- tryListenOnPortMock
203- . mockRejectedValueOnce ( Object . assign ( new Error ( "in use" ) , { code : "EADDRINUSE" } ) )
204- . mockResolvedValue ( undefined ) ;
200+ probePortUsageMock . mockResolvedValueOnce ( "busy" ) . mockResolvedValue ( "free" ) ;
205201
206202 const result = await forceFreePortAndWait ( 18789 , { timeoutMs : 500 , intervalMs : 100 } ) ;
207203
@@ -231,13 +227,12 @@ describe("gateway --force helpers", () => {
231227 return "" ;
232228 } ) ;
233229
234- const busyErr = Object . assign ( new Error ( "in use" ) , { code : "EADDRINUSE" } ) ;
235- tryListenOnPortMock
236- . mockRejectedValueOnce ( busyErr )
237- . mockRejectedValueOnce ( busyErr )
238- . mockRejectedValueOnce ( busyErr )
239- . mockRejectedValueOnce ( busyErr )
240- . mockResolvedValueOnce ( undefined ) ;
230+ probePortUsageMock
231+ . mockResolvedValueOnce ( "busy" )
232+ . mockResolvedValueOnce ( "busy" )
233+ . mockResolvedValueOnce ( "busy" )
234+ . mockResolvedValueOnce ( "busy" )
235+ . mockResolvedValue ( "free" ) ;
241236
242237 const promise = forceFreePortAndWait ( 18789 , {
243238 timeoutMs : 300 ,
@@ -258,6 +253,8 @@ describe("gateway --force helpers", () => {
258253 } ) ;
259254
260255 it ( "throws when lsof is unavailable and fuser is missing" , async ( ) => {
256+ // An inconclusive four-host probe must continue into the cleanup tools.
257+ probePortUsageMock . mockResolvedValue ( "unknown" ) ;
261258 ( execFileSync as unknown as Mock ) . mockImplementation ( ( cmd : string ) => {
262259 const err = new Error ( `spawnSync ${ cmd } ENOENT` ) as NodeJS . ErrnoException ;
263260 err . code = "ENOENT" ;
0 commit comments