From 69e5b2ac9a2d5e827e29164088c8fc6be673274a Mon Sep 17 00:00:00 2001 From: Evan Morikawa Date: Fri, 9 Oct 2015 09:37:56 -0700 Subject: [PATCH] Add ChaosMonkey to test misbehaving servers Summary: `ChaosMonkey.unleashOnAPI()` will by default cause all API requests to 500 `ChaosMonkey.unleashOnAPI(timeoutMonkey: true)` will cause all API requests to SOCKETTIMEOUT `ChaosMonkey.unleashOnAPI(numMonkeys: 10)` will cause the next 10 API requests to 500 `ChaosMonkey.unleashOnAPI(errorCode: 401, numMonkeys: 10)` will cause the next 10 API requests to 401. It must be manually invoked from the console on each window you want the Monkeys wrecking havok. It is available on the `window` object as well This was created to manually test our server failure cases. Test Plan: manual Reviewers: drew, bengotow Reviewed By: bengotow Differential Revision: https://phab.nylas.com/D2133 --- package.json | 1 + src/chaos-monkey.coffee | 52 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 src/chaos-monkey.coffee diff --git a/package.json b/package.json index 453dc01a1..a6554a7c3 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "vm-compatibility-layer": "0.1.0" }, "devDependencies": { + "nock": "^2", "grunt": "^0.4.5", "grunt-serve": "^0.1.6", "jasmine-react-helpers": "^0.2", diff --git a/src/chaos-monkey.coffee b/src/chaos-monkey.coffee new file mode 100644 index 000000000..0c55c5384 --- /dev/null +++ b/src/chaos-monkey.coffee @@ -0,0 +1,52 @@ +NylasAPI = require './flux/nylas-api' +nock = require 'nock' + +# We be wrecking havok in your code +class ChaosMonkey + @unleashOnAPI: ({errorCode, numMonkeys, makeTimeout}={}) -> + errorCode ?= 500 + numMonkeys ?= "all the monkeys" + makeTimeout ?= false + nGet = nock(NylasAPI.APIRoot) + nPut = nock(NylasAPI.APIRoot) + nPost = nock(NylasAPI.APIRoot) + + numTimes = 1 + if numMonkeys.toLowerCase() is "all the monkeys" + nGet = nGet.persist() + nPut = nPut.persist() + nPost = nPost.persist() + else if _.isNumber(numMonkeys) + numTimes = numMonkeys + + nGet = nGet.filteringPath (path) -> '/*' + .get('/*') + + nPut = nPut.filteringRequestBody (body) -> '*' + .filteringPath (path) -> '/*' + .put('/*', '*') + + nPost = nPost.filteringRequestBody (body) -> '*' + .filteringPath (path) -> '/*' + .post('/*', '*') + + [nGet, nPut, nPost] = [nGet, nPut, nPost].map (n) -> + n = n.times(numTimes) + if makeTimeout + return n.socketDelay(31000) + else + return n + + if makeTimeout + [nGet, nPut, nPost].forEach (n) -> n.reply(200, 'Timed out') + else + nGet.replyWithError({message:'Monkey GET error!', code: errorCode}) + nPut.replyWithError({message:'Monkey PUT error!', code: errorCode}) + nPost.replyWithError({message:'Monkey POST error!', code: errorCode}) + + @goHome: -> + nock.restore() + nock.cleanAll() + +window.ChaosMonkey = ChaosMonkey +module.exports = ChaosMonkey