From e7034fadb4f6658473d3713fdb245bc8b8c0b6c3 Mon Sep 17 00:00:00 2001 From: Matthew Dobson Date: Thu, 17 Nov 2016 15:43:13 -0800 Subject: [PATCH 1/5] Adding functional tests for plugins. --- package.json | 2 +- test/accumulate-request-test.js | 94 ++++++++++++++++++++++++++++++++ test/accumulate-response-test.js | 94 ++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 test/accumulate-request-test.js create mode 100644 test/accumulate-response-test.js diff --git a/package.json b/package.json index a1c3cf0..a3f5208 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Plugins for Apige Edge Microgateway", "main": "index.js", "scripts": { - "test": "bin/test" + "test": "./node_modules/.bin/mocha -R spec" }, "dependencies": { "async": "^1.4.2", diff --git a/test/accumulate-request-test.js b/test/accumulate-request-test.js new file mode 100644 index 0000000..01cda3d --- /dev/null +++ b/test/accumulate-request-test.js @@ -0,0 +1,94 @@ +const accumulateRequest = require('../accumulate-request/index'); +const assert = require('assert'); + +describe('accumulate request plugin', () => { + var plugin = null; + + beforeEach(() => { + var config = {}; + var logger = {}; + var stats = {}; + + plugin = accumulateRequest.init.apply(null, config, logger, stats); + }); + + it('exposes an ondata_request handler', () => { + assert.ok(plugin.ondata_request); + }); + + it('exposes an onend_request handler', () => { + assert.ok(plugin.onend_request); + }); + + it('calls back with two null function arguments in the ondata_request handler', (done) => { + var cb = (err, result) => { + assert.equal(err, null); + assert.equal(result, null); + done(); + } + + + plugin.ondata_request.apply(null, [{}, {}, Buffer.alloc(5, 'a'), cb]); + }); + + it('will collect all buffers provided to ondata_request handler, concatenate them, and return them as a single buffer', (done) => { + var desiredResult = 'aaaaaaaaaaaaaaa'; + + var ondata_cb = (err, result) => { + assert.equal(err, null); + assert.equal(result, null); + assert.ok(req._chunks); + } + + var onend_cb = (err, result) => { + assert.equal(err, null); + assert.equal(result.toString(), desiredResult); + done(); + } + + var req = {}; + + plugin.ondata_request.apply(null, [req, {}, Buffer.alloc(5, 'a'), ondata_cb]); + plugin.ondata_request.apply(null, [req, {}, Buffer.alloc(5, 'a'), ondata_cb]); + plugin.ondata_request.apply(null, [req, {}, Buffer.alloc(5, 'a'), ondata_cb]); + + plugin.onend_request.apply(null, [req, {}, null, onend_cb]); + }); + + it('will append data included in the end call to the buffer', (done) => { + var desiredResult = 'aaaaaaaaaaaaaaaaaaaa'; + + var ondata_cb = (err, result) => { + assert.equal(err, null); + assert.equal(result, null); + assert.ok(req._chunks); + } + + var onend_cb = (err, result) => { + assert.equal(err, null); + assert.equal(result.toString(), desiredResult); + done(); + } + + var req = {}; + + plugin.ondata_request.apply(null, [req, {}, Buffer.alloc(5, 'a'), ondata_cb]); + plugin.ondata_request.apply(null, [req, {}, Buffer.alloc(5, 'a'), ondata_cb]); + plugin.ondata_request.apply(null, [req, {}, Buffer.alloc(5, 'a'), ondata_cb]); + + plugin.onend_request.apply(null, [req, {}, Buffer.alloc(5, 'a'), onend_cb]); + }); + + it('will create a req._chunks object on the request object', (done) => { + var req = {}; + var cb = (err, result) => { + assert.equal(err, null); + assert.equal(result, null); + assert.ok(req._chunks); + assert.equal(req._chunks.toString(), 'aaaaa'); + done(); + } + + plugin.ondata_request.apply(null, [req, {}, Buffer.alloc(5, 'a'), cb]); + }); +}) diff --git a/test/accumulate-response-test.js b/test/accumulate-response-test.js new file mode 100644 index 0000000..df91cf5 --- /dev/null +++ b/test/accumulate-response-test.js @@ -0,0 +1,94 @@ +const accumulateRequest = require('../accumulate-response/index'); +const assert = require('assert'); + +describe('accumulate response plugin', () => { + var plugin = null; + + beforeEach(() => { + var config = {}; + var logger = {}; + var stats = {}; + + plugin = accumulateRequest.init.apply(null, config, logger, stats); + }); + + it('exposes an ondata_response handler', () => { + assert.ok(plugin.ondata_response); + }); + + it('exposes an onend_response handler', () => { + assert.ok(plugin.onend_response); + }); + + it('calls back with two null function arguments in the ondata_response handler', (done) => { + var cb = (err, result) => { + assert.equal(err, null); + assert.equal(result, null); + done(); + } + + + plugin.ondata_response.apply(null, [{}, {}, Buffer.alloc(5, 'a'), cb]); + }); + + it('will collect all buffers provided to ondata_response handler, concatenate them, and return them as a single buffer', (done) => { + var desiredResult = 'aaaaaaaaaaaaaaa'; + + var ondata_cb = (err, result) => { + assert.equal(err, null); + assert.equal(result, null); + assert.ok(res._chunks); + } + + var onend_cb = (err, result) => { + assert.equal(err, null); + assert.equal(result.toString(), desiredResult); + done(); + } + + var res = {}; + + plugin.ondata_response.apply(null, [{}, res, Buffer.alloc(5, 'a'), ondata_cb]); + plugin.ondata_response.apply(null, [{}, res, Buffer.alloc(5, 'a'), ondata_cb]); + plugin.ondata_response.apply(null, [{}, res, Buffer.alloc(5, 'a'), ondata_cb]); + + plugin.onend_response.apply(null, [{}, res, null, onend_cb]); + }); + + it('will append data included in the end call to the buffer', (done) => { + var desiredResult = 'aaaaaaaaaaaaaaaaaaaa'; + + var ondata_cb = (err, result) => { + assert.equal(err, null); + assert.equal(result, null); + assert.ok(res._chunks); + } + + var onend_cb = (err, result) => { + assert.equal(err, null); + assert.equal(result.toString(), desiredResult); + done(); + } + + var res = {}; + + plugin.ondata_response.apply(null, [{}, res, Buffer.alloc(5, 'a'), ondata_cb]); + plugin.ondata_response.apply(null, [{}, res, Buffer.alloc(5, 'a'), ondata_cb]); + plugin.ondata_response.apply(null, [{}, res, Buffer.alloc(5, 'a'), ondata_cb]); + + plugin.onend_response.apply(null, [{}, res, Buffer.alloc(5, 'a'), onend_cb]); + }); + + it('will create a req._chunks object on the request object', (done) => { + var res = {}; + var cb = (err, result) => { + assert.equal(err, null); + assert.equal(result, null); + assert.ok(res._chunks); + assert.equal(res._chunks.toString(), 'aaaaa'); + done(); + } + + plugin.ondata_response.apply(null, [{}, res, Buffer.alloc(5, 'a'), cb]); + }); +}) From 8868e6776c020f79cb9e87b20d3a2e59d7ef229f Mon Sep 17 00:00:00 2001 From: Matthew Dobson Date: Thu, 17 Nov 2016 16:12:34 -0800 Subject: [PATCH 2/5] Fixing issues with inital plugin tests. Adding spike arrest tests. --- test/accumulate-request-test.js | 2 +- test/accumulate-response-test.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/accumulate-request-test.js b/test/accumulate-request-test.js index 01cda3d..88f7b6d 100644 --- a/test/accumulate-request-test.js +++ b/test/accumulate-request-test.js @@ -9,7 +9,7 @@ describe('accumulate request plugin', () => { var logger = {}; var stats = {}; - plugin = accumulateRequest.init.apply(null, config, logger, stats); + plugin = accumulateRequest.init.apply(null, [config, logger, stats]); }); it('exposes an ondata_request handler', () => { diff --git a/test/accumulate-response-test.js b/test/accumulate-response-test.js index df91cf5..38b2258 100644 --- a/test/accumulate-response-test.js +++ b/test/accumulate-response-test.js @@ -1,4 +1,4 @@ -const accumulateRequest = require('../accumulate-response/index'); +const accumulateResponse = require('../accumulate-response/index'); const assert = require('assert'); describe('accumulate response plugin', () => { @@ -9,7 +9,7 @@ describe('accumulate response plugin', () => { var logger = {}; var stats = {}; - plugin = accumulateRequest.init.apply(null, config, logger, stats); + plugin = accumulateResponse.init.apply(null, [config, logger, stats]); }); it('exposes an ondata_response handler', () => { From adbc63bb717e6f4cec2789db987512856814ccb4 Mon Sep 17 00:00:00 2001 From: Matthew Dobson Date: Mon, 21 Nov 2016 12:20:08 -0500 Subject: [PATCH 3/5] Adding some more tests. --- quota-memory/index.js | 10 ++++- quota/index.js | 11 ++++- test/cache-test.js | 28 ++++++++++++ test/quota-test.js | 93 +++++++++++++++++++++++++++++++++++++++ test/spike-arrest-test.js | 48 ++++++++++++++++++++ 5 files changed, 186 insertions(+), 4 deletions(-) create mode 100644 test/cache-test.js create mode 100644 test/quota-test.js create mode 100644 test/spike-arrest-test.js diff --git a/quota-memory/index.js b/quota-memory/index.js index 6d0579d..fb4ce97 100644 --- a/quota-memory/index.js +++ b/quota-memory/index.js @@ -5,7 +5,9 @@ var Quota = require('volos-quota-memory'); var debug = require('debug')('gateway:quota'); module.exports.init = function(config, logger, stats) { - + console.log('CONFIG START'); + console.log(config); + console.log('CONFIG END'); var quotas = {}; // productName -> connectMiddleware var options = { @@ -14,7 +16,11 @@ module.exports.init = function(config, logger, stats) { Object.keys(config).forEach(function(productName) { var product = config[productName]; - if (!product.uri && !product.key && !product.secret && !product.allow && !product.interval) return; // skip non-quota config + if (!product.uri && !product.key && !product.secret && !product.allow && !product.interval) { + console.log('Not enough info to configure quota'); + return; // skip non-quota config + } + var quota = Quota.create(config[productName]); quotas[productName] = quota.connectMiddleware().apply(options); debug('created quota for', productName); diff --git a/quota/index.js b/quota/index.js index 0830ecf..7e377fb 100644 --- a/quota/index.js +++ b/quota/index.js @@ -9,12 +9,19 @@ module.exports.init = function(config, logger, stats) { var quotas = {}; // productName -> connectMiddleware var options = { - key: function(req) { return req.token.application_name; } + key: function(req) { + return req.token.application_name; + } }; Object.keys(config).forEach(function(productName) { var product = config[productName]; - if (!product.uri && !product.key && !product.secret && !product.allow && !product.interval) return; // skip non-quota config + if (!product.uri && !product.key && !product.secret && !product.allow && !product.interval) { + // skip non-quota config + console.log('Not enough info for configuring quota'); + return; + } + var quota = Quota.create(config[productName]); quotas[productName] = quota.connectMiddleware().apply(options); debug('created quota for', productName); diff --git a/test/cache-test.js b/test/cache-test.js new file mode 100644 index 0000000..1662e08 --- /dev/null +++ b/test/cache-test.js @@ -0,0 +1,28 @@ +const cache = require('../cache/index'); +const assert = require('assert'); + +describe('cache plugin', () => { + var plugin = null; + + beforeEach(() => { + var config = {}; + var logger = {}; + var stats = {}; + + plugin = cache.init.apply(null, [config, logger, stats]); + }); + + it('exposes an onrequest handler', () => { + assert.ok(plugin.onrequest); + }); + + it('will call next if there is no token attached to the request object', (done) => { + const onrequest_cb = () => { + done(); + }; + + plugin.onrequest.apply(null, [{}, {}, onrequest_cb]); + + }); +}); + diff --git a/test/quota-test.js b/test/quota-test.js new file mode 100644 index 0000000..8f23df1 --- /dev/null +++ b/test/quota-test.js @@ -0,0 +1,93 @@ +const quota = require('../quota/index'); +const assert = require('assert'); + +var exampleConfig = { + EdgeMicroTestProduct: { + allow: '3', + interval: '1', + timeUnit: 'minute', + bufferSize: 10000, + uri: 'https://edgemicroservices-us-east-1.apigee.net/edgemicro/quotas/organization/ws-poc3/environment/test', + key: 'b7b69b6bd79e778782af9a653ae9c4d91e65440d8acbc7e969437a8a8dc13612', + secret: 'c273ec588e22f29f3165fda450fee27f2c0703a08904ebecdbf379b5ac71090a' + } +} + +describe('quota plugin', () => { + var plugin = null; + + beforeEach(() => { + var logger = {}; + var stats = {}; + + plugin = quota.init.apply(null, [exampleConfig, logger, stats]); + + }); + + it('exposes an onrequest handler', () => { + assert.ok(plugin.onrequest); + }); + + it('will quota limit after 3 API calls', (done) => { + var count = 0; + var onrequest_cb = (err) => { + count++; + if(count == 4) { + assert.equal(count, 4); + assert.equal(err.message, 'exceeded quota'); + done(); + } + }; + + var req = { + token: { + application_name: '0e7762f4-ea67-4cc1-ae4a-21598c35b18f', + api_product_list: ['EdgeMicroTestProduct'] + } + } + + var res = { + headers: {}, + setHeader: (key, val) => { + res.headers[key] = val; + } + } + + plugin.onrequest.apply(null, [req, res, onrequest_cb]); + plugin.onrequest.apply(null, [req, res, onrequest_cb]); + plugin.onrequest.apply(null, [req, res, onrequest_cb]); + plugin.onrequest.apply(null, [req, res, onrequest_cb]); + }); + + it('will not quota limit before 3 API calls', (done) => { + var count = 0; + var onrequest_cb = (err) => { + count++; + if(count == 3) { + assert.equal(count, 3); + assert.ok(!(err instanceof Error)); + done(); + } + }; + + var req = { + token: { + application_name: '0e7762f4-ea67-4cc1-ae4a-21598c35b18f', + api_product_list: ['EdgeMicroTestProduct'] + } + } + + var res = { + headers: {}, + setHeader: (key, val) => { + res.headers[key] = val; + } + } + + plugin.onrequest.apply(null, [req, res, onrequest_cb]); + plugin.onrequest.apply(null, [req, res, onrequest_cb]); + plugin.onrequest.apply(null, [req, res, onrequest_cb]); + }); +}); + + diff --git a/test/spike-arrest-test.js b/test/spike-arrest-test.js new file mode 100644 index 0000000..409eb77 --- /dev/null +++ b/test/spike-arrest-test.js @@ -0,0 +1,48 @@ +const spikeArrest = require('../spikearrest/index'); +const assert = require('assert'); + +describe('spike arrest plugin', () => { + var plugin = null; + + beforeEach(() => { + var config = { + timeUnit: 'minute', + bufferSize: 0, + allow: 1 + }; + var logger = {}; + var stats = {}; + + plugin = spikeArrest.init.apply(null, [config, logger, stats]); + }); + + it('exposes an onrequest handler', () => { + assert.ok(plugin.onrequest); + }); + + it('will accept a request', (done) => { + var onrequest_cb = () => { + done(); + }; + + var req = {}; + var res = {}; + plugin.onrequest.apply(null, [req, res, onrequest_cb]); + }); + + it('will reject a requests that come in too fast', (done) => { + var onrequest_cb = () => { + }; + + var onrequest_cb_second = (req, res, next) => { + assert.ok(req instanceof Error); + assert.equal(req.message, 'SpikeArrest engaged'); + done(); + }; + + var req = {}; + var res = {}; + plugin.onrequest.apply(null, [req, res, onrequest_cb]); + plugin.onrequest.apply(null, [req, res, onrequest_cb_second]); + }); +}); From 0f9d19417d7dad59f1fd713c51b25e2682bd3a58 Mon Sep 17 00:00:00 2001 From: Matthew Dobson Date: Mon, 28 Nov 2016 07:48:59 -0500 Subject: [PATCH 4/5] Deleting old cache plugin test. Updating quota memory to get rid of logging. --- quota-memory/index.js | 4 ---- test/cache-test.js | 28 ---------------------------- 2 files changed, 32 deletions(-) delete mode 100644 test/cache-test.js diff --git a/quota-memory/index.js b/quota-memory/index.js index fb4ce97..337bf6e 100644 --- a/quota-memory/index.js +++ b/quota-memory/index.js @@ -5,9 +5,6 @@ var Quota = require('volos-quota-memory'); var debug = require('debug')('gateway:quota'); module.exports.init = function(config, logger, stats) { - console.log('CONFIG START'); - console.log(config); - console.log('CONFIG END'); var quotas = {}; // productName -> connectMiddleware var options = { @@ -17,7 +14,6 @@ module.exports.init = function(config, logger, stats) { Object.keys(config).forEach(function(productName) { var product = config[productName]; if (!product.uri && !product.key && !product.secret && !product.allow && !product.interval) { - console.log('Not enough info to configure quota'); return; // skip non-quota config } diff --git a/test/cache-test.js b/test/cache-test.js deleted file mode 100644 index 1662e08..0000000 --- a/test/cache-test.js +++ /dev/null @@ -1,28 +0,0 @@ -const cache = require('../cache/index'); -const assert = require('assert'); - -describe('cache plugin', () => { - var plugin = null; - - beforeEach(() => { - var config = {}; - var logger = {}; - var stats = {}; - - plugin = cache.init.apply(null, [config, logger, stats]); - }); - - it('exposes an onrequest handler', () => { - assert.ok(plugin.onrequest); - }); - - it('will call next if there is no token attached to the request object', (done) => { - const onrequest_cb = () => { - done(); - }; - - plugin.onrequest.apply(null, [{}, {}, onrequest_cb]); - - }); -}); - From cbb6d27fc212f7704aae41ff94a68ae1e11c409c Mon Sep 17 00:00:00 2001 From: Matthew Dobson Date: Fri, 2 Dec 2016 08:21:49 -0500 Subject: [PATCH 5/5] Updates to git ignore, and quota test to use env variables. --- .gitignore | 3 ++- test/quota-test.js | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 3c0ac2f..23d4050 100644 --- a/.gitignore +++ b/.gitignore @@ -34,4 +34,5 @@ node_modules .vscode .idea -.DS_Store \ No newline at end of file +.DS_Store +env.sh diff --git a/test/quota-test.js b/test/quota-test.js index 8f23df1..92a7beb 100644 --- a/test/quota-test.js +++ b/test/quota-test.js @@ -3,13 +3,13 @@ const assert = require('assert'); var exampleConfig = { EdgeMicroTestProduct: { - allow: '3', - interval: '1', - timeUnit: 'minute', - bufferSize: 10000, - uri: 'https://edgemicroservices-us-east-1.apigee.net/edgemicro/quotas/organization/ws-poc3/environment/test', - key: 'b7b69b6bd79e778782af9a653ae9c4d91e65440d8acbc7e969437a8a8dc13612', - secret: 'c273ec588e22f29f3165fda450fee27f2c0703a08904ebecdbf379b5ac71090a' + allow: process.env.QUOTA_ALLOW, + interval: process.env.QUOTA_INTERVAL, + timeUnit: process.env.QUOTA_TIMEUNIT, + bufferSize: process.env.QUOTA_BUFFERSIZE, + uri: process.env.QUOTA_URI, + key: process.env.QUOTA_KEY, + secret: process.env.QUOTA_SECRET } }