mirror of
https://github.com/nodejs/node.git
synced 2024-12-01 16:10:02 +01:00
3e1b1dd4a9
The copyright and license notice is already in the LICENSE file. There is no justifiable reason to also require that it be included in every file, since the individual files are not individually distributed except as part of the entire package.
128 lines
3.8 KiB
JavaScript
128 lines
3.8 KiB
JavaScript
// test-cluster-worker-kill.js
|
|
// verifies that, when a child process is killed (we use SIGKILL)
|
|
// - the parent receives the proper events in the proper order, no duplicates
|
|
// - the exitCode and signalCode are correct in the 'exit' event
|
|
// - the worker.suicide flag, and worker.state are correct
|
|
// - the worker process actually goes away
|
|
|
|
var common = require('../common');
|
|
var assert = require('assert');
|
|
var cluster = require('cluster');
|
|
|
|
if (cluster.isWorker) {
|
|
var http = require('http');
|
|
var server = http.Server(function() { });
|
|
|
|
server.once('listening', function() { });
|
|
server.listen(common.PORT, '127.0.0.1');
|
|
|
|
} else if (cluster.isMaster) {
|
|
|
|
var KILL_SIGNAL = 'SIGKILL',
|
|
expected_results = {
|
|
cluster_emitDisconnect: [1, "the cluster did not emit 'disconnect'"],
|
|
cluster_emitExit: [1, "the cluster did not emit 'exit'"],
|
|
cluster_exitCode: [null, 'the cluster exited w/ incorrect exitCode'],
|
|
cluster_signalCode: [KILL_SIGNAL, 'the cluster exited w/ incorrect signalCode'],
|
|
worker_emitDisconnect: [1, "the worker did not emit 'disconnect'"],
|
|
worker_emitExit: [1, "the worker did not emit 'exit'"],
|
|
worker_state: ['disconnected', 'the worker state is incorrect'],
|
|
worker_suicideMode: [false, 'the worker.suicide flag is incorrect'],
|
|
worker_died: [true, 'the worker is still running'],
|
|
worker_exitCode: [null, 'the worker exited w/ incorrect exitCode'],
|
|
worker_signalCode: [KILL_SIGNAL, 'the worker exited w/ incorrect signalCode']
|
|
},
|
|
results = {
|
|
cluster_emitDisconnect: 0,
|
|
cluster_emitExit: 0,
|
|
worker_emitDisconnect: 0,
|
|
worker_emitExit: 0
|
|
};
|
|
|
|
|
|
// start worker
|
|
var worker = cluster.fork();
|
|
|
|
// when the worker is up and running, kill it
|
|
worker.once('listening', function() {
|
|
worker.process.kill(KILL_SIGNAL);
|
|
});
|
|
|
|
|
|
// Check cluster events
|
|
cluster.on('disconnect', function() {
|
|
results.cluster_emitDisconnect += 1;
|
|
});
|
|
cluster.on('exit', function(worker) {
|
|
results.cluster_exitCode = worker.process.exitCode;
|
|
results.cluster_signalCode = worker.process.signalCode;
|
|
results.cluster_emitExit += 1;
|
|
assert.ok(results.cluster_emitDisconnect,
|
|
"cluster: 'exit' event before 'disconnect' event");
|
|
});
|
|
|
|
// Check worker events and properties
|
|
worker.on('disconnect', function() {
|
|
results.worker_emitDisconnect += 1;
|
|
results.worker_suicideMode = worker.suicide;
|
|
results.worker_state = worker.state;
|
|
});
|
|
|
|
// Check that the worker died
|
|
worker.once('exit', function(exitCode, signalCode) {
|
|
results.worker_exitCode = exitCode;
|
|
results.worker_signalCode = signalCode;
|
|
results.worker_emitExit += 1;
|
|
results.worker_died = !alive(worker.process.pid);
|
|
assert.ok(results.worker_emitDisconnect,
|
|
"worker: 'exit' event before 'disconnect' event");
|
|
|
|
process.nextTick(function() { finish_test(); });
|
|
});
|
|
|
|
var finish_test = function() {
|
|
try {
|
|
checkResults(expected_results, results);
|
|
} catch (exc) {
|
|
console.error('FAIL: ' + exc.message);
|
|
if (exc.name != 'AssertionError') {
|
|
console.trace(exc);
|
|
}
|
|
|
|
process.exit(1);
|
|
return;
|
|
}
|
|
process.exit(0);
|
|
};
|
|
}
|
|
|
|
// some helper functions ...
|
|
|
|
function checkResults(expected_results, results) {
|
|
for (var k in expected_results) {
|
|
var actual = results[k],
|
|
expected = expected_results[k];
|
|
|
|
if (typeof expected === 'function') {
|
|
expected(r[k]);
|
|
} else {
|
|
var msg = (expected[1] || '') +
|
|
(' [expected: ' + expected[0] + ' / actual: ' + actual + ']');
|
|
if (expected && expected.length) {
|
|
assert.equal(actual, expected[0], msg);
|
|
} else {
|
|
assert.equal(actual, expected, msg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function alive(pid) {
|
|
try {
|
|
process.kill(pid, 'SIGCONT');
|
|
return true;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
}
|