Skip to content

Commit b15378c

Browse files
refackaddaleax
authored andcommitted
test: improve async-hooks/test-callback-error
PR-URL: #13559 Fixes: #13527 Reviewed-By: Andreas Madsen <[email protected]>
1 parent 46756ac commit b15378c

File tree

2 files changed

+121
-36
lines changed

2 files changed

+121
-36
lines changed

test/async-hooks/async-hooks.status

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
prefix async-hooks
2+
3+
# To mark a test as flaky, list the test name in the appropriate section
4+
# below, without ".js", followed by ": PASS,FLAKY". Example:
5+
# sample-test : PASS,FLAKY
6+
7+
[true] # This section applies to all platforms
8+
9+
[$system==win32]
10+
11+
[$system==linux]
12+
test-callback-error : PASS,FLAKY
13+
14+
[$system==macos]
15+
test-callback-error : PASS,FLAKY
16+
17+
[$arch==arm || $arch==arm64]
18+
19+
[$system==solaris] # Also applies to SmartOS
20+
21+
[$system==freebsd]
+100-36
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,120 @@
11
'use strict';
2-
32
const common = require('../common');
43
const assert = require('assert');
5-
const spawnSync = require('child_process').spawnSync;
4+
const { spawnSync, fork } = require('child_process');
65
const async_hooks = require('async_hooks');
76
const initHooks = require('./init-hooks');
87

9-
switch (process.argv[2]) {
8+
const arg = process.argv[2];
9+
switch (arg) {
1010
case 'test_init_callback':
1111
initHooks({
12-
oninit: common.mustCall(() => { throw new Error('test_init_callback'); })
12+
oninit: common.mustCall(() => { throw new Error(arg); })
1313
}).enable();
14+
async_hooks.emitInit(
15+
async_hooks.executionAsyncId(),
16+
`${arg}_type`,
17+
async_hooks.triggerAsyncId()
18+
);
19+
return;
1420

15-
async_hooks.emitInit(async_hooks.executionAsyncId(),
16-
'test_init_callback_type',
17-
async_hooks.triggerAsyncId());
18-
break;
1921
case 'test_callback':
2022
initHooks({
21-
onbefore: common.mustCall(() => { throw new Error('test_callback'); })
23+
onbefore: common.mustCall(() => { throw new Error(arg); })
2224
}).enable();
23-
24-
async_hooks.emitInit(async_hooks.executionAsyncId(), 'test_callback_type',
25-
async_hooks.triggerAsyncId());
25+
async_hooks.emitInit(
26+
async_hooks.executionAsyncId(),
27+
`${arg}_type`,
28+
async_hooks.triggerAsyncId()
29+
);
2630
async_hooks.emitBefore(async_hooks.executionAsyncId());
27-
break;
31+
return;
32+
2833
case 'test_callback_abort':
2934
initHooks({
30-
oninit: common.mustCall(() => { throw new Error('test_callback_abort'); })
35+
oninit: common.mustCall(() => { throw new Error(arg); })
3136
}).enable();
37+
async_hooks.emitInit(
38+
async_hooks.executionAsyncId(),
39+
`${arg}_type`,
40+
async_hooks.triggerAsyncId()
41+
);
42+
return;
43+
}
44+
45+
// this part should run only for the master test
46+
assert.ok(!arg);
47+
{
48+
// console.log should stay until this test's flakiness is solved
49+
console.log('start case 1');
50+
console.time('end case 1');
51+
const child = spawnSync(process.execPath, [__filename, 'test_init_callback']);
52+
assert.ifError(child.error);
53+
const test_init_first_line = child.stderr.toString().split(/[\r\n]+/g)[0];
54+
assert.strictEqual(test_init_first_line, 'Error: test_init_callback');
55+
assert.strictEqual(child.status, 1);
56+
console.timeEnd('end case 1');
57+
}
3258

33-
async_hooks.emitInit(async_hooks.executionAsyncId(), 'test_callback_abort',
34-
async_hooks.triggerAsyncId());
35-
break;
59+
{
60+
console.log('start case 2');
61+
console.time('end case 2');
62+
const child = spawnSync(process.execPath, [__filename, 'test_callback']);
63+
assert.ifError(child.error);
64+
const test_callback_first_line = child.stderr.toString().split(/[\r\n]+/g)[0];
65+
assert.strictEqual(test_callback_first_line, 'Error: test_callback');
66+
assert.strictEqual(child.status, 1);
67+
console.timeEnd('end case 2');
3668
}
3769

38-
const c1 = spawnSync(`${process.execPath}`, [__filename, 'test_init_callback']);
39-
assert.strictEqual(c1.stderr.toString().split('\n')[0],
40-
'Error: test_init_callback');
41-
assert.strictEqual(c1.status, 1);
42-
43-
const c2 = spawnSync(`${process.execPath}`, [__filename, 'test_callback']);
44-
assert.strictEqual(c2.stderr.toString().split('\n')[0], 'Error: test_callback');
45-
assert.strictEqual(c2.status, 1);
46-
47-
const c3 = spawnSync(`${process.execPath}`, ['--abort-on-uncaught-exception',
48-
__filename,
49-
'test_callback_abort']);
50-
assert.strictEqual(c3.stdout.toString(), '');
51-
52-
const stderrOutput = c3.stderr.toString()
53-
.trim()
54-
.split('\n')
55-
.map((s) => s.trim());
56-
assert.strictEqual(stderrOutput[0], 'Error: test_callback_abort');
70+
{
71+
console.log('start case 3');
72+
console.time('end case 3');
73+
// Timeout is set because this case is known to be problematic, so stderr is
74+
// logged for further analysis.
75+
// Ref: https://github.com/nodejs/node/issues/13527
76+
// Ref: https://github.com/nodejs/node/pull/13559
77+
const opts = {
78+
execArgv: ['--abort-on-uncaught-exception'],
79+
silent: true
80+
};
81+
const child = fork(__filename, ['test_callback_abort'], opts);
82+
83+
let stdout = '';
84+
child.stdout.on('data', (data) => {
85+
stdout += data;
86+
});
87+
88+
let stderr = '';
89+
child.stderr.on('data', (data) => {
90+
stderr += data;
91+
});
92+
93+
const tO = setTimeout(() => {
94+
console.log(stderr);
95+
child.kill('SIGKILL');
96+
process.exit(1);
97+
}, 15 * 1000);
98+
tO.unref();
99+
100+
child.on('close', (code, signal) => {
101+
clearTimeout(tO);
102+
if (common.isWindows) {
103+
assert.strictEqual(code, 3);
104+
assert.strictEqual(signal, null);
105+
} else {
106+
assert.strictEqual(code, null);
107+
// most posix systems will show 'SIGABRT', but alpine34 does not
108+
if (signal !== 'SIGABRT') {
109+
console.log(`parent recived signal ${signal}\nchild's stderr:`);
110+
console.log(stderr);
111+
process.exit(1);
112+
}
113+
assert.strictEqual(signal, 'SIGABRT');
114+
}
115+
assert.strictEqual(stdout, '');
116+
const firstLineStderr = stderr.split(/[\r\n]+/g)[0].trim();
117+
assert.strictEqual(firstLineStderr, 'Error: test_callback_abort');
118+
});
119+
console.timeEnd('end case 3');
120+
}

0 commit comments

Comments
 (0)