forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest-child-process-stdin-close-on-exit.js
More file actions
73 lines (68 loc) Β· 3.31 KB
/
test-child-process-stdin-close-on-exit.js
File metadata and controls
73 lines (68 loc) Β· 3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
// Regression test for https://github.com/nodejs/node/issues/25131.
//
// Since #18701 (v8.12) the parent's `child.stdin` socket no longer emitted a
// 'close' event when the child closed its end of the stdin pipe. The
// 'close' event should be observable so consumers can detect that the
// writable side of the pipe is gone without having to attempt a write and
// wait for EPIPE. This test exercises both:
// 1. The well-behaved case where the child simply exits without anyone
// touching stdin β `child.stdin` must still emit 'close'.
// 2. The exact scenario from #25131 where a long-running child closes
// its own fd 0 β the parent should observe 'close' eagerly, before
// the child process exits.
const common = require('../common');
const { spawn } = require('child_process');
// Case 1: child exits without anyone touching stdin. `child.stdin` must
// emit 'close'.
{
const child = spawn(process.execPath, ['-e', 'setTimeout(() => {}, 50)']);
child.stdin.on('close', common.mustCall());
child.on('exit', common.mustCall());
}
// Case 2: child explicitly closes its own stdin file descriptor while
// still running. The parent should observe 'close' on `child.stdin`
// eagerly, without waiting for the child process to exit. Skipped on
// Windows because the named-pipe semantics there do not propagate the
// peer close until the child process exits.
if (!common.isWindows) {
const child = spawn(
process.execPath,
['-e', 'require("fs").closeSync(0); setTimeout(() => {}, 2000)'],
{ stdio: ['pipe', 'inherit', 'inherit'] },
);
// The 'close' must fire well before the child's 2s timer expires.
// common.platformTimeout keeps this comfortable on slow CI machines
// while still catching the regression (which would only fire 'close'
// after the child finally exits at ~2000ms).
const eagerWindow = setTimeout(() => {
throw new Error('child.stdin close did not fire eagerly on peer-close');
}, common.platformTimeout(1500));
child.stdin.on('close', common.mustCall(() => {
clearTimeout(eagerWindow);
// Kill the still-running child so the test does not have to wait
// for its 2s timer.
child.kill();
}));
child.on('exit', common.mustCall());
}