enhancer-recluster
Version:
Clustering library with support for zero-downtime reloading
141 lines (120 loc) • 4.78 kB
JavaScript
var lib = require('./lib/index'),
runTest = lib.runTest,
request = lib.request;
/**
* Termination tests
* 1) dies ungracefully after 1/2 s (lib/server-die-halfsec.js)
* 2) disconnects IPC after 1/2 s (lib/server-disconnect-halfsec.js)
* 3) msgs 'disconnect' after 1/2 s (lib/server-msg-disconnect-halfsec.js)
* Then test if
* 1) they have been replaced quickly
* 2) they have been killed after a while for (2) and (3)
*
* Recommended settings are:
* respawn: 0.01 - for quick respawns
* backoff: 0.01 - for quick respawns
* workers: 2 - to make sure we're not testing only for one
* timeout: 0.3 - to be able to test if timeout works
* before the replacement tries to signal that its dead
*
* I know that timing-based tests are not perfect, but I have no better
* idea at the moment.
*/
function extend(opt, add) {
var res = {};
for (var key in opt) res[key] = opt[key];
for (var key in add) res[key] = add[key];
return res;
}
function pids() {
return lib.balancer.workers().map(function(w) { return w.process.pid; });
}
function activePids() {
var pids = [];
var aw = lib.balancer.activeWorkers();
for (var key in aw) {
if (key != 'length' && aw[key]) {
pids.push(aw[key].process.pid);
}
}
return pids;
}
function activeCount() {
return Object.keys(require('cluster').workers).length
}
var termSettings = {
respawn: 0.001, backoff: 0.001, workers: 2, timeout: 0.3,
readyWhen: 'listening'
};
// kill timeout
var timeoutKill = termSettings.timeout * 1000;
// Time after which the worker dies
var timeoutWorker = 500;
// Time to wait for a reload to happen
var timeToSpawn = 100;
// Time necessary to terminate a worker
var timeToKill = 20;
termSettings.file = 'server-die-halfsec.js';
runTest("dying server", termSettings, function(t) {
var wrkpids = pids();
setTimeout(function() {
t.equal(activePids().length, 2, "2 workers serving requests");
}, timeToSpawn);
setTimeout(function() {
var wrkpids2 = pids();
var wrkpidsActive = activePids();
t.equal(wrkpids2.length, 2, "2 workers should be active");
t.equal(wrkpidsActive.length, 0, "0 workers serving requests");
t.equal(activeCount(), 2, "2 workers should be active according to cluster");
t.notEquals(wrkpids[0], wrkpids2[0], "workers have been replaced");
t.notEquals(wrkpids[1], wrkpids2[1], "workers have been replaced");
t.end();
}, timeoutWorker + timeToSpawn);
});
var discSettings = extend(
termSettings, {file: 'server-disconnect-halfsec.js'});
runTest("IPC-disconnecting server", discSettings, function(t) {
setTimeout(function() {
t.equal(activePids().length, 2, "2 workers serving requests");
}, timeToSpawn);
setTimeout(function() {
t.equal(pids().length, 4, "4 workers present, 2 disconnected");
t.equal(activePids().length, 0, "0 workers serving requests");
t.equal(activeCount(), 4, "4 workers should be active according to cluster");
}, timeoutWorker + timeToSpawn);
setTimeout(function() {
t.equal(pids().length, 2, "2 workers present");
t.equal(activePids().length, 2, "2 workers serving requests");
t.equal(activeCount(), 2, "2 workers should be active according to cluster");
t.end();
}, timeoutWorker + timeToSpawn + timeoutKill + timeToKill);
});
var dmsgSettings = extend(
termSettings, {file: 'server-msg-disconnect-halfsec.js'});
runTest("IPC-disconnecting server via msg", dmsgSettings, function(t) {
setTimeout(function() {
t.equal(activePids().length, 2, "2 workers serving requests");
}, timeToSpawn);
setTimeout(function() {
t.equal(pids().length, 4, "4 workers present, 2 disconnected");
t.equal(activePids().length, 0, "0 workers serving requests");
t.equal(activeCount(), 4, "4 workers should be active according to cluster");
}, timeoutWorker + timeToSpawn);
setTimeout(function() {
t.equal(pids().length, 2, "2 workers present");
t.equal(activePids().length, 2, "2 workers serving requests");
t.equal(activeCount(), 2, "2 workers should be active according to cluster");
t.end();
}, timeoutWorker + timeToSpawn + timeoutKill + timeToKill);
});
runTest("stopped cluster", termSettings, function(t) {
setTimeout(function() {
lib.balancer.stop();
}, timeToSpawn);
setTimeout(function() {
t.equal(pids().length, 0, "0 workers should be active");
t.equal(activePids().length, 0, "0 workers serving requests");
t.equal(activeCount(), 0, "0 workers should be active according to cluster");
t.end();
}, timeoutWorker + timeToSpawn);
});