• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2const common = require('../common');
3const assert = require('assert');
4const cp = require('child_process');
5
6if (process.argv[2] === 'child') {
7  setTimeout(() => {
8    // The following console statements are part of the test.
9    console.log('child stdout');
10    console.error('child stderr');
11  }, common.platformTimeout(1000));
12  return;
13}
14
15const cmd = `"${process.execPath}" "${__filename}" child`;
16
17// Test the case where a timeout is set, and it expires.
18cp.exec(cmd, { timeout: 1 }, common.mustCall((err, stdout, stderr) => {
19  let sigterm = 'SIGTERM';
20  assert.strictEqual(err.killed, true);
21  // TODO OpenBSD returns a null signal and 143 for code
22  if (common.isOpenBSD) {
23    assert.strictEqual(err.code, 143);
24    sigterm = null;
25  } else {
26    assert.strictEqual(err.code, null);
27  }
28  // At least starting with Darwin Kernel Version 16.4.0, sending a SIGTERM to a
29  // process that is still starting up kills it with SIGKILL instead of SIGTERM.
30  // See: https://github.com/libuv/libuv/issues/1226
31  if (common.isOSX)
32    assert.ok(err.signal === 'SIGTERM' || err.signal === 'SIGKILL');
33  else
34    assert.strictEqual(err.signal, sigterm);
35  assert.strictEqual(err.cmd, cmd);
36  assert.strictEqual(stdout.trim(), '');
37  assert.strictEqual(stderr.trim(), '');
38}));
39
40// Test with a different kill signal.
41cp.exec(cmd, {
42  timeout: 1,
43  killSignal: 'SIGKILL'
44}, common.mustCall((err, stdout, stderr) => {
45  assert.strictEqual(err.killed, true);
46  assert.strictEqual(err.code, null);
47  assert.strictEqual(err.signal, 'SIGKILL');
48  assert.strictEqual(err.cmd, cmd);
49  assert.strictEqual(stdout.trim(), '');
50  assert.strictEqual(stderr.trim(), '');
51}));
52
53// Test the case where a timeout is set, but not expired.
54cp.exec(cmd, { timeout: 2 ** 30 }, common.mustSucceed((stdout, stderr) => {
55  assert.strictEqual(stdout.trim(), 'child stdout');
56  assert.strictEqual(stderr.trim(), 'child stderr');
57}));
58
59// Workaround for Windows Server 2008R2
60// When CMD is used to launch a process and CMD is killed too quickly, the
61// process can stay behind running in suspended state, never completing.
62if (common.isWindows) {
63  process.once('beforeExit', () => {
64    const basename = __filename.replace(/.*[/\\]/g, '');
65    cp.execFileSync(`${process.env.SystemRoot}\\System32\\wbem\\WMIC.exe`, [
66      'process',
67      'where',
68      `commandline like '%${basename}%child'`,
69      'delete',
70      '/nointeractive',
71    ]);
72  });
73}
74