@@ -20,10 +20,12 @@ const {
20
20
SafeSet,
21
21
SafePromiseAll,
22
22
SafePromiseRace,
23
+ SymbolDispose,
24
+ ObjectDefineProperty,
23
25
Symbol,
24
26
} = primordials ;
27
+ const { addAbortListener } = require ( 'events' ) ;
25
28
const { AsyncResource } = require ( 'async_hooks' ) ;
26
- const { once } = require ( 'events' ) ;
27
29
const { AbortController } = require ( 'internal/abort_controller' ) ;
28
30
const {
29
31
codes : {
@@ -52,7 +54,7 @@ const {
52
54
validateOneOf,
53
55
validateUint32,
54
56
} = require ( 'internal/validators' ) ;
55
- const { setTimeout } = require ( 'timers/promises ' ) ;
57
+ const { setTimeout } = require ( 'timers' ) ;
56
58
const { TIMEOUT_MAX } = require ( 'internal/timers' ) ;
57
59
const { availableParallelism } = require ( 'os' ) ;
58
60
const { bigint : hrtime } = process . hrtime ;
@@ -76,15 +78,42 @@ const { testNamePatterns, testOnlyFlag } = parseCommandLine();
76
78
let kResistStopPropagation ;
77
79
78
80
function stopTest ( timeout , signal ) {
81
+ const deferred = createDeferredPromise ( ) ;
82
+ const abortListener = addAbortListener ( signal , deferred . resolve ) ;
83
+ let timer ;
84
+ let disposeFunction ;
85
+
79
86
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
+ } ;
81
108
}
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 ,
87
115
} ) ;
116
+ return deferred . promise ;
88
117
}
89
118
90
119
class TestContext {
@@ -549,14 +578,16 @@ class Test extends AsyncResource {
549
578
}
550
579
} ) ;
551
580
581
+ let stopPromise ;
582
+
552
583
try {
553
584
if ( this . parent ?. hooks . before . length > 0 ) {
554
585
await this . parent . runHook ( 'before' , this . parent . getRunArgs ( ) ) ;
555
586
}
556
587
if ( this . parent ?. hooks . beforeEach . length > 0 ) {
557
588
await this . parent . runHook ( 'beforeEach' , { __proto__ : null , args, ctx } ) ;
558
589
}
559
- const stopPromise = stopTest ( this . timeout , this . signal ) ;
590
+ stopPromise = stopTest ( this . timeout , this . signal ) ;
560
591
const runArgs = ArrayPrototypeSlice ( args ) ;
561
592
ArrayPrototypeUnshift ( runArgs , this . fn , ctx ) ;
562
593
@@ -603,6 +634,8 @@ class Test extends AsyncResource {
603
634
this . fail ( new ERR_TEST_FAILURE ( err , kTestCodeFailure ) ) ;
604
635
}
605
636
} finally {
637
+ stopPromise ?. [ SymbolDispose ] ( ) ;
638
+
606
639
// Do not abort hooks and the root test as hooks instance are shared between tests suite so aborting them will
607
640
// cause them to not run for further tests.
608
641
if ( this . parent !== null ) {
@@ -817,6 +850,7 @@ class Suite extends Test {
817
850
async run ( ) {
818
851
const hookArgs = this . getRunArgs ( ) ;
819
852
853
+ let stopPromise ;
820
854
try {
821
855
this . parent . activeSubtests ++ ;
822
856
await this . buildSuite ;
@@ -834,7 +868,7 @@ class Suite extends Test {
834
868
835
869
await this . runHook ( 'before' , hookArgs ) ;
836
870
837
- const stopPromise = stopTest ( this . timeout , this . signal ) ;
871
+ stopPromise = stopTest ( this . timeout , this . signal ) ;
838
872
const subtests = this . skipped || this . error ? [ ] : this . subtests ;
839
873
const promise = SafePromiseAll ( subtests , ( subtests ) => subtests . start ( ) ) ;
840
874
@@ -848,6 +882,8 @@ class Suite extends Test {
848
882
} else {
849
883
this . fail ( new ERR_TEST_FAILURE ( err , kTestCodeFailure ) ) ;
850
884
}
885
+ } finally {
886
+ stopPromise ?. [ SymbolDispose ] ( ) ;
851
887
}
852
888
853
889
this . postRun ( ) ;
0 commit comments