Skip to content

Commit 6ea5d9c

Browse files
committed
test_runner: bootstrap reporters before running tests
1 parent 16aacfa commit 6ea5d9c

File tree

5 files changed

+30
-12
lines changed

5 files changed

+30
-12
lines changed

‎doc/api/test.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,9 @@ added:
684684
**Default:**`false`.
685685
*`files`:{Array} An array containing the list of files to run.
686686
**Default** matching files from [test runner execution model][].
687+
*`setup`{Function} A function that accepts the TestsStream instance
688+
and can be used to setup listeners before any tests are run.
689+
**Default:**`undefined`.
687690
*`signal`{AbortSignal} Allows aborting an in-progress test execution.
688691
*`timeout`{number} A number of milliseconds the test execution will
689692
fail after.

‎lib/internal/main/test_runner.js‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ if (isUsingInspector()){
2222
inspectPort=process.debugPort;
2323
}
2424

25-
consttestsStream=run({ concurrency, inspectPort,watch: getOptionValue('--watch')});
26-
testsStream.once('test:fail',()=>{
25+
run({ concurrency, inspectPort,watch: getOptionValue('--watch'),setup: setupTestReporters})
26+
.once('test:fail',()=>{
2727
process.exitCode=kGenericUserError;
2828
});
29-
setupTestReporters(testsStream);

‎lib/internal/test_runner/harness.js‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,29 +161,35 @@ function setup(root){
161161
}
162162

163163
letglobalRoot;
164+
letreportersSetup;
164165
functiongetGlobalRoot(){
165166
if(!globalRoot){
166167
globalRoot=createTestTree();
167168
globalRoot.reporter.once('test:fail',()=>{
168169
process.exitCode=kGenericUserError;
169170
});
170-
setupTestReporters(globalRoot.reporter);
171+
reportersSetup=setupTestReporters(globalRoot.reporter);
171172
}
172173
returnglobalRoot;
173174
}
174175

176+
asyncfunctionstartSubtest(subtest){
177+
awaitreportersSetup;
178+
awaitsubtest.start();
179+
}
180+
175181
functiontest(name,options,fn){
176182
constparent=testResources.get(executionAsyncId())||getGlobalRoot();
177183
constsubtest=parent.createSubtest(Test,name,options,fn);
178-
returnsubtest.start();
184+
returnstartSubtest(subtest);
179185
}
180186

181187
functionrunInParentContext(Factory){
182188
functionrun(name,options,fn,overrides){
183189
constparent=testResources.get(executionAsyncId())||getGlobalRoot();
184190
constsubtest=parent.createSubtest(Factory,name,options,fn,overrides);
185191
if(parent===getGlobalRoot()){
186-
subtest.start();
192+
startSubtest(subtest);
187193
}
188194
}
189195

‎lib/internal/test_runner/runner.js‎

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ const{
1313
ObjectAssign,
1414
ObjectKeys,
1515
PromisePrototypeThen,
16+
SafePromiseAll,
1617
SafePromiseAllReturnVoid,
1718
SafePromiseAllSettledReturnVoid,
19+
PromiseResolve,
1820
SafeMap,
1921
SafeSet,
2022
StringPrototypeIndexOf,
@@ -24,6 +26,7 @@ const{
2426

2527
const{ spawn }=require('child_process');
2628
const{ readdirSync, statSync }=require('fs');
29+
const{ finished }=require('internal/streams/end-of-stream');
2730
// TODO(aduh95): switch to internal/readline/interface when backporting to Node.js 16.x is no longer a concern.
2831
const{ createInterface }=require('readline');
2932
const{ FilesWatcher }=require('internal/watch_mode/files_watcher');
@@ -33,7 +36,7 @@ const{
3336
ERR_TEST_FAILURE,
3437
},
3538
}=require('internal/errors');
36-
const{ validateArray, validateBoolean }=require('internal/validators');
39+
const{ validateArray, validateBoolean, validateFunction}=require('internal/validators');
3740
const{ getInspectPort, isUsingInspector, isInspectorMessage }=require('internal/util/inspector');
3841
const{ kEmptyObject }=require('internal/util');
3942
const{ createTestTree }=require('internal/test_runner/harness');
@@ -299,7 +302,10 @@ function runTestFile(path, root, inspectPort, filesWatcher){
299302
subtest.addToReport(ast);
300303
});
301304

302-
const{0: code,1: signal}=awaitonce(child,'exit',{signal: t.signal});
305+
const{0: {0: code,1: signal}}=awaitSafePromiseAll([
306+
once(child,'exit',{signal: t.signal}),
307+
finished(parser,{signal: t.signal}),
308+
]);
303309

304310
runningProcesses.delete(path);
305311
runningSubtests.delete(path);
@@ -348,14 +354,17 @@ function run(options){
348354
if(options===null||typeofoptions!=='object'){
349355
options=kEmptyObject;
350356
}
351-
const{ concurrency, timeout, signal, files, inspectPort, watch }=options;
357+
const{ concurrency, timeout, signal, files, inspectPort, watch, setup}=options;
352358

353359
if(files!=null){
354360
validateArray(files,'options.files');
355361
}
356362
if(watch!=null){
357363
validateBoolean(watch,'options.watch');
358364
}
365+
if(setup!=null){
366+
validateFunction(setup,'options.setup');
367+
}
359368

360369
constroot=createTestTree({ concurrency, timeout, signal });
361370
consttestFiles=files??createTestFileList();
@@ -366,13 +375,13 @@ function run(options){
366375
filesWatcher=watchFiles(testFiles,root,inspectPort);
367376
postRun=undefined;
368377
}
369-
370-
PromisePrototypeThen(SafePromiseAllSettledReturnVoid(testFiles,(path)=>{
378+
construnFiles=()=>SafePromiseAllSettledReturnVoid(testFiles,(path)=>{
371379
constsubtest=runTestFile(path,root,inspectPort,filesWatcher);
372380
runningSubtests.set(path,subtest);
373381
returnsubtest;
374-
}),postRun);
382+
});
375383

384+
PromisePrototypeThen(PromisePrototypeThen(PromiseResolve(setup?.(root.reporter)),runFiles),postRun);
376385

377386
returnroot.reporter;
378387
}

‎lib/internal/test_runner/test.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ const{
5050
validateUint32,
5151
}=require('internal/validators');
5252
const{ setTimeout }=require('timers/promises');
53+
const{ setInterval, clearInterval }=require('timers');
5354
const{TIMEOUT_MAX}=require('internal/timers');
5455
const{ availableParallelism }=require('os');
5556
const{bigint: hrtime}=process.hrtime;

0 commit comments

Comments
(0)