11const path = require ( 'node:path' ) ;
2+ const net = require ( 'node:net' ) ;
23const { rspack } = require ( '@rspack/core' ) ;
34const { RspackDevServer : Server } = require ( '@rspack/dev-server' ) ;
45const config = require ( '../fixtures/client-config/rspack.config' ) ;
56const runBrowser = require ( '../helpers/run-browser' ) ;
67const sessionSubscribe = require ( '../helpers/session-subscribe' ) ;
8+ const {
9+ getRandomPorts,
10+ releaseRandomPorts,
11+ } = require ( '../helpers/get-random-port' ) ;
712const port = require ( '../helpers/ports-map' ) . api ;
813
914describe ( 'API' , ( ) => {
@@ -337,12 +342,19 @@ describe('API', () => {
337342 } ) ;
338343
339344 describe ( 'Server.getFreePort' , ( ) => {
345+ let basePort ;
346+ let reservedPorts = [ ] ;
340347 let dummyServers = [ ] ;
341348 let devServerPort ;
342349
350+ beforeEach ( async ( ) => {
351+ reservedPorts = await getRandomPorts ( 8 , '0.0.0.0' ) ;
352+ [ basePort ] = reservedPorts ;
353+ } ) ;
354+
343355 afterEach ( ( ) => {
344- process . env . RSPACK_DEV_SERVER_BASE_PORT = undefined ;
345- process . env . RSPACK_DEV_SERVER_PORT_RETRY = undefined ;
356+ delete process . env . RSPACK_DEV_SERVER_BASE_PORT ;
357+ delete process . env . RSPACK_DEV_SERVER_PORT_RETRY ;
346358
347359 return dummyServers
348360 . reduce (
@@ -359,18 +371,20 @@ describe('API', () => {
359371 )
360372 . then ( ( ) => {
361373 dummyServers = [ ] ;
374+ releaseRandomPorts ( reservedPorts ) ;
375+ reservedPorts = [ ] ;
362376 } ) ;
363377 } ) ;
364378
365379 function createDummyServers ( n ) {
366- process . env . RSPACK_DEV_SERVER_BASE_PORT = 60000 ;
380+ process . env . RSPACK_DEV_SERVER_BASE_PORT = ` ${ basePort } ` ;
367381
368382 return ( Array . isArray ( n ) ? n : [ ...new Array ( n ) ] ) . reduce (
369383 ( p , _ , i ) =>
370384 p . then (
371385 ( ) =>
372386 new Promise ( ( resolve ) => {
373- devServerPort = 60000 + i ;
387+ devServerPort = basePort + i ;
374388 const compiler = rspack ( config ) ;
375389 const server = new Server (
376390 { port : devServerPort , host : '0.0.0.0' } ,
@@ -407,7 +421,7 @@ describe('API', () => {
407421
408422 const freePort = await Server . getFreePort ( null ) ;
409423
410- expect ( freePort ) . toEqual ( 60000 + retryCount ) ;
424+ expect ( freePort ) . toEqual ( basePort + retryCount ) ;
411425
412426 const { page, browser } = await runBrowser ( ) ;
413427
@@ -447,7 +461,7 @@ describe('API', () => {
447461 // eslint-disable-next-line no-undefined
448462 const freePort = await Server . getFreePort ( undefined ) ;
449463
450- expect ( freePort ) . toEqual ( 60000 + retryCount ) ;
464+ expect ( freePort ) . toEqual ( basePort + retryCount ) ;
451465
452466 const { page, browser } = await runBrowser ( ) ;
453467
@@ -486,7 +500,7 @@ describe('API', () => {
486500
487501 const freePort = await Server . getFreePort ( ) ;
488502
489- expect ( freePort ) . toEqual ( 60000 + retryCount ) ;
503+ expect ( freePort ) . toEqual ( basePort + retryCount ) ;
490504
491505 const { page, browser } = await runBrowser ( ) ;
492506
@@ -525,7 +539,7 @@ describe('API', () => {
525539
526540 const freePort = await Server . getFreePort ( ) ;
527541
528- expect ( freePort ) . toEqual ( 60000 + retryCount ) ;
542+ expect ( freePort ) . toEqual ( basePort + retryCount ) ;
529543
530544 const { page, browser } = await runBrowser ( ) ;
531545
@@ -556,15 +570,15 @@ describe('API', () => {
556570 } ) ;
557571
558572 it ( 'should retry finding the port when serial ports are busy' , async ( ) => {
559- const busyPorts = [ 60000 , 60001 , 60002 , 60003 , 60004 , 60005 ] ;
573+ const busyPorts = reservedPorts . slice ( 0 , 6 ) ;
560574
561575 process . env . RSPACK_DEV_SERVER_PORT_RETRY = 1000 ;
562576
563577 await createDummyServers ( busyPorts ) ;
564578
565579 const freePort = await Server . getFreePort ( ) ;
566580
567- expect ( freePort ) . toBeGreaterThan ( 60005 ) ;
581+ expect ( freePort ) . toBeGreaterThan ( busyPorts [ busyPorts . length - 1 ] ) ;
568582
569583 const { page, browser } = await runBrowser ( ) ;
570584
@@ -597,16 +611,50 @@ describe('API', () => {
597611 } ) ;
598612
599613 it ( "should throw the error when the port isn't found" , async ( ) => {
600- rs . doMockRequire (
601- '../../dist/getPort' ,
602- ( ) => ( ) => Promise . reject ( new Error ( 'busy' ) ) ,
603- ) ;
614+ const busyServers = [ ] ;
615+ const busyPorts = [ 65534 , 65535 ] ;
604616
605- process . env . RSPACK_DEV_SERVER_PORT_RETRY = 1 ;
617+ try {
618+ await Promise . all (
619+ busyPorts . map (
620+ ( busyPort ) =>
621+ new Promise ( ( resolve , reject ) => {
622+ const server = net . createServer ( ) ;
623+
624+ server . unref ( ) ;
625+ server . on ( 'error' , reject ) ;
626+ server . listen ( busyPort , '0.0.0.0' , ( ) => {
627+ busyServers . push ( server ) ;
628+ resolve ( ) ;
629+ } ) ;
630+ } ) ,
631+ ) ,
632+ ) ;
606633
607- const { RspackDevServer : Server } = require ( '@rspack/dev-server' ) ;
634+ process . env . RSPACK_DEV_SERVER_BASE_PORT = '65534' ;
635+ process . env . RSPACK_DEV_SERVER_PORT_RETRY = 0 ;
608636
609- await expect ( Server . getFreePort ( ) ) . rejects . toThrowErrorMatchingSnapshot ( ) ;
637+ await expect (
638+ Server . getFreePort ( ) ,
639+ ) . rejects . toThrowErrorMatchingSnapshot ( ) ;
640+ } finally {
641+ await Promise . all (
642+ busyServers . map (
643+ ( server ) =>
644+ new Promise ( ( resolve , reject ) => {
645+ server . close ( ( error ) => {
646+ if ( error ) {
647+ reject ( error ) ;
648+
649+ return ;
650+ }
651+
652+ resolve ( ) ;
653+ } ) ;
654+ } ) ,
655+ ) ,
656+ ) ;
657+ }
610658 } ) ;
611659 } ) ;
612660
0 commit comments