Creating your own HTTP Chaos Monkey in 15 Minutes using Fiddler

You’ve written your awesome web app and you’ve been an awesome developer by handling those pesky intermittent connectivity issues that happen now and again when making HTTP requests. Typically you are doing this by catching the common HTTP Error Status Codes and performing retries.

When it comes to testing you will want to methodically test each of these cases to make sure your code responds as intended. This testing is usually fairly tedious and involves breakpoints and manipulating responses in flight. While I recommend you do this testing I also think there’s great value in continuously testing your app and the handling of these intermittent connectivity issues as you develop. For this we can make use of Fiddler and create our own simple Chaos Monkey that will randomly intercept HTTP calls and return various error status codes associated with these type of connectivity issues. This forces our error handling code to be exercised frequently as we are developing.

Fiddler is a pretty powerful tool for inspecting and manipulating HTTP traffic (read my Top 6 Fiddler tips for developers). To create our Chaos Monkey we are going to tap into the Custom Rules feature of Fiddler. You’ll find this under Rules | Customize Rules…

This will open up the ScriptEditor which looks a little scary and more than a tad dated.

Inside the class Handlers there’s a lot of commented out bits. Once the code starts you should see some lines that define RulesOptions (as shown below)

public static RulesOption("Hide 304s")
    BindPref("fiddlerscript.rules.Hide304s")
    var m_Hide304s: boolean = false;

    // Cause Fiddler to override the Accept-Language header with one of the defined values
    public static RulesOption("Request &Japanese Content")
    var m_Japanese: boolean = false;

    // Automatic Authentication
    public static RulesOption("&Automatically Authenticate")
    BindPref("fiddlerscript.rules.AutoAuth")
    var m_AutoAuth: boolean = false;

Just underneath those RulesOptions paste this code. It defines a rule of our own. These rules in the Fiddler world correspond to menu options and we are creating our own menu that will allow us to turn on the chaos handler and choose just how much chaos we want to cause!

// Cam's Chaos Monkey - Menu Setting	
RulesString("🐵 Cams Chaos Monkey", true) 
BindPref("fiddlerscript.ephemeral.sCamsChaos")
RulesStringValue(0,"25% Chaos 🐵", "25")
RulesStringValue(1,"50% Chaos 🐵🐵","50")
RulesStringValue(2,"75% Chaos 🐵🐵🐵","75")
RulesStringValue(3,"100% Chaos 🐵🐵🐵🐵","100")
public static var sCamsChaos: String = null;

If you save the script and close the window to return to Fiddler you will immediately see our new menu option.

Now return to Rules | Customize Rules… to bring the ScriptEditor back up. This time scroll down a fair way until you find the OnBeforeResponse method. It should look similar to this:

 static function OnBeforeResponse(oSession: Session) {
        if (m_Hide304s && oSession.responseCode == 304) {
            oSession["ui-hide"] = "true";
        }
}

This method is the code that runs everytime Fiddler sees a response come in from a HTTP request. This is our opportunity to grab it and change the status code to an error. We will look at that menu item we just created and determine what percentage of responses we want to modify and also randomly return a series of different error codes. Here’s the full method with the code that will do it for us.

 static function OnBeforeResponse(oSession: Session) {
        if (m_Hide304s && oSession.responseCode == 304) {
            oSession["ui-hide"] = "true";
        }
		
		/*
		* Cam's Chaos Monkey
		*/
		if (null != sCamsChaos && oSession.responseCode == 200) {
			var chanceOfChaos = parseInt(sCamsChaos);
			var intRandNumberUpTo100 = Math.round((Math.random() * 100));
			if(intRandNumberUpTo100 <= chanceOfChaos)
			{
				// Time for choas
				// Pick a random error code to throw
				var intRandomError = Math.round((Math.random() * 4));
				switch(intRandomError){
					case 1:
						oSession.responseCode = 404;
						oSession.oResponse.headers.HTTPResponseCode = 429;
						oSession.oResponse.headers.HTTPResponseStatus = "429 Too Many Requests";
						break;
					case 2:
						oSession.responseCode = 502;
						oSession.oResponse.headers.HTTPResponseCode = 502;
						oSession.oResponse.headers.HTTPResponseStatus = "502 Bad Gateway";
						break;
					case 3:
						oSession.responseCode = 503;
						oSession.oResponse.headers.HTTPResponseCode = 503;
						oSession.oResponse.headers.HTTPResponseStatus = "503 Service Unavailable";
						break;
					case 4:
						oSession.responseCode = 504;
						oSession.oResponse.headers.HTTPResponseCode = 504;
						oSession.oResponse.headers.HTTPResponseStatus = "504 Gateway Timeout";
						break;
				}
			}		
		}
    }

That’s all there is to it. Save those changes and return to Fiddler. Now you can just select how much chaos you want the monkey to create and you will hopefully start to see your retry code kicking in and issuing those retry calls.

If you set the chaos level at 25% or 50% your app should still remain useable even though a good chunk of the calls are failing. Its a good feeling to know you’ve been developing something all day long, half your HTTP traffic is failing and you don’t even notice it from a UI perspective. That gives you a bit of confidence that it will be ok out in the wild 🙂

Tip: The Chaos Monkey only applies to traffic that is captured in the Fiddler window (which is everything by default). You can make use of the filter tab in Fiddler to be much more specific so that the Chaos Monkey only works on HTTP requests to a particular service or URL for example.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Create a website or blog at WordPress.com

Up ↑

%d bloggers like this: