test: fix test-debug-signal-cluster.js flakyness

Do not assume any order and buffering/atomicity of output from child
processes' debugger agents.

Fixes: https://github.com/nodejs/node/issues/3796
PR-URL: https://github.com/nodejs/node/pull/8568
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Ilkka Myller <ilkka.myller@nodefield.com>
This commit is contained in:
Julien Gilli 2016-09-16 11:40:28 -07:00
parent d3834a1fa3
commit 7926886bf3
2 changed files with 39 additions and 32 deletions

View File

@ -19,7 +19,6 @@ test-tick-processor-cpp-core : PASS,FLAKY
test-tick-processor-unknown : PASS,FLAKY test-tick-processor-unknown : PASS,FLAKY
[$system==solaris] # Also applies to SmartOS [$system==solaris] # Also applies to SmartOS
test-debug-signal-cluster : PASS,FLAKY
[$system==freebsd] [$system==freebsd]
@ -34,9 +33,5 @@ test-fs-watch-encoding : FAIL, PASS
#being worked under https://github.com/nodejs/node/issues/7973 #being worked under https://github.com/nodejs/node/issues/7973
test-stdio-closed : PASS, FLAKY test-stdio-closed : PASS, FLAKY
#covered by https://github.com/nodejs/node/issues/3796
# but more frequent on AIX ?
test-debug-signal-cluster : PASS, FLAKY
#covered by https://github.com/nodejs/node/issues/8271 #covered by https://github.com/nodejs/node/issues/8271
test-child-process-fork-dgram : PASS, FLAKY test-child-process-fork-dgram : PASS, FLAKY

View File

@ -3,6 +3,7 @@
const common = require('../common'); const common = require('../common');
const assert = require('assert'); const assert = require('assert');
const spawn = require('child_process').spawn; const spawn = require('child_process').spawn;
const os = require('os');
const path = require('path'); const path = require('path');
const port = common.PORT; const port = common.PORT;
@ -11,13 +12,24 @@ const args = [`--debug-port=${port}`, serverPath];
const options = { stdio: ['inherit', 'inherit', 'pipe', 'ipc'] }; const options = { stdio: ['inherit', 'inherit', 'pipe', 'ipc'] };
const child = spawn(process.execPath, args, options); const child = spawn(process.execPath, args, options);
const outputLines = []; var expectedContent = [
var waitingForDebuggers = false; 'Starting debugger agent.',
'Debugger listening on 127.0.0.1:' + (port + 0),
'Starting debugger agent.',
'Debugger listening on 127.0.0.1:' + (port + 1),
'Starting debugger agent.',
'Debugger listening on 127.0.0.1:' + (port + 2),
].join(os.EOL);
expectedContent += os.EOL; // the last line also contains an EOL character
var debuggerAgentsOutput = '';
var debuggerAgentsStarted = false;
var pids; var pids;
child.stderr.on('data', function(data) { child.stderr.on('data', function(data) {
const lines = data.toString().replace(/\r/g, '').trim().split('\n'); const childStderrOutputString = data.toString();
const lines = childStderrOutputString.replace(/\r/g, '').trim().split('\n');
lines.forEach(function(line) { lines.forEach(function(line) {
console.log('> ' + line); console.log('> ' + line);
@ -30,24 +42,26 @@ child.stderr.on('data', function(data) {
pids = msg.pids; pids = msg.pids;
console.error('got pids %j', pids); console.error('got pids %j', pids);
waitingForDebuggers = true;
process._debugProcess(child.pid); process._debugProcess(child.pid);
debuggerAgentsStarted = true;
}); });
child.send({ child.send({
type: 'getpids' type: 'getpids'
}); });
} else if (waitingForDebuggers) {
outputLines.push(line);
} }
}); });
if (outputLines.length === expectedLines.length)
onNoMoreLines(); if (debuggerAgentsStarted) {
debuggerAgentsOutput += childStderrOutputString;
if (debuggerAgentsOutput.length === expectedContent.length) {
onNoMoreDebuggerAgentsOutput();
}
}
}); });
function onNoMoreLines() { function onNoMoreDebuggerAgentsOutput() {
assertOutputLines(); assertDebuggerAgentsOutput();
process.exit(); process.exit();
} }
@ -63,21 +77,19 @@ process.on('exit', function onExit() {
}); });
}); });
const expectedLines = [ function assertDebuggerAgentsOutput() {
'Starting debugger agent.', // Workers can take different amout of time to start up, and child processes'
'Debugger listening on 127.0.0.1:' + (port + 0), // output may be interleaved arbitrarily. Moreover, child processes' output
'Starting debugger agent.', // may be written using an arbitrary number of system calls, and no assumption
'Debugger listening on 127.0.0.1:' + (port + 1), // on buffering or atomicity of output should be made. Thus, we process the
'Starting debugger agent.', // output of all child processes' debugger agents character by character, and
'Debugger listening on 127.0.0.1:' + (port + 2), // remove each character from the set of expected characters. Once all the
]; // output from all debugger agents has been processed, we consider that we got
// the content we expected if there's no character left in the initial
// expected content.
debuggerAgentsOutput.split('').forEach(function gotChar(char) {
expectedContent = expectedContent.replace(char, '');
});
function assertOutputLines() { assert.strictEqual(expectedContent, '');
// Do not assume any particular order of output messages,
// since workers can take different amout of time to
// start up
outputLines.sort();
expectedLines.sort();
assert.deepStrictEqual(outputLines, expectedLines);
} }