1'use strict';
2const common = require('../common');
3const assert = require('assert');
4const { spawnSync } = require('child_process');
5const async_hooks = require('async_hooks');
6const initHooks = require('./init-hooks');
7
8const arg = process.argv[2];
9switch (arg) {
10  case 'test_init_callback':
11    initHooks({
12      oninit: common.mustCall(() => { throw new Error(arg); }),
13    }).enable();
14    new async_hooks.AsyncResource(`${arg}_type`);
15    return;
16
17  case 'test_callback': {
18    initHooks({
19      onbefore: common.mustCall(() => { throw new Error(arg); }),
20    }).enable();
21    const resource = new async_hooks.AsyncResource(`${arg}_type`);
22    resource.runInAsyncScope(() => {});
23    return;
24  }
25
26  case 'test_callback_abort':
27    initHooks({
28      oninit: common.mustCall(() => { throw new Error(arg); }),
29    }).enable();
30    new async_hooks.AsyncResource(`${arg}_type`);
31    return;
32}
33
34// This part should run only for the primary test
35assert.ok(!arg);
36{
37  // console.log should stay until this test's flakiness is solved
38  console.log('start case 1');
39  console.time('end case 1');
40  const child = spawnSync(process.execPath, [__filename, 'test_init_callback']);
41  assert.ifError(child.error);
42  const test_init_first_line = child.stderr.toString().split(/[\r\n]+/g)[0];
43  assert.strictEqual(test_init_first_line, 'Error: test_init_callback');
44  assert.strictEqual(child.status, 1);
45  console.timeEnd('end case 1');
46}
47
48{
49  console.log('start case 2');
50  console.time('end case 2');
51  const child = spawnSync(process.execPath, [__filename, 'test_callback']);
52  assert.ifError(child.error);
53  const test_callback_first_line = child.stderr.toString().split(/[\r\n]+/g)[0];
54  assert.strictEqual(test_callback_first_line, 'Error: test_callback');
55  assert.strictEqual(child.status, 1);
56  console.timeEnd('end case 2');
57}
58
59{
60  console.log('start case 3');
61  console.time('end case 3');
62  let program = process.execPath;
63  let args = [
64    '--abort-on-uncaught-exception', __filename, 'test_callback_abort' ];
65  const options = { encoding: 'utf8' };
66  if (!common.isWindows) {
67    program = `ulimit -c 0 && exec ${program} ${args.join(' ')}`;
68    args = [];
69    options.shell = true;
70  }
71  const child = spawnSync(program, args, options);
72  if (common.isWindows) {
73    assert.strictEqual(child.status, 134);
74    assert.strictEqual(child.signal, null);
75  } else {
76    assert.strictEqual(child.status, null);
77    // Most posix systems will show 'SIGABRT', but alpine34 does not
78    if (child.signal !== 'SIGABRT') {
79      console.log(`primary received signal ${child.signal}\nchild's stderr:`);
80      console.log(child.stderr);
81      process.exit(1);
82    }
83    assert.strictEqual(child.signal, 'SIGABRT');
84  }
85  assert.strictEqual(child.stdout, '');
86  const firstLineStderr = child.stderr.split(/[\r\n]+/g)[0].trim();
87  assert.strictEqual(firstLineStderr, 'Error: test_callback_abort');
88  console.timeEnd('end case 3');
89}
90