From e34759e880c74e0158140c361c215073e6748d04 Mon Sep 17 00:00:00 2001 From: retrohacker Date: Fri, 1 Sep 2017 14:09:18 -0700 Subject: [PATCH] Implement tests --- lib/plugins/cpuUsageThrottle.js | 4 +- package.json | 1 + test/plugins/cpuUsageThrottle.test.js | 119 ++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 test/plugins/cpuUsageThrottle.test.js diff --git a/lib/plugins/cpuUsageThrottle.js b/lib/plugins/cpuUsageThrottle.js index 109963b2e..7a8a9c902 100644 --- a/lib/plugins/cpuUsageThrottle.js +++ b/lib/plugins/cpuUsageThrottle.js @@ -53,7 +53,7 @@ function cpuUsageThrottle (opts) { // usage over the interval and determines whether or not the process should // be shedding load function updateReject() { - pidusage.stat(function (e, stat) { + pidusage.stat(process.pid, function (e, stat) { // If we fail to stat for whatever reason, err on the side of // accepting traffic, while failure probably indicates something // horribly wrong with the server, identifying this error case and @@ -67,7 +67,7 @@ function cpuUsageThrottle (opts) { // Divide by 100 to match linux's top format self._cpu = stat.cpu / 100; // Update reject - self._reject = self.cpu > self._limit; + self._reject = self._cpu > self._limit; self._timeout = setTimeout(updateReject, self._interval); }); } diff --git a/package.json b/package.json index 3fd577fea..f818f5adc 100644 --- a/package.json +++ b/package.json @@ -129,6 +129,7 @@ "mocha": "^3.2.0", "nodeunit": "^0.11.0", "nsp": "^2.2.0", + "proxyquire": "^1.8.0", "restify-clients": "^1.2.1", "rimraf": "^2.4.3", "validator": "^7.0.0", diff --git a/test/plugins/cpuUsageThrottle.test.js b/test/plugins/cpuUsageThrottle.test.js new file mode 100644 index 000000000..556bc6955 --- /dev/null +++ b/test/plugins/cpuUsageThrottle.test.js @@ -0,0 +1,119 @@ +'use strict'; + +var assert = require('chai').assert; +var proxyquire = require('proxyquire'); +var restify = require('../../lib/index.js'); +var restifyClients = require('restify-clients'); + +// Allow tests to set the CPU usage and error message returned by pidUsage +var ERROR = null; +var CPU = 50; + +var cpuUsageThrottle = proxyquire('../../lib/plugins/cpuUsageThrottle.js', { + pidusage: { + stat: function (pid, cb) { + return cb(ERROR, { cpu: CPU }); + } + } +}); + +describe('cpuUsageThrottle', function () { + + it('Unit: Should shed load', function (done) { + var logged = false; + var opts = { limit: 0, interval: 500 }; + var plugin = cpuUsageThrottle(opts); + function send (body) { + assert(logged, 'Should have emitted a log'); + assert.equal(body.statusCode, 503, 'Defaults to 503 status'); + assert(body instanceof Error, 'Defaults to error body'); + } + function next (cont) { + assert.isFalse(cont, 'Should call next with false'); + clearTimeout(plugin._timeout); + done(); + } + function trace () { + logged = true; + } + var log = { trace: trace }; + var fakeReq = { log: log }; + plugin(fakeReq, { send: send }, next); + }); + + it('Unit: Should support custom response', function (done) { + var err = new Error('foo'); + var opts = { limit: 0, interval:500, err: err }; + var plugin = cpuUsageThrottle(opts); + function send (body) { + assert.equal(body, err, 'Overrides body'); + } + function next (cont) { + assert.isFalse(cont, 'Should call next with false'); + clearTimeout(plugin._timeout); + done(); + } + var fakeReq = { log : { trace: function () {} } }; + plugin(fakeReq, { send: send }, next); + }); + + it('Unit: Should let request through when not under load', function (done) { + var opts = { interval: 500, limit: 1 }; + var plugin = cpuUsageThrottle(opts); + function send () { + assert(false, 'Should not call send'); + clearTimeout(plugin._timeout); + done(); + } + function next (cont) { + assert.isUndefined(cont, 'Should call next'); + clearTimeout(plugin._timeout); + done(); + } + var fakeReq = { log : { trace: function () {} } }; + plugin(fakeReq, { send: send }, next); + }); + + it('Integration: Should shed load', function (done) { + var server = restify.createServer(); + var client = { + close: function () {} + }; + var isDone = false; + var to; + function finish() { + if (isDone) { + return null; + } + clearTimeout(to); + isDone = true; + client.close(); + server.close(); + return done(); + } + to = setTimeout(finish, 1000); + var err = new Error('foo'); + err.statusCode = 555; + var opts = { interval: 500, limit: 0, err: err }; + var 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(e.name, + 'InternalServerError', 'Default err returned'); + assert.equal(res.statusCode, 555, + 'Default shed status code returned'); + clearTimeout(plugin._timeout); + }); + }); + }); +});