@@ -20,10 +20,12 @@ const {
2020 SafeSet,
2121 SafePromiseAll,
2222 SafePromiseRace,
23+ SymbolDispose,
24+ ObjectDefineProperty,
2325 Symbol,
2426} = primordials ;
27+ const { addAbortListener } = require ( 'events' ) ;
2528const { AsyncResource } = require ( 'async_hooks' ) ;
26- const { once } = require ( 'events' ) ;
2729const { AbortController } = require ( 'internal/abort_controller' ) ;
2830const {
2931 codes : {
@@ -52,7 +54,7 @@ const {
5254 validateOneOf,
5355 validateUint32,
5456} = require ( 'internal/validators' ) ;
55- const { setTimeout } = require ( 'timers/promises ' ) ;
57+ const { setTimeout } = require ( 'timers' ) ;
5658const { TIMEOUT_MAX } = require ( 'internal/timers' ) ;
5759const { availableParallelism } = require ( 'os' ) ;
5860const { bigint : hrtime } = process . hrtime ;
@@ -76,15 +78,42 @@ const { testNamePatterns, testOnlyFlag } = parseCommandLine();
7678let kResistStopPropagation ;
7779
7880function stopTest ( timeout , signal ) {
81+ const deferred = createDeferredPromise ( ) ;
82+ const abortListener = addAbortListener ( signal , deferred . resolve ) ;
83+ let timer ;
84+ let disposeFunction ;
85+
7986 if ( timeout === kDefaultTimeout ) {
80- return once ( signal , 'abort' ) ;
87+ disposeFunction = abortListener [ SymbolDispose ] ;
88+ } if ( timeout !== kDefaultTimeout ) {
89+ timer = setTimeout ( ( ) => deferred . resolve ( ) , timeout ) ;
90+ timer . unref ( ) ;
91+
92+ ObjectDefineProperty ( deferred , 'promise' , {
93+ __proto__ : null ,
94+ configurable : true ,
95+ writable : true ,
96+ value : PromisePrototypeThen ( deferred . promise , ( ) => {
97+ throw new ERR_TEST_FAILURE (
98+ `test timed out after ${ timeout } ms` ,
99+ kTestTimeoutFailure ,
100+ ) ;
101+ } ) ,
102+ } ) ;
103+
104+ disposeFunction = ( ) => {
105+ abortListener [ SymbolDispose ] ( ) ;
106+ timer [ SymbolDispose ] ( ) ;
107+ } ;
81108 }
82- return PromisePrototypeThen ( setTimeout ( timeout , null , { __proto__ : null , ref : false , signal } ) , ( ) => {
83- throw new ERR_TEST_FAILURE (
84- `test timed out after ${ timeout } ms` ,
85- kTestTimeoutFailure ,
86- ) ;
109+
110+ ObjectDefineProperty ( deferred . promise , SymbolDispose , {
111+ __proto__ : null ,
112+ configurable : true ,
113+ writable : true ,
114+ value : disposeFunction ,
87115 } ) ;
116+ return deferred . promise ;
88117}
89118
90119class TestContext {
@@ -549,14 +578,16 @@ class Test extends AsyncResource {
549578 }
550579 } ) ;
551580
581+ let stopPromise ;
582+
552583 try {
553584 if ( this . parent ?. hooks . before . length > 0 ) {
554585 await this . parent . runHook ( 'before' , this . parent . getRunArgs ( ) ) ;
555586 }
556587 if ( this . parent ?. hooks . beforeEach . length > 0 ) {
557588 await this . parent . runHook ( 'beforeEach' , { __proto__ : null , args, ctx } ) ;
558589 }
559- const stopPromise = stopTest ( this . timeout , this . signal ) ;
590+ stopPromise = stopTest ( this . timeout , this . signal ) ;
560591 const runArgs = ArrayPrototypeSlice ( args ) ;
561592 ArrayPrototypeUnshift ( runArgs , this . fn , ctx ) ;
562593
@@ -603,6 +634,8 @@ class Test extends AsyncResource {
603634 this . fail ( new ERR_TEST_FAILURE ( err , kTestCodeFailure ) ) ;
604635 }
605636 } finally {
637+ stopPromise ?. [ SymbolDispose ] ( ) ;
638+
606639 // Do not abort hooks and the root test as hooks instance are shared between tests suite so aborting them will
607640 // cause them to not run for further tests.
608641 if ( this . parent !== null ) {
@@ -817,6 +850,7 @@ class Suite extends Test {
817850 async run ( ) {
818851 const hookArgs = this . getRunArgs ( ) ;
819852
853+ let stopPromise ;
820854 try {
821855 this . parent . activeSubtests ++ ;
822856 await this . buildSuite ;
@@ -834,7 +868,7 @@ class Suite extends Test {
834868
835869 await this . runHook ( 'before' , hookArgs ) ;
836870
837- const stopPromise = stopTest ( this . timeout , this . signal ) ;
871+ stopPromise = stopTest ( this . timeout , this . signal ) ;
838872 const subtests = this . skipped || this . error ? [ ] : this . subtests ;
839873 const promise = SafePromiseAll ( subtests , ( subtests ) => subtests . start ( ) ) ;
840874
@@ -848,6 +882,8 @@ class Suite extends Test {
848882 } else {
849883 this . fail ( new ERR_TEST_FAILURE ( err , kTestCodeFailure ) ) ;
850884 }
885+ } finally {
886+ stopPromise ?. [ SymbolDispose ] ( ) ;
851887 }
852888
853889 this . postRun ( ) ;
0 commit comments