blob: 570fa42aa2f265fad029043a9f90d37c7a0f55c9 [file] [log] [blame]
'use strict';
// Testcase to check reporting of uv handles.
const common = require('../common');
common.skipIfReportDisabled();
if (process.argv[2] === 'child') {
// Exit on loss of parent process
const exit = () => process.exit(2);
process.on('disconnect', exit);
const fs = require('fs');
const http = require('http');
const spawn = require('child_process').spawn;
// Watching files should result in fs_event/fs_poll uv handles.
let watcher;
try {
watcher = fs.watch(__filename);
} catch {
// fs.watch() unavailable
}
fs.watchFile(__filename, () => {});
// Child should exist when this returns as child_process.pid must be set.
const child_process = spawn(process.execPath,
['-e', "process.stdin.on('data', (x) => " +
'console.log(x.toString()));']);
const timeout = setInterval(() => {}, 1000);
// Make sure the timer doesn't keep the test alive and let
// us check we detect unref'd handles correctly.
timeout.unref();
// Datagram socket for udp uv handles.
const dgram = require('dgram');
const udp_socket = dgram.createSocket('udp4');
udp_socket.bind({});
// Simple server/connection to create tcp uv handles.
const server = http.createServer((req, res) => {
req.on('end', () => {
// Generate the report while the connection is active.
console.log(process.report.getReport());
child_process.kill();
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end();
// Tidy up to allow process to exit cleanly.
server.close(() => {
if (watcher) watcher.close();
fs.unwatchFile(__filename);
udp_socket.close();
process.removeListener('disconnect', exit);
});
});
req.resume();
});
server.listen(() => {
const data = { pid: child_process.pid,
tcp_address: server.address(),
udp_address: udp_socket.address(),
skip_fs_watch: (watcher === undefined ?
'fs.watch() unavailable' :
false) };
process.send(data);
http.get({ port: server.address().port });
});
} else {
const helper = require('../common/report.js');
const fork = require('child_process').fork;
const assert = require('assert');
const tmpdir = require('../common/tmpdir');
tmpdir.refresh();
const options = { encoding: 'utf8', silent: true, cwd: tmpdir.path };
const child = fork('--experimental-report', [__filename, 'child'], options);
let stderr = '';
child.stderr.on('data', (chunk) => { stderr += chunk; });
let stdout = '';
const std_msg = 'Found messages in stderr unexpectedly: ';
const report_msg = 'Report files were written: unexpectedly';
child.stdout.on('data', (chunk) => { stdout += chunk; });
child.on('exit', common.mustCall((code, signal) => {
assert.deepStrictEqual(code, 0, 'Process exited unexpectedly with code' +
`${code}`);
assert.deepStrictEqual(signal, null, 'Process should have exited cleanly,' +
` but did not: ${signal}`);
assert.ok(stderr.match(
'(node:.*) ExperimentalWarning: report is an experimental' +
' feature. This feature could change at any time'),
std_msg);
const reports = helper.findReports(child.pid, tmpdir.path);
assert.deepStrictEqual(reports, [], report_msg, reports);
const report = JSON.parse(stdout);
let fs = 0;
let poll = 0;
let process = 0;
let timer = 0;
let pipe = 0;
let tcp = 0;
let udp = 0;
const fs_msg = 'fs_event not found';
const poll_msg = 'poll_event not found';
const process_msg = 'process event not found';
const timer_msg = 'timer event not found';
const pipe_msg = 'pipe event not found';
const tcp_msg = 'tcp event not found';
const udp_msg = 'udp event not found';
for (const entry in report.libuv) {
if (report.libuv[entry].type === 'fs_event') fs = 1;
else if (report.libuv[entry].type === 'fs_poll') poll = 1;
else if (report.libuv[entry].type === 'process') process = 1;
else if (report.libuv[entry].type === 'timer') timer = 1;
else if (report.libuv[entry].type === 'pipe') pipe = 1;
else if (report.libuv[entry].type === 'tcp') tcp = 1;
else if (report.libuv[entry].type === 'udp') udp = 1;
}
assert.deepStrictEqual(fs, 1, fs_msg);
assert.deepStrictEqual(poll, 1, poll_msg);
assert.deepStrictEqual(process, 1, process_msg);
assert.deepStrictEqual(timer, 1, timer_msg);
assert.deepStrictEqual(pipe, 1, pipe_msg);
assert.deepStrictEqual(tcp, 1, tcp_msg);
assert.deepStrictEqual(udp, 1, udp_msg);
// Common report tests.
helper.validateContent(stdout);
}));
}