@@ -3,20 +3,18 @@ const { |
3 | 3 | ArrayFrom, |
4 | 4 | ArrayPrototypeFilter, |
5 | 5 | ArrayPrototypeIncludes, |
| 6 | + ArrayPrototypeJoin, |
6 | 7 | ArrayPrototypePush, |
7 | 8 | ArrayPrototypeSlice, |
8 | 9 | ArrayPrototypeSort, |
9 | | - Promise, |
10 | | - PromiseAll, |
11 | | - SafeArrayIterator, |
| 10 | + SafePromiseAll, |
12 | 11 | SafeSet, |
13 | 12 | } = primordials; |
14 | 13 | const { |
15 | 14 | prepareMainThreadExecution, |
16 | 15 | } = require('internal/bootstrap/pre_execution'); |
17 | 16 | const { spawn } = require('child_process'); |
18 | 17 | const { readdirSync, statSync } = require('fs'); |
19 | | -const { finished } = require('internal/streams/end-of-stream'); |
20 | 18 | const console = require('internal/console/global'); |
21 | 19 | const { |
22 | 20 | codes: { |
@@ -30,6 +28,7 @@ const { |
30 | 28 | doesPathMatchFilter, |
31 | 29 | } = require('internal/test_runner/utils'); |
32 | 30 | const { basename, join, resolve } = require('path'); |
| 31 | +const { once } = require('events'); |
33 | 32 | const kFilterArgs = ['--test']; |
34 | 33 |
|
35 | 34 | prepareMainThreadExecution(false); |
@@ -102,53 +101,39 @@ function filterExecArgv(arg) { |
102 | 101 | } |
103 | 102 |
|
104 | 103 | function 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; |
151 | 115 | }); |
| 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 | + } |
152 | 137 | }); |
153 | 138 | } |
154 | 139 |
|
|