test: refactor/cleanup a number of cluster tests
* Move shared code into common * Favor use of strictEqual * Add some missing common.mustCalls * Other general cleanup PR-URL: https://github.com/nodejs/node/pull/8261 Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
This commit is contained in:
parent
2168432c36
commit
baa0ffdab3
@ -498,3 +498,12 @@ exports.busyLoop = function busyLoop(time) {
|
||||
var stopTime = startTime + time;
|
||||
while (Timer.now() < stopTime) {}
|
||||
};
|
||||
|
||||
exports.isAlive = function isAlive(pid) {
|
||||
try {
|
||||
process.kill(pid, 'SIGCONT');
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
@ -1,26 +1,26 @@
|
||||
'use strict';
|
||||
var common = require('../common');
|
||||
var assert = require('assert');
|
||||
var cluster = require('cluster');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const cluster = require('cluster');
|
||||
|
||||
assert.equal('NODE_UNIQUE_ID' in process.env, false,
|
||||
'NODE_UNIQUE_ID should be removed on startup');
|
||||
assert.strictEqual('NODE_UNIQUE_ID' in process.env, false,
|
||||
'NODE_UNIQUE_ID should be removed on startup');
|
||||
|
||||
function forEach(obj, fn) {
|
||||
Object.keys(obj).forEach(function(name, index) {
|
||||
Object.keys(obj).forEach((name, index) => {
|
||||
fn(obj[name], name, index);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (cluster.isWorker) {
|
||||
var http = require('http');
|
||||
const http = require('http');
|
||||
http.Server(function() {
|
||||
|
||||
}).listen(common.PORT, '127.0.0.1');
|
||||
} else if (cluster.isMaster) {
|
||||
|
||||
var checks = {
|
||||
const checks = {
|
||||
cluster: {
|
||||
events: {
|
||||
fork: false,
|
||||
@ -57,13 +57,13 @@ if (cluster.isWorker) {
|
||||
};
|
||||
|
||||
var worker;
|
||||
var stateNames = Object.keys(checks.worker.states);
|
||||
const stateNames = Object.keys(checks.worker.states);
|
||||
|
||||
//Check events, states, and emit arguments
|
||||
forEach(checks.cluster.events, function(bool, name, index) {
|
||||
forEach(checks.cluster.events, (bool, name, index) => {
|
||||
|
||||
//Listen on event
|
||||
cluster.on(name, function(/* worker */) {
|
||||
cluster.on(name, common.mustCall(function(/* worker */) {
|
||||
|
||||
//Set event
|
||||
checks.cluster.events[name] = true;
|
||||
@ -74,28 +74,26 @@ if (cluster.isWorker) {
|
||||
//Check state
|
||||
var state = stateNames[index];
|
||||
checks.worker.states[state] = (state === worker.state);
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
//Kill worker when listening
|
||||
cluster.on('listening', function() {
|
||||
cluster.on('listening', common.mustCall(() => {
|
||||
worker.kill();
|
||||
});
|
||||
}));
|
||||
|
||||
//Kill process when worker is killed
|
||||
cluster.on('exit', function() {
|
||||
process.exit(0);
|
||||
});
|
||||
cluster.on('exit', common.mustCall(() => {}));
|
||||
|
||||
//Create worker
|
||||
worker = cluster.fork();
|
||||
assert.equal(worker.id, 1);
|
||||
assert.ok(worker instanceof cluster.Worker,
|
||||
'the worker is not a instance of the Worker constructor');
|
||||
assert.strictEqual(worker.id, 1);
|
||||
assert(worker instanceof cluster.Worker,
|
||||
'the worker is not a instance of the Worker constructor');
|
||||
|
||||
//Check event
|
||||
forEach(checks.worker.events, function(bool, name, index) {
|
||||
worker.on(name, function() {
|
||||
worker.on(name, common.mustCall(function() {
|
||||
//Set event
|
||||
checks.worker.events[name] = true;
|
||||
|
||||
@ -104,56 +102,57 @@ if (cluster.isWorker) {
|
||||
|
||||
switch (name) {
|
||||
case 'exit':
|
||||
assert.equal(arguments[0], worker.process.exitCode);
|
||||
assert.equal(arguments[1], worker.process.signalCode);
|
||||
assert.equal(arguments.length, 2);
|
||||
assert.strictEqual(arguments[0], worker.process.exitCode);
|
||||
assert.strictEqual(arguments[1], worker.process.signalCode);
|
||||
assert.strictEqual(arguments.length, 2);
|
||||
break;
|
||||
|
||||
case 'listening':
|
||||
assert.equal(arguments.length, 1);
|
||||
var expect = { address: '127.0.0.1',
|
||||
port: common.PORT,
|
||||
addressType: 4,
|
||||
fd: undefined };
|
||||
assert.strictEqual(arguments.length, 1);
|
||||
const expect = { address: '127.0.0.1',
|
||||
port: common.PORT,
|
||||
addressType: 4,
|
||||
fd: undefined };
|
||||
assert.deepStrictEqual(arguments[0], expect);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert.equal(arguments.length, 0);
|
||||
assert.strictEqual(arguments.length, 0);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
//Check all values
|
||||
process.once('exit', function() {
|
||||
process.once('exit', () => {
|
||||
//Check cluster events
|
||||
forEach(checks.cluster.events, function(check, name) {
|
||||
assert.ok(check, 'The cluster event "' + name + '" on the cluster ' +
|
||||
'object did not fire');
|
||||
forEach(checks.cluster.events, (check, name) => {
|
||||
assert(check,
|
||||
`The cluster event "${name}" on the cluster object did not fire`);
|
||||
});
|
||||
|
||||
//Check cluster event arguments
|
||||
forEach(checks.cluster.equal, function(check, name) {
|
||||
assert.ok(check, 'The cluster event "' + name + '" did not emit ' +
|
||||
'with correct argument');
|
||||
forEach(checks.cluster.equal, (check, name) => {
|
||||
assert(check,
|
||||
`The cluster event "${name}" did not emit with correct argument`);
|
||||
});
|
||||
|
||||
//Check worker states
|
||||
forEach(checks.worker.states, function(check, name) {
|
||||
assert.ok(check, 'The worker state "' + name + '" was not set to true');
|
||||
forEach(checks.worker.states, (check, name) => {
|
||||
assert(check,
|
||||
`The worker state "${name}" was not set to true`);
|
||||
});
|
||||
|
||||
//Check worker events
|
||||
forEach(checks.worker.events, function(check, name) {
|
||||
assert.ok(check, 'The worker event "' + name + '" on the worker object ' +
|
||||
'did not fire');
|
||||
forEach(checks.worker.events, (check, name) => {
|
||||
assert(check,
|
||||
`The worker event "${name}" on the worker object did not fire`);
|
||||
});
|
||||
|
||||
//Check worker event arguments
|
||||
forEach(checks.worker.equal, function(check, name) {
|
||||
assert.ok(check, 'The worker event "' + name + '" did not emit with ' +
|
||||
'corrent argument');
|
||||
forEach(checks.worker.equal, (check, name) => {
|
||||
assert(check,
|
||||
`The worker event "${name}" did not emit with correct argument`);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
'use strict';
|
||||
var common = require('../common');
|
||||
var assert = require('assert');
|
||||
var cluster = require('cluster');
|
||||
var net = require('net');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const cluster = require('cluster');
|
||||
const net = require('net');
|
||||
|
||||
if (common.isWindows) {
|
||||
common.skip('not reliable on Windows.');
|
||||
@ -15,14 +15,14 @@ if (process.getuid() === 0) {
|
||||
}
|
||||
|
||||
if (cluster.isMaster) {
|
||||
cluster.fork().on('exit', common.mustCall(function(exitCode) {
|
||||
assert.equal(exitCode, 0);
|
||||
cluster.fork().on('exit', common.mustCall((exitCode) => {
|
||||
assert.strictEqual(exitCode, 0);
|
||||
}));
|
||||
} else {
|
||||
var s = net.createServer(common.fail);
|
||||
s.listen(42, common.fail.bind(null, 'listen should have failed'));
|
||||
s.on('error', common.mustCall(function(err) {
|
||||
assert.equal(err.code, 'EACCES');
|
||||
s.on('error', common.mustCall((err) => {
|
||||
assert.strictEqual(err.code, 'EACCES');
|
||||
process.disconnect();
|
||||
}));
|
||||
}
|
||||
|
@ -18,88 +18,74 @@
|
||||
//
|
||||
// See https://github.com/joyent/node/issues/2721 for more details.
|
||||
|
||||
var common = require('../common');
|
||||
var assert = require('assert');
|
||||
var cluster = require('cluster');
|
||||
var fork = require('child_process').fork;
|
||||
var http = require('http');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const cluster = require('cluster');
|
||||
const fork = require('child_process').fork;
|
||||
const http = require('http');
|
||||
|
||||
var id = process.argv[2];
|
||||
const id = process.argv[2];
|
||||
|
||||
if (!id) {
|
||||
var a = fork(__filename, ['one']);
|
||||
var b = fork(__filename, ['two']);
|
||||
const a = fork(__filename, ['one']);
|
||||
const b = fork(__filename, ['two']);
|
||||
|
||||
a.on('exit', function(c) {
|
||||
a.on('exit', common.mustCall((c) => {
|
||||
if (c) {
|
||||
b.send('QUIT');
|
||||
throw new Error('A exited with ' + c);
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
b.on('exit', function(c) {
|
||||
b.on('exit', common.mustCall((c) => {
|
||||
if (c) {
|
||||
a.send('QUIT');
|
||||
throw new Error('B exited with ' + c);
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
a.on('message', function(m) {
|
||||
a.on('message', common.mustCall((m) => {
|
||||
if (typeof m === 'object') return;
|
||||
assert.equal(m, 'READY');
|
||||
assert.strictEqual(m, 'READY');
|
||||
b.send('START');
|
||||
});
|
||||
}));
|
||||
|
||||
let ok = false;
|
||||
|
||||
b.on('message', function(m) {
|
||||
if (typeof m === 'object') return; // ignore system messages
|
||||
assert.equal(m, 'EADDRINUSE');
|
||||
ok = true;
|
||||
b.on('message', common.mustCall((m) => {
|
||||
assert.strictEqual(m, 'EADDRINUSE');
|
||||
a.send('QUIT');
|
||||
b.send('QUIT');
|
||||
});
|
||||
}));
|
||||
|
||||
process.on('exit', function() {
|
||||
assert(ok);
|
||||
});
|
||||
} else if (id === 'one') {
|
||||
if (cluster.isMaster) return startWorker();
|
||||
|
||||
http.createServer(common.fail).listen(common.PORT, function() {
|
||||
http.createServer(common.fail).listen(common.PORT, common.mustCall(() => {
|
||||
process.send('READY');
|
||||
});
|
||||
}));
|
||||
|
||||
process.on('message', function(m) {
|
||||
process.on('message', common.mustCall((m) => {
|
||||
if (m === 'QUIT') process.exit();
|
||||
});
|
||||
}));
|
||||
} else if (id === 'two') {
|
||||
if (cluster.isMaster) return startWorker();
|
||||
|
||||
let ok = false;
|
||||
process.on('exit', function() {
|
||||
assert(ok);
|
||||
});
|
||||
|
||||
var server = http.createServer(common.fail);
|
||||
process.on('message', function(m) {
|
||||
if (typeof m === 'object') return; // ignore system messages
|
||||
const server = http.createServer(common.fail);
|
||||
process.on('message', common.mustCall((m) => {
|
||||
if (m === 'QUIT') process.exit();
|
||||
assert.equal(m, 'START');
|
||||
assert.strictEqual(m, 'START');
|
||||
server.listen(common.PORT, common.fail);
|
||||
server.on('error', function(e) {
|
||||
assert.equal(e.code, 'EADDRINUSE');
|
||||
server.on('error', common.mustCall((e) => {
|
||||
assert.strictEqual(e.code, 'EADDRINUSE');
|
||||
process.send(e.code);
|
||||
ok = true;
|
||||
});
|
||||
});
|
||||
}));
|
||||
}, 2));
|
||||
} else {
|
||||
assert(0); // bad command line argument
|
||||
}
|
||||
|
||||
function startWorker() {
|
||||
var worker = cluster.fork();
|
||||
const worker = cluster.fork();
|
||||
worker.on('exit', process.exit);
|
||||
worker.on('message', process.send.bind(process));
|
||||
process.on('message', worker.send.bind(worker));
|
||||
|
@ -1,11 +1,11 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
var NUM_WORKERS = 4;
|
||||
var PACKETS_PER_WORKER = 10;
|
||||
const NUM_WORKERS = 4;
|
||||
const PACKETS_PER_WORKER = 10;
|
||||
|
||||
var assert = require('assert');
|
||||
var cluster = require('cluster');
|
||||
var dgram = require('dgram');
|
||||
const assert = require('assert');
|
||||
const cluster = require('cluster');
|
||||
const dgram = require('dgram');
|
||||
|
||||
|
||||
if (common.isWindows) {
|
||||
@ -28,13 +28,13 @@ function master() {
|
||||
cluster.fork();
|
||||
|
||||
// Wait until all workers are listening.
|
||||
cluster.on('listening', function() {
|
||||
cluster.on('listening', common.mustCall(() => {
|
||||
if (++listening < NUM_WORKERS)
|
||||
return;
|
||||
|
||||
// Start sending messages.
|
||||
var buf = Buffer.from('hello world');
|
||||
var socket = dgram.createSocket('udp4');
|
||||
const buf = Buffer.from('hello world');
|
||||
const socket = dgram.createSocket('udp4');
|
||||
var sent = 0;
|
||||
doSend();
|
||||
|
||||
@ -47,15 +47,14 @@ function master() {
|
||||
if (sent < NUM_WORKERS * PACKETS_PER_WORKER) {
|
||||
doSend();
|
||||
} else {
|
||||
console.log('master sent %d packets', sent);
|
||||
socket.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
}, NUM_WORKERS));
|
||||
|
||||
// Set up event handlers for every worker. Each worker sends a message when
|
||||
// it has received the expected number of packets. After that it disconnects.
|
||||
for (var key in cluster.workers) {
|
||||
for (const key in cluster.workers) {
|
||||
if (cluster.workers.hasOwnProperty(key))
|
||||
setupWorker(cluster.workers[key]);
|
||||
}
|
||||
@ -63,15 +62,13 @@ function master() {
|
||||
function setupWorker(worker) {
|
||||
var received = 0;
|
||||
|
||||
worker.on('message', function(msg) {
|
||||
worker.on('message', common.mustCall((msg) => {
|
||||
received = msg.received;
|
||||
console.log('worker %d received %d packets', worker.id, received);
|
||||
});
|
||||
}));
|
||||
|
||||
worker.on('disconnect', function() {
|
||||
assert(received === PACKETS_PER_WORKER);
|
||||
console.log('worker %d disconnected', worker.id);
|
||||
});
|
||||
worker.on('disconnect', common.mustCall(() => {
|
||||
assert.strictEqual(received, PACKETS_PER_WORKER);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,15 +79,15 @@ function worker() {
|
||||
// Create udp socket and start listening.
|
||||
var socket = dgram.createSocket('udp4');
|
||||
|
||||
socket.on('message', function(data, info) {
|
||||
socket.on('message', common.mustCall((data, info) => {
|
||||
received++;
|
||||
|
||||
// Every 10 messages, notify the master.
|
||||
if (received == PACKETS_PER_WORKER) {
|
||||
if (received === PACKETS_PER_WORKER) {
|
||||
process.send({received: received});
|
||||
process.disconnect();
|
||||
}
|
||||
});
|
||||
}, PACKETS_PER_WORKER));
|
||||
|
||||
socket.bind(common.PORT);
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
var NUM_WORKERS = 4;
|
||||
var PACKETS_PER_WORKER = 10;
|
||||
const NUM_WORKERS = 4;
|
||||
const PACKETS_PER_WORKER = 10;
|
||||
|
||||
var cluster = require('cluster');
|
||||
var dgram = require('dgram');
|
||||
const cluster = require('cluster');
|
||||
const dgram = require('dgram');
|
||||
|
||||
|
||||
if (common.isWindows) {
|
||||
@ -28,11 +28,10 @@ function master() {
|
||||
|
||||
// Disconnect workers when the expected number of messages have been
|
||||
// received.
|
||||
socket.on('message', function(data, info) {
|
||||
socket.on('message', common.mustCall((data, info) => {
|
||||
received++;
|
||||
|
||||
if (received == PACKETS_PER_WORKER * NUM_WORKERS) {
|
||||
console.log('master received %d packets', received);
|
||||
if (received === PACKETS_PER_WORKER * NUM_WORKERS) {
|
||||
|
||||
// Close the socket.
|
||||
socket.close();
|
||||
@ -40,7 +39,7 @@ function master() {
|
||||
// Disconnect all workers.
|
||||
cluster.disconnect();
|
||||
}
|
||||
});
|
||||
}, NUM_WORKERS * PACKETS_PER_WORKER));
|
||||
|
||||
// Fork workers.
|
||||
for (var i = 0; i < NUM_WORKERS; i++)
|
||||
@ -50,8 +49,8 @@ function master() {
|
||||
|
||||
function worker() {
|
||||
// Create udp socket and send packets to master.
|
||||
var socket = dgram.createSocket('udp4');
|
||||
var buf = Buffer.from('hello world');
|
||||
const socket = dgram.createSocket('udp4');
|
||||
const buf = Buffer.from('hello world');
|
||||
|
||||
// This test is intended to exercise the cluster binding of udp sockets, but
|
||||
// since sockets aren't clustered when implicitly bound by at first call of
|
||||
@ -60,7 +59,4 @@ function worker() {
|
||||
|
||||
for (var i = 0; i < PACKETS_PER_WORKER; i++)
|
||||
socket.send(buf, 0, buf.length, common.PORT, '127.0.0.1');
|
||||
|
||||
console.log('worker %d sent %d packets', cluster.worker.id,
|
||||
PACKETS_PER_WORKER);
|
||||
}
|
||||
|
@ -11,9 +11,9 @@ if (common.isWindows) {
|
||||
}
|
||||
|
||||
if (cluster.isMaster) {
|
||||
cluster.fork().on('exit', function(code) {
|
||||
assert.equal(code, 0);
|
||||
});
|
||||
cluster.fork().on('exit', common.mustCall((code) => {
|
||||
assert.strictEqual(code, 0);
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ function next() {
|
||||
return;
|
||||
|
||||
// Work around health check issue
|
||||
process.nextTick(function() {
|
||||
process.nextTick(() => {
|
||||
for (var i = 0; i < sockets.length; i++)
|
||||
sockets[i].close(close);
|
||||
});
|
||||
|
@ -1,9 +1,9 @@
|
||||
'use strict';
|
||||
require('../common');
|
||||
var cluster = require('cluster');
|
||||
const common = require('../common');
|
||||
const cluster = require('cluster');
|
||||
|
||||
if (cluster.isMaster) {
|
||||
var worker = cluster.fork().on('online', disconnect);
|
||||
const worker = cluster.fork().on('online', common.mustCall(disconnect));
|
||||
|
||||
function disconnect() {
|
||||
worker.disconnect();
|
||||
@ -11,6 +11,6 @@ if (cluster.isMaster) {
|
||||
// Disconnect is supposed to disconnect all workers, but not workers that
|
||||
// are already disconnected, since calling disconnect() on an already
|
||||
// disconnected worker would error.
|
||||
worker.on('disconnect', cluster.disconnect);
|
||||
worker.on('disconnect', common.mustCall(cluster.disconnect));
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
'use strict';
|
||||
var common = require('../common');
|
||||
var assert = require('assert');
|
||||
var cluster = require('cluster');
|
||||
var net = require('net');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const cluster = require('cluster');
|
||||
const net = require('net');
|
||||
|
||||
if (cluster.isWorker) {
|
||||
net.createServer(function(socket) {
|
||||
net.createServer((socket) => {
|
||||
socket.end('echo');
|
||||
}).listen(common.PORT, '127.0.0.1');
|
||||
|
||||
net.createServer(function(socket) {
|
||||
net.createServer((socket) => {
|
||||
socket.end('echo');
|
||||
}).listen(common.PORT + 1, '127.0.0.1');
|
||||
|
||||
@ -17,25 +17,25 @@ if (cluster.isWorker) {
|
||||
var servers = 2;
|
||||
|
||||
// test a single TCP server
|
||||
var testConnection = function(port, cb) {
|
||||
var socket = net.connect(port, '127.0.0.1', function() {
|
||||
const testConnection = function(port, cb) {
|
||||
var socket = net.connect(port, '127.0.0.1', () => {
|
||||
// buffer result
|
||||
var result = '';
|
||||
socket.on('data', function(chunk) { result += chunk; });
|
||||
socket.on('data', common.mustCall((chunk) => { result += chunk; }));
|
||||
|
||||
// check result
|
||||
socket.on('end', function() {
|
||||
socket.on('end', common.mustCall(() => {
|
||||
cb(result === 'echo');
|
||||
});
|
||||
}));
|
||||
});
|
||||
};
|
||||
|
||||
// test both servers created in the cluster
|
||||
var testCluster = function(cb) {
|
||||
const testCluster = function(cb) {
|
||||
var done = 0;
|
||||
|
||||
for (var i = 0, l = servers; i < l; i++) {
|
||||
testConnection(common.PORT + i, function(success) {
|
||||
testConnection(common.PORT + i, (success) => {
|
||||
assert.ok(success);
|
||||
done += 1;
|
||||
if (done === servers) {
|
||||
@ -46,40 +46,38 @@ if (cluster.isWorker) {
|
||||
};
|
||||
|
||||
// start two workers and execute callback when both is listening
|
||||
var startCluster = function(cb) {
|
||||
const startCluster = function(cb) {
|
||||
var workers = 8;
|
||||
var online = 0;
|
||||
|
||||
for (var i = 0, l = workers; i < l; i++) {
|
||||
|
||||
var worker = cluster.fork();
|
||||
worker.on('listening', function() {
|
||||
cluster.fork().on('listening', common.mustCall(() => {
|
||||
online += 1;
|
||||
if (online === workers * servers) {
|
||||
cb();
|
||||
}
|
||||
});
|
||||
}, servers));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var results = {
|
||||
const results = {
|
||||
start: 0,
|
||||
test: 0,
|
||||
disconnect: 0
|
||||
};
|
||||
|
||||
var test = function(again) {
|
||||
const test = function(again) {
|
||||
//1. start cluster
|
||||
startCluster(function() {
|
||||
startCluster(() => {
|
||||
results.start += 1;
|
||||
|
||||
//2. test cluster
|
||||
testCluster(function() {
|
||||
testCluster(() => {
|
||||
results.test += 1;
|
||||
|
||||
//3. disconnect cluster
|
||||
cluster.disconnect(function() {
|
||||
cluster.disconnect(() => {
|
||||
results.disconnect += 1;
|
||||
|
||||
// run test again to confirm cleanup
|
||||
@ -93,9 +91,9 @@ if (cluster.isWorker) {
|
||||
|
||||
test(true);
|
||||
|
||||
process.once('exit', function() {
|
||||
assert.equal(results.start, 2);
|
||||
assert.equal(results.test, 2);
|
||||
assert.equal(results.disconnect, 2);
|
||||
process.once('exit', () => {
|
||||
assert.strictEqual(results.start, 2);
|
||||
assert.strictEqual(results.test, 2);
|
||||
assert.strictEqual(results.disconnect, 2);
|
||||
});
|
||||
}
|
||||
|
@ -1,22 +1,22 @@
|
||||
'use strict';
|
||||
var common = require('../common');
|
||||
var assert = require('assert');
|
||||
var cluster = require('cluster');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const cluster = require('cluster');
|
||||
|
||||
const totalWorkers = 2;
|
||||
|
||||
// Cluster setup
|
||||
if (cluster.isWorker) {
|
||||
var http = require('http');
|
||||
http.Server(function() {
|
||||
const http = require('http');
|
||||
http.Server(() => {
|
||||
|
||||
}).listen(common.PORT, '127.0.0.1');
|
||||
|
||||
} else if (process.argv[2] === 'cluster') {
|
||||
|
||||
var totalWorkers = 2;
|
||||
|
||||
// Send PID to testcase process
|
||||
var forkNum = 0;
|
||||
cluster.on('fork', function forkEvent(worker) {
|
||||
cluster.on('fork', common.mustCall(function forkEvent(worker) {
|
||||
|
||||
// Send PID
|
||||
process.send({
|
||||
@ -28,11 +28,11 @@ if (cluster.isWorker) {
|
||||
if (++forkNum === totalWorkers) {
|
||||
cluster.removeListener('fork', forkEvent);
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
// Throw accidental error when all workers are listening
|
||||
var listeningNum = 0;
|
||||
cluster.on('listening', function listeningEvent() {
|
||||
cluster.on('listening', common.mustCall(function listeningEvent() {
|
||||
|
||||
// When all workers are listening
|
||||
if (++listeningNum === totalWorkers) {
|
||||
@ -40,13 +40,12 @@ if (cluster.isWorker) {
|
||||
cluster.removeListener('listening', listeningEvent);
|
||||
|
||||
// Throw accidental error
|
||||
process.nextTick(function() {
|
||||
console.error('about to throw');
|
||||
process.nextTick(() => {
|
||||
throw new Error('accidental error');
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}));
|
||||
|
||||
// Startup a basic cluster
|
||||
cluster.fork();
|
||||
@ -55,51 +54,36 @@ if (cluster.isWorker) {
|
||||
} else {
|
||||
// This is the testcase
|
||||
|
||||
var fork = require('child_process').fork;
|
||||
|
||||
var isAlive = function(pid) {
|
||||
try {
|
||||
//this will throw an error if the process is dead
|
||||
process.kill(pid, 0);
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
const fork = require('child_process').fork;
|
||||
|
||||
var masterExited = false;
|
||||
var workersExited = false;
|
||||
|
||||
// List all workers
|
||||
var workers = [];
|
||||
const workers = [];
|
||||
|
||||
// Spawn a cluster process
|
||||
var master = fork(process.argv[1], ['cluster'], {silent: true});
|
||||
const master = fork(process.argv[1], ['cluster'], {silent: true});
|
||||
|
||||
// Handle messages from the cluster
|
||||
master.on('message', function(data) {
|
||||
master.on('message', common.mustCall((data) => {
|
||||
|
||||
// Add worker pid to list and progress tracker
|
||||
if (data.cmd === 'worker') {
|
||||
workers.push(data.workerPID);
|
||||
}
|
||||
});
|
||||
}, totalWorkers));
|
||||
|
||||
// When cluster is dead
|
||||
master.on('exit', function(code) {
|
||||
master.on('exit', common.mustCall((code) => {
|
||||
|
||||
// Check that the cluster died accidentally (non-zero exit code)
|
||||
masterExited = !!code;
|
||||
|
||||
var pollWorkers = function() {
|
||||
const pollWorkers = function() {
|
||||
// When master is dead all workers should be dead too
|
||||
var alive = false;
|
||||
workers.forEach(function(pid) {
|
||||
if (isAlive(pid)) {
|
||||
alive = true;
|
||||
}
|
||||
});
|
||||
workers.forEach((pid) => alive = common.isAlive(pid));
|
||||
if (alive) {
|
||||
setTimeout(pollWorkers, 50);
|
||||
} else {
|
||||
@ -109,13 +93,13 @@ if (cluster.isWorker) {
|
||||
|
||||
// Loop indefinitely until worker exit
|
||||
pollWorkers();
|
||||
});
|
||||
}));
|
||||
|
||||
process.once('exit', function() {
|
||||
var m = 'The master did not die after an error was thrown';
|
||||
assert.ok(masterExited, m);
|
||||
m = 'The workers did not die after an error in the master';
|
||||
assert.ok(workersExited, m);
|
||||
process.once('exit', () => {
|
||||
assert(masterExited,
|
||||
'The master did not die after an error was thrown');
|
||||
assert(workersExited,
|
||||
'The workers did not die after an error in the master');
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -1,17 +1,17 @@
|
||||
'use strict';
|
||||
var common = require('../common');
|
||||
var assert = require('assert');
|
||||
var cluster = require('cluster');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const cluster = require('cluster');
|
||||
|
||||
if (cluster.isWorker) {
|
||||
|
||||
// keep the worker alive
|
||||
var http = require('http');
|
||||
const http = require('http');
|
||||
http.Server().listen(common.PORT, '127.0.0.1');
|
||||
|
||||
} else if (process.argv[2] === 'cluster') {
|
||||
|
||||
var worker = cluster.fork();
|
||||
const worker = cluster.fork();
|
||||
|
||||
// send PID info to testcase process
|
||||
process.send({
|
||||
@ -19,59 +19,47 @@ if (cluster.isWorker) {
|
||||
});
|
||||
|
||||
// terminate the cluster process
|
||||
worker.once('listening', function() {
|
||||
setTimeout(function() {
|
||||
worker.once('listening', common.mustCall(() => {
|
||||
setTimeout(() => {
|
||||
process.exit(0);
|
||||
}, 1000);
|
||||
});
|
||||
}));
|
||||
|
||||
} else {
|
||||
|
||||
// This is the testcase
|
||||
var fork = require('child_process').fork;
|
||||
|
||||
// is process alive helper
|
||||
var isAlive = function(pid) {
|
||||
try {
|
||||
//this will throw an error if the process is dead
|
||||
process.kill(pid, 0);
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
const fork = require('child_process').fork;
|
||||
|
||||
// Spawn a cluster process
|
||||
var master = fork(process.argv[1], ['cluster']);
|
||||
const master = fork(process.argv[1], ['cluster']);
|
||||
|
||||
// get pid info
|
||||
var pid = null;
|
||||
master.once('message', function(data) {
|
||||
master.once('message', (data) => {
|
||||
pid = data.pid;
|
||||
});
|
||||
|
||||
// When master is dead
|
||||
var alive = true;
|
||||
master.on('exit', function(code) {
|
||||
master.on('exit', common.mustCall((code) => {
|
||||
|
||||
// make sure that the master died on purpose
|
||||
assert.equal(code, 0);
|
||||
assert.strictEqual(code, 0);
|
||||
|
||||
// check worker process status
|
||||
var pollWorker = function() {
|
||||
alive = isAlive(pid);
|
||||
const pollWorker = function() {
|
||||
alive = common.isAlive(pid);
|
||||
if (alive) {
|
||||
setTimeout(pollWorker, 50);
|
||||
}
|
||||
};
|
||||
// Loop indefinitely until worker exit.
|
||||
pollWorker();
|
||||
});
|
||||
}));
|
||||
|
||||
process.once('exit', function() {
|
||||
assert.equal(typeof pid, 'number', 'did not get worker pid info');
|
||||
assert.equal(alive, false, 'worker was alive after master died');
|
||||
process.once('exit', () => {
|
||||
assert.strictEqual(typeof pid, 'number', 'did not get worker pid info');
|
||||
assert.strictEqual(alive, false, 'worker was alive after master died');
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -1,25 +1,25 @@
|
||||
'use strict';
|
||||
var common = require('../common');
|
||||
var assert = require('assert');
|
||||
var cluster = require('cluster');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const cluster = require('cluster');
|
||||
|
||||
if (cluster.isWorker) {
|
||||
var http = require('http');
|
||||
http.Server(function() {
|
||||
const http = require('http');
|
||||
http.Server(() => {
|
||||
|
||||
}).listen(common.PORT, '127.0.0.1');
|
||||
const worker = cluster.worker;
|
||||
assert.strictEqual(worker.exitedAfterDisconnect, worker.suicide);
|
||||
|
||||
cluster.worker.on('disconnect', function() {
|
||||
cluster.worker.on('disconnect', common.mustCall(() => {
|
||||
assert.strictEqual(cluster.worker.exitedAfterDisconnect,
|
||||
cluster.worker.suicide);
|
||||
process.exit(42);
|
||||
});
|
||||
}));
|
||||
|
||||
} else if (cluster.isMaster) {
|
||||
|
||||
var checks = {
|
||||
const checks = {
|
||||
cluster: {
|
||||
emitDisconnect: false,
|
||||
emitExit: false,
|
||||
@ -35,50 +35,40 @@ if (cluster.isWorker) {
|
||||
}
|
||||
};
|
||||
|
||||
// helper function to check if a process is alive
|
||||
var alive = function(pid) {
|
||||
try {
|
||||
process.kill(pid, 0);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// start worker
|
||||
var worker = cluster.fork();
|
||||
const worker = cluster.fork();
|
||||
|
||||
// Disconnect worker when it is ready
|
||||
worker.once('listening', function() {
|
||||
worker.once('listening', common.mustCall(() => {
|
||||
worker.disconnect();
|
||||
});
|
||||
}));
|
||||
|
||||
// Check cluster events
|
||||
cluster.once('disconnect', function() {
|
||||
cluster.once('disconnect', common.mustCall(() => {
|
||||
checks.cluster.emitDisconnect = true;
|
||||
});
|
||||
cluster.once('exit', function() {
|
||||
}));
|
||||
cluster.once('exit', common.mustCall(() => {
|
||||
checks.cluster.emitExit = true;
|
||||
});
|
||||
}));
|
||||
|
||||
// Check worker events and properties
|
||||
worker.once('disconnect', function() {
|
||||
worker.once('disconnect', common.mustCall(() => {
|
||||
checks.worker.emitDisconnect = true;
|
||||
checks.worker.voluntaryMode = worker.exitedAfterDisconnect;
|
||||
checks.worker.state = worker.state;
|
||||
});
|
||||
}));
|
||||
|
||||
// Check that the worker died
|
||||
worker.once('exit', function(code) {
|
||||
worker.once('exit', common.mustCall((code) => {
|
||||
checks.worker.emitExit = true;
|
||||
checks.worker.died = !alive(worker.process.pid);
|
||||
checks.worker.died = !common.isAlive(worker.process.pid);
|
||||
checks.worker.emitDisconnectInsideWorker = code === 42;
|
||||
});
|
||||
}));
|
||||
|
||||
process.once('exit', function() {
|
||||
process.once('exit', () => {
|
||||
|
||||
var w = checks.worker;
|
||||
var c = checks.cluster;
|
||||
const w = checks.worker;
|
||||
const c = checks.cluster;
|
||||
|
||||
// events
|
||||
assert.ok(w.emitDisconnect, 'Disconnect event did not emit');
|
||||
@ -89,8 +79,10 @@ if (cluster.isWorker) {
|
||||
assert.ok(c.emitExit, 'Exit event did not emit');
|
||||
|
||||
// flags
|
||||
assert.equal(w.state, 'disconnected', 'The state property was not set');
|
||||
assert.equal(w.voluntaryMode, true, 'Voluntary exit mode was not set');
|
||||
assert.strictEqual(w.state, 'disconnected',
|
||||
'The state property was not set');
|
||||
assert.strictEqual(w.voluntaryMode, true,
|
||||
'Voluntary exit mode was not set');
|
||||
|
||||
// is process alive
|
||||
assert.ok(w.died, 'The worker did not die');
|
||||
|
@ -6,24 +6,24 @@
|
||||
// - the worker.exitedAfterDisconnect flag, and worker.state are correct
|
||||
// - the worker process actually goes away
|
||||
|
||||
var common = require('../common');
|
||||
var assert = require('assert');
|
||||
var cluster = require('cluster');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const cluster = require('cluster');
|
||||
|
||||
var EXIT_CODE = 42;
|
||||
const EXIT_CODE = 42;
|
||||
|
||||
if (cluster.isWorker) {
|
||||
var http = require('http');
|
||||
var server = http.Server(function() { });
|
||||
const http = require('http');
|
||||
const server = http.Server(() => { });
|
||||
|
||||
server.once('listening', function() {
|
||||
server.once('listening', common.mustCall(() => {
|
||||
process.exit(EXIT_CODE);
|
||||
});
|
||||
}));
|
||||
server.listen(common.PORT, '127.0.0.1');
|
||||
|
||||
} else if (cluster.isMaster) {
|
||||
|
||||
var expected_results = {
|
||||
const expected_results = {
|
||||
cluster_emitDisconnect: [1, "the cluster did not emit 'disconnect'"],
|
||||
cluster_emitExit: [1, "the cluster did not emit 'exit'"],
|
||||
cluster_exitCode: [EXIT_CODE, 'the cluster exited w/ incorrect exitCode'],
|
||||
@ -38,7 +38,7 @@ if (cluster.isWorker) {
|
||||
worker_exitCode: [EXIT_CODE, 'the worker exited w/ incorrect exitCode'],
|
||||
worker_signalCode: [null, 'the worker exited w/ incorrect signalCode']
|
||||
};
|
||||
var results = {
|
||||
const results = {
|
||||
cluster_emitDisconnect: 0,
|
||||
cluster_emitExit: 0,
|
||||
worker_emitDisconnect: 0,
|
||||
@ -47,51 +47,45 @@ if (cluster.isWorker) {
|
||||
|
||||
|
||||
// start worker
|
||||
var worker = cluster.fork();
|
||||
|
||||
worker.once('listening', function() {
|
||||
// the worker is up and running...
|
||||
});
|
||||
|
||||
const worker = cluster.fork();
|
||||
|
||||
// Check cluster events
|
||||
cluster.on('disconnect', function() {
|
||||
cluster.on('disconnect', common.mustCall(() => {
|
||||
results.cluster_emitDisconnect += 1;
|
||||
});
|
||||
cluster.on('exit', function(worker) {
|
||||
}));
|
||||
cluster.on('exit', common.mustCall((worker) => {
|
||||
results.cluster_exitCode = worker.process.exitCode;
|
||||
results.cluster_signalCode = worker.process.signalCode;
|
||||
results.cluster_emitExit += 1;
|
||||
});
|
||||
}));
|
||||
|
||||
// Check worker events and properties
|
||||
worker.on('disconnect', function() {
|
||||
worker.on('disconnect', common.mustCall(() => {
|
||||
results.worker_emitDisconnect += 1;
|
||||
results.worker_suicideMode = worker.suicide;
|
||||
results.worker_exitedAfterDisconnect = worker.exitedAfterDisconnect;
|
||||
results.worker_state = worker.state;
|
||||
if (results.worker_emitExit > 0) {
|
||||
process.nextTick(function() { finish_test(); });
|
||||
process.nextTick(() => finish_test());
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
// Check that the worker died
|
||||
worker.once('exit', function(exitCode, signalCode) {
|
||||
worker.once('exit', common.mustCall((exitCode, signalCode) => {
|
||||
results.worker_exitCode = exitCode;
|
||||
results.worker_signalCode = signalCode;
|
||||
results.worker_emitExit += 1;
|
||||
results.worker_died = !alive(worker.process.pid);
|
||||
results.worker_died = !common.isAlive(worker.process.pid);
|
||||
if (results.worker_emitDisconnect > 0) {
|
||||
process.nextTick(function() { finish_test(); });
|
||||
process.nextTick(() => finish_test());
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
var finish_test = function() {
|
||||
const finish_test = function() {
|
||||
try {
|
||||
checkResults(expected_results, results);
|
||||
} catch (exc) {
|
||||
console.error('FAIL: ' + exc.message);
|
||||
if (exc.name != 'AssertionError') {
|
||||
if (exc.name !== 'AssertionError') {
|
||||
console.trace(exc);
|
||||
}
|
||||
|
||||
@ -105,26 +99,13 @@ if (cluster.isWorker) {
|
||||
// some helper functions ...
|
||||
|
||||
function checkResults(expected_results, results) {
|
||||
for (var k in expected_results) {
|
||||
for (const k in expected_results) {
|
||||
const actual = results[k];
|
||||
const expected = expected_results[k];
|
||||
|
||||
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;
|
||||
assert.strictEqual(actual,
|
||||
expected && expected.length ? expected[0] : expected,
|
||||
(expected[1] || '') +
|
||||
` [expected: ${expected[0]} / actual: ${actual}]`);
|
||||
}
|
||||
}
|
||||
|
@ -6,20 +6,20 @@
|
||||
// - the worker.exitedAfterDisconnect flag, and worker.state are correct
|
||||
// - the worker process actually goes away
|
||||
|
||||
var common = require('../common');
|
||||
var assert = require('assert');
|
||||
var cluster = require('cluster');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const cluster = require('cluster');
|
||||
|
||||
if (cluster.isWorker) {
|
||||
var http = require('http');
|
||||
var server = http.Server(function() { });
|
||||
const http = require('http');
|
||||
const server = http.Server(() => { });
|
||||
|
||||
server.once('listening', function() { });
|
||||
server.once('listening', common.mustCall(() => { }));
|
||||
server.listen(common.PORT, '127.0.0.1');
|
||||
|
||||
} else if (cluster.isMaster) {
|
||||
|
||||
var KILL_SIGNAL = 'SIGKILL',
|
||||
const KILL_SIGNAL = 'SIGKILL',
|
||||
expected_results = {
|
||||
cluster_emitDisconnect: [1, "the cluster did not emit 'disconnect'"],
|
||||
cluster_emitExit: [1, "the cluster did not emit 'exit'"],
|
||||
@ -45,40 +45,40 @@ if (cluster.isWorker) {
|
||||
|
||||
|
||||
// start worker
|
||||
var worker = cluster.fork();
|
||||
const worker = cluster.fork();
|
||||
|
||||
// when the worker is up and running, kill it
|
||||
worker.once('listening', function() {
|
||||
worker.once('listening', common.mustCall(() => {
|
||||
worker.process.kill(KILL_SIGNAL);
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
// Check cluster events
|
||||
cluster.on('disconnect', function() {
|
||||
cluster.on('disconnect', common.mustCall(() => {
|
||||
results.cluster_emitDisconnect += 1;
|
||||
});
|
||||
cluster.on('exit', function(worker) {
|
||||
}));
|
||||
cluster.on('exit', common.mustCall((worker) => {
|
||||
results.cluster_exitCode = worker.process.exitCode;
|
||||
results.cluster_signalCode = worker.process.signalCode;
|
||||
results.cluster_emitExit += 1;
|
||||
});
|
||||
}));
|
||||
|
||||
// Check worker events and properties
|
||||
worker.on('disconnect', function() {
|
||||
worker.on('disconnect', common.mustCall(() => {
|
||||
results.worker_emitDisconnect += 1;
|
||||
results.worker_exitedAfter = worker.exitedAfterDisconnect;
|
||||
results.worker_state = worker.state;
|
||||
});
|
||||
}));
|
||||
|
||||
// Check that the worker died
|
||||
worker.once('exit', function(exitCode, signalCode) {
|
||||
worker.once('exit', common.mustCall((exitCode, signalCode) => {
|
||||
results.worker_exitCode = exitCode;
|
||||
results.worker_signalCode = signalCode;
|
||||
results.worker_emitExit += 1;
|
||||
results.worker_died = !alive(worker.process.pid);
|
||||
});
|
||||
results.worker_died = !common.isAlive(worker.process.pid);
|
||||
}));
|
||||
|
||||
process.on('exit', function() {
|
||||
process.on('exit', () => {
|
||||
checkResults(expected_results, results);
|
||||
});
|
||||
}
|
||||
@ -86,25 +86,13 @@ if (cluster.isWorker) {
|
||||
// some helper functions ...
|
||||
|
||||
function checkResults(expected_results, results) {
|
||||
for (var k in expected_results) {
|
||||
for (const k in expected_results) {
|
||||
const actual = results[k];
|
||||
const expected = expected_results[k];
|
||||
|
||||
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;
|
||||
assert.strictEqual(actual,
|
||||
expected && expected.length ? expected[0] : expected,
|
||||
(expected[1] || '') +
|
||||
` [expected: ${expected[0]} / actual: ${actual}]`);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user