From 913b00232dd1b8d9b1f70d41df72c2a8aed7b9a4 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