@@ -3,20 +3,18 @@ const {
33 ArrayFrom,
44 ArrayPrototypeFilter,
55 ArrayPrototypeIncludes,
6+ ArrayPrototypeJoin,
67 ArrayPrototypePush,
78 ArrayPrototypeSlice,
89 ArrayPrototypeSort,
9- Promise,
10- PromiseAll,
11- SafeArrayIterator,
10+ SafePromiseAll,
1211 SafeSet,
1312} = primordials ;
1413const {
1514 prepareMainThreadExecution,
1615} = require ( 'internal/bootstrap/pre_execution' ) ;
1716const { spawn } = require ( 'child_process' ) ;
1817const { readdirSync, statSync } = require ( 'fs' ) ;
19- const { finished } = require ( 'internal/streams/end-of-stream' ) ;
2018const console = require ( 'internal/console/global' ) ;
2119const {
2220 codes : {
@@ -30,6 +28,7 @@ const {
3028 doesPathMatchFilter,
3129} = require ( 'internal/test_runner/utils' ) ;
3230const { basename, join, resolve } = require ( 'path' ) ;
31+ const { once } = require ( 'events' ) ;
3332const kFilterArgs = [ '--test' ] ;
3433
3534prepareMainThreadExecution ( false ) ;
@@ -102,53 +101,39 @@ function filterExecArgv(arg) {
102101}
103102
104103function runTestFile ( path ) {
105- return test ( path , ( ) => {
106- return new Promise ( ( resolve , reject ) => {
107- const args = ArrayPrototypeFilter ( process . execArgv , filterExecArgv ) ;
108- ArrayPrototypePush ( args , path ) ;
109-
110- const child = spawn ( process . execPath , args ) ;
111- // TODO(cjihrig): Implement a TAP parser to read the child's stdout
112- // instead of just displaying it all if the child fails.
113- let stdout = '' ;
114- let stderr = '' ;
115- let err ;
116-
117- child . on ( 'error' , ( error ) => {
118- err = error ;
119- } ) ;
120-
121- child . stdout . setEncoding ( 'utf8' ) ;
122- child . stderr . setEncoding ( 'utf8' ) ;
123-
124- child . stdout . on ( 'data' , ( chunk ) => {
125- stdout += chunk ;
126- } ) ;
127-
128- child . stderr . on ( 'data' , ( chunk ) => {
129- stderr += chunk ;
130- } ) ;
131-
132- child . once ( 'exit' , async ( code , signal ) => {
133- if ( code !== 0 || signal !== null ) {
134- if ( ! err ) {
135- await PromiseAll ( new SafeArrayIterator ( [ finished ( child . stderr ) , finished ( child . stdout ) ] ) ) ;
136- err = new ERR_TEST_FAILURE ( 'test failed' , kSubtestsFailed ) ;
137- err . exitCode = code ;
138- err . signal = signal ;
139- err . stdout = stdout ;
140- err . stderr = stderr ;
141- // The stack will not be useful since the failures came from tests
142- // in a child process.
143- err . stack = undefined ;
144- }
145-
146- return reject ( err ) ;
147- }
148-
149- resolve ( ) ;
150- } ) ;
104+ return test ( path , async ( t ) => {
105+ const args = ArrayPrototypeFilter ( process . execArgv , filterExecArgv ) ;
106+ ArrayPrototypePush ( args , path ) ;
107+
108+ const child = spawn ( process . execPath , args , { signal : t . signal , encoding : 'utf8' } ) ;
109+ // TODO(cjihrig): Implement a TAP parser to read the child's stdout
110+ // instead of just displaying it all if the child fails.
111+ let err ;
112+
113+ child . on ( 'error' , ( error ) => {
114+ err = error ;
151115 } ) ;
116+
117+ const { 0 : { code, signal } , 1 : stdout , 2 : stderr } = await SafePromiseAll ( [
118+ once ( child , 'exit' , { signal : t . signal } ) ,
119+ child . stdout . toArray ( { signal : t . signal } ) ,
120+ child . stderr . toArray ( { signal : t . signal } ) ,
121+ ] ) ;
122+
123+ if ( code !== 0 || signal !== null ) {
124+ if ( ! err ) {
125+ err = new ERR_TEST_FAILURE ( 'test failed' , kSubtestsFailed ) ;
126+ err . exitCode = code ;
127+ err . signal = signal ;
128+ err . stdout = ArrayPrototypeJoin ( stdout , '' ) ;
129+ err . stderr = ArrayPrototypeJoin ( stderr , '' ) ;
130+ // The stack will not be useful since the failures came from tests
131+ // in a child process.
132+ err . stack = undefined ;
133+ }
134+
135+ throw err ;
136+ }
152137 } ) ;
153138}
154139
0 commit comments