@@ -20,6 +20,31 @@ describe('utils/get-free-port', () => {
2020 expect ( result ) . toBeLessThan ( 65536 )
2121 } )
2222
23+ it ( 'never returns a port that is taken on 0.0.0.0, the address the preview server binds' , async ( ) => {
24+ // occupy the base port (8000) with an IPv4-only listener, like a leftover preview server;
25+ // a hostless probe binds the IPv6 wildcard and, on macOS, misses this listener entirely
26+ const blocker = net . createServer ( )
27+ blocker . unref ( )
28+ const blocked = await new Promise < boolean > ( ( resolve ) => {
29+ blocker . once ( 'error' , ( ) => resolve ( false ) )
30+ blocker . listen ( 8000 , '0.0.0.0' , ( ) => resolve ( true ) )
31+ } )
32+ try {
33+ const result = await getPort ( NaN , 123 )
34+ if ( blocked ) expect ( result ) . not . toBe ( 8000 )
35+ // the returned port must be bindable on 0.0.0.0, exactly like the real server binds it
36+ const server = net . createServer ( )
37+ server . unref ( )
38+ await new Promise < void > ( ( resolve , reject ) => {
39+ server . once ( 'error' , reject )
40+ server . listen ( result , '0.0.0.0' , ( ) => resolve ( ) )
41+ } )
42+ await new Promise ( ( resolve ) => server . close ( resolve ) )
43+ } finally {
44+ if ( blocked ) await new Promise ( ( resolve ) => blocker . close ( resolve ) )
45+ }
46+ } )
47+
2348 it ( 'should return the fail-over port when probing fails' , async ( ) => {
2449 jest . spyOn ( net , 'createServer' ) . mockImplementation ( ( ) => {
2550 throw new Error ( 'probe failed' )
0 commit comments