restify-new-nodejs-compatible
Version:
REST framework
155 lines (140 loc) • 4.62 kB
JavaScript
;
/* eslint-disable func-names */
var assert = require('chai').assert;
var proxyquire = require('proxyquire');
var restify = require('../../lib/index.js');
var restifyClients = require('restify-clients');
var pidusage = require('pidusage');
// Allow tests to set the CPU usage returned by pidUsage
var CPU = 50;
var cpuUsageThrottle = proxyquire('../../lib/plugins/cpuUsageThrottle.js', {
pidusage: function(pid, cb) {
return cb(null, { cpu: CPU });
}
});
var MR = Math.random;
describe('cpuUsageThrottle', function() {
var plugin;
before('Setup: stub math.random', function(done) {
Math.random = function() {
return 0;
};
done();
});
it('Unit: Should shed load', function(done) {
var opts = { limit: 0, interval: 500 };
plugin = cpuUsageThrottle(opts);
function next(cont) {
assert(cont instanceof Error, 'Should call next with error');
assert.equal(cont.statusCode, 503, 'Defaults to 503 status');
done();
}
plugin({}, {}, next);
});
it('Unit: Should let request through when not under load', function(done) {
var opts = { interval: 500, limit: 0.9 };
plugin = cpuUsageThrottle(opts);
function next(cont) {
assert.isUndefined(cont, 'Should call next');
done();
}
plugin({}, {}, next);
});
it('Unit: Update should update state', function(done) {
var opts = {
max: 1,
limit: 0.9,
halfLife: 50,
interval: 50
};
plugin = cpuUsageThrottle(opts);
opts = {
max: 0.5,
limit: 0.1,
halfLife: 1000,
interval: 1000
};
plugin.update(opts);
assert.equal(plugin.state.limit, opts.limit, 'opts.limit');
assert.equal(plugin.state.max, opts.max, 'opts.max');
assert.equal(plugin.state.halfLife, opts.halfLife, 'opts.halfLife');
assert.equal(plugin.state.interval, opts.interval, 'opts.interval');
done();
});
it('Unit: Should have proper name', function(done) {
var opts = {
max: 1,
limit: 0.9,
halfLife: 50,
interval: 50
};
plugin = cpuUsageThrottle(opts);
assert.equal(plugin.name, 'cpuUsageThrottle');
done();
});
it('Unit: Should report proper lag', function(done) {
var opts = { max: 1, limit: 0.9, halfLife: 50, interval: 50 };
var dn = Date.now;
var now = 0;
// First timer will be 0, all future timers will be interval
Date.now = function() {
return (now++ > 0) * opts.interval;
};
plugin = cpuUsageThrottle(opts);
Date.now = dn;
assert.equal(plugin.state.lag, 0);
done();
});
it('Integration: Should shed load', function(done) {
var server = restify.createServer();
var client = {
close: function() {}
};
var opts = { interval: 500, limit: 0 };
plugin = cpuUsageThrottle(opts);
server.pre(plugin);
server.get('/foo', function(req, res, next) {
res.send(200);
next();
});
server.listen(0, '127.0.0.1', function() {
client = restifyClients.createJsonClient({
url: 'http://127.0.0.1:' + server.address().port,
retry: false
});
client.get({ path: '/foo' }, function(e, _, res) {
assert(e, 'Second request is shed');
assert.equal(
res.statusCode,
503,
'Default shed status code returned'
);
clearTimeout(plugin._timeout);
// we should close the server else mocha wont exit
server.close();
done();
});
});
});
it('Integration: pidusage should report CPU usage', function(done) {
assert.isFunction(pidusage, 'pidusage can be invoked');
pidusage(process.pid, function(e, stat) {
assert.ifError(e);
assert.isObject(stat);
assert.isNumber(stat.cpu);
pidusage.clear();
done();
});
});
afterEach(function(done) {
if (plugin) {
plugin.close();
}
plugin = undefined;
done();
});
after('Teardown: Reset Math.random', function(done) {
Math.random = MR;
done();
});
});