Andrew Rea

Independent Technical Architect, Software Engineer and Consultant

Introducing Enanos a HTTP server for analyzing applications with HTTP dependencies

Date: Mar 19th 2015

What is it?

Enanos is a HTTP server with several endpoints that can be used to substitute the actual http service dependencies of a system. Its purpose is to simulate unstable dependencies so that the effects on the target system can be observed. Of course it is easy to write such endpoints in any language which you use but Enanos simply groups these together with a small amount of configuration in order to be a convenient, simple and useful tool.

Where to get it?

All on github at https://github.com/REAANDREW/enanos/releases/latest

Currently the supported platforms are Windows, Linux and MAC both 32 and 64bit. You can of course cross compile it to more platforms as it is built in golang and so that kind of thing is really simple to do.

Why has it even been built?

There are a couple reasons for the creation of Enanos which are:

  • I wanted a pet project which I could use to learn go lang but with a practical result at the end
  • I work with a LOT of legacy systems and at the beginning of any work I always like to evaluate the system and one of those tasks (assuming it has HTTP dependencies) is to simulate unstable HTTP dependencies and then analyze the glowing parts of the app once the smoke sub-sides. The definition of legacy in this context and the profile of the applications are those with little to no test coverage.

What does it do?

Enanos is comprised of 8 endpoints which include success, server_error, content_size, wait, redirect, client_error, dead_or_alive, defined. Each endpoint has a specific and sometimes configurable behaviour. A description of each of the endpoints is below including any related configuration which affects the response.

/success

This endpoint returns 200 every single time you hit it. If you have configured the content flag this will be the content which is returned. Otherwise the default content "hello world" is returned.

./enanos --content booboo
 >curl http://localhost:8000/success
 >booboo
 
./enanos
 >curl http://localhost:8000/success
 >hello world
 

/server_error

This endpoint returns a random response code in the set of 500, 501, 502, 503, 504, 505.

/content_size

This endpoint returns a 200 status code but also returns a response body of dash characters. A random size between the min-size and max-size will be returned if the random-size flag is set otherwise only the max-size will be applied.

/wait

This endpoint returns a 200 status code but also waits for a specified time before it returns. A random wait between the min-sleep and max-sleep will occur if the random-sleep flag is set otherwise only the max-sleep will be applied.

/redirect

This endpoint returns a random response code in the set of 300, 301, 302, 303, 304, 305, 307. Unless a location header is sent then the location of the redirection will be back to the same endpoint being redirect causing a redirection loop if the client should follow it.

/client_error

This endpoint returns a random response code in the set of 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 429.

/dead_or_alive

This endpoint when called will temporarily close the listening Enanos server. After 5 seconds the server will come back and be listening again. All Enanos endpoints will be in-accessible when this endpoint is called and will only be restored after the time elapses.

/defined

This endpoint will literally just set the response code to the one which is defined in the code query string value.

Configuration

The other parts of the configuration which are not mentioned above are self explanatory like the host and port which are used for the Enanos server. The -H (header) field can be used multiple times and each one will be appended to the responses headers for all of the endpoints, exluding dead_or_alive. Setting the verbose flag will write information about each request to STDOUT. The information written to STDOUT includes:

  • response time
  • http status code
  • request path
Flags:
   --help               Show help.
   --verbose            Enable verbose mode.
   -p, --port=8000      the port to host the server on
   --host="0.0.0.0"     this host for enanos to bind to
   --min-sleep="1s"     the minimum sleep time for the wait endpoint e.g. 5ms, 5s, 5m etc...
   --max-sleep="60s"    the maximum sleep time for the wait endpoint e.g. 5ms, 5s, 5m etc...
   --random-sleep       whether to sleep a random time between min and max or just the max
   --min-size="10KB"    the minimum size of response body for the content_size endpoint e.g. 5B, 5KB, 5MB etc...
   --max-size="100KB"   the maximum size of response body for the content_size endpoint e.g. 5B, 5KB, 5MB etc...
   --random-size        whether to return a random sized payload between min and max or just max
   --content="hello world"  
                        the content to return for OK responses
   -H, --header=HEADER  response headers to be returned. Key:Value
   --version            Show application version.
 

Examples

A simple example of using the /success endpoint setting some custom content and adding a couple of response headers.

./enanos --content '<xml value="something"></xml>' -H 'Content-type: application/xml' -H 'Age: 12'
 > curl -i http://localhost:8000/success
 HTTP/1.1 200 OK
 Age: 12
 Content-Type: application/xml
 Date: Sat, 21 Mar 2015 18:16:52 GMT
 Content-Length: 29
 
 <xml value="something"></xml>
 

Setting the max-sleep parameter but not setting the random-sleep option

./enanos --max-sleep 5s --content '<xml value="something"></xml>' -H 'Content-type: application/xml'
 >time curl -i http://localhost:8000/wait
 HTTP/1.1 200 OK
 Content-Type: application/xml
 Date: Sat, 21 Mar 2015 18:22:46 GMT
 Content-Length: 29
 
 <xml value="something"></xml>
 
 real    0m5.012s
 user    0m0.005s
 sys     0m0.003s
 

Calling the /dead_or_alive endpoint and showing the effect by calling the /success a couple of times with the second succeeding as the dead time has elapsed.

./enanos --max-sleep 5s --content '{"msg":"hello world"}' -H 'Content-type: application/json'
 >curl -i http://localhost:8000/dead_or_alive
 HTTP/1.1 200 OK
 Date: Sat, 21 Mar 2015 19:03:04 GMT
 Content-Length: 0
 Content-Type: text/plain; charset=utf-8
 
 >curl -i http://localhost:8000/success
 curl: (7) Failed to connect to localhost port 8000: Connection refused
 
 >curl -i http://localhost:8000/success
 HTTP/1.1 200 OK
 Content-Type: application/json
 Date: Sat, 21 Mar 2015 19:03:10 GMT
 Content-Length: 21
 
 {"msg":"hello world"}
 

Why use Object.freeze and why not to use Object.freeze

Date: Mar 15th 2015

This is an update to an original post I wrote Why use Object.freeze.

Two things which need to be made clear with the usage of Object.freeze are:

  1. Using Object.freeze can have a considerable impact on the execution time of your application (which will be demonstrated in this update)
  2. It only freezes the top level properties of the object graph - which is not immediately obvious when you read some of the documentation out there.

The Object.freeze() method freezes an object: that is, prevents new properties from being added to it; prevents existing properties from being removed; and prevents existing properties, or their enumerability, configurability, or writability, from being changed. In essence the object is made effectively immutable. The method returns the object being frozen.

source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze

Execution time

Simple Object

The following examples use a simple iteration to create an object. The first one does nothing special and simply creates and returns an object.

function createObject() {
     return {
         a: 1,
         b: 2
     };
 }
 
 for (var i = 0; i < 1000000; i++) {
     createObject();
 }
 

The timings are:

real    0m0.030s
 user    0m0.018s
 sys     0m0.010s
 

Frozen Object

If the above is altered so that it freezes the object, the difference in execution time is enormous.

function createFrozenObject() {
     return Object.freeze({
         a: 1,
         b: 2
     });
 }
 
 for (var i = 0; i < 1000000; i++) {
     createFrozenObject();
 }
 

The timings are:

real    0m2.971s
 user    0m1.495s
 sys     0m1.290s
 

Deep Freeze Object

To address point two at the start of this update and also to show a further reduction in performance, this example will use a function called deepFreeze from the Mozilla Developer Network.

Part way down in the documentation it does state this behaviour with Object.freeze.

Values cannot be changed for data properties. Accessor properties (getters and setters) work the same (and still give the illusion that you are changing the value). Note that values that are objects can still be modified, unless they are also frozen.

source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze

function deepFreeze(o) {
     var prop, propKey;
     Object.freeze(o); // First freeze the object.
     for (propKey in o) {
         prop = o[propKey];
         if (!o.hasOwnProperty(propKey) || !(typeof prop === 'object') || Object.isFrozen(prop)) {
             continue;
         }
 
         deepFreeze(prop); // Recursively call deepFreeze.
     }
     return o;
 }
 
 function createDeepFreezeObject() {
     var obj = {
         a: 1,
         b: 2
     };
     return deepFreeze(obj); 
 }
 
 for (var i = 0; i < 1000000; i++) {
     createDeepFreezeObject();
 }
 

The timings are:

real    0m3.715s
 user    0m1.863s
 sys     0m1.634s
 

The only modification I have made to the original deepFreeze code is that it returns the modified object. Grouping together the results from above clearly show the impact on execution time:

  • SimpleObject: 30ms
  • Object.freeze: 2900ms
  • deepFreeze: 3700ms

What does the above tell me? Well if I am using Object.freeze or deepFreeze and the objects which I am freezing have a short lifetime and their creation will be frequent, then I will incur a performance impact. If I am not creating objects frequently, inside of a loop and I do value immutability, then honestly I would still use the deepFreeze method. Like anything with Software Development, there has to be a balance and a pragmatic view to things. Different languages bring different considerations to common topics. For example statically typed languages enable you to implement immutability a lot more efficiently and naturally than JavaScript currently does.

Promise Libraries

The following url, https://github.com/cujojs/promise-perf-tests, shows performance tests of different promise libraries and provides information on the different libraries which do and do not use Object.freeze. This repo is no longer maintained at time of writing this.

ECMAScript 6

The draft specification of ECMAcript does contain Object.freeze. http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.freeze

Why use Object.freeze

Date: Apr 17th 2014

March 15 2015: An update to this post has been written: Why use Object.freeze and why not to use Object.freeze.

I like JavaScript but I also like Encapsulation and Immutability.

There is lots of information on the internet, in books, whitepapers etc... about the benefits of Encapsulation and Immutability so I will not go through these in this post. I simply want to show the facts of what you get when you use the Object.freeze method, and also conversely what are the effects when you do not use it.

When you are working in a development team with a size greater than 1, you want to ensure that the development experience is efficient and consistent from the team and not just from your own work. You also expect the same back from the members of your team. Working with a dynamic language can introduce problems such as type/value betrayal. If you set a value of 1 and somewhere along the codebase this value changes to "1" then you are undoubtably going to get errors and side effects which you ultimately have not accounted for.

The first example shows a simple object which exposes its inner property. The test shows that we are free to modify the property directly.

describe('without encapsulation', function() {
     var OpenPerson = function(age) {
         return {
             age: age
         };
     };
 
     it('state can be changed', function(done) {
         var p = new OpenPerson(0);
         p.age++;
         p.age.should.eql(1);
         done();
     });
 });
 

The next example shows how we can achieve encapsulation without using Object.freeze. Things to notice here is that it requires you to expose the property via a function. This does prevent the value from being changed but it does not guard from the function being deleted.

describe('achieving encapsulation without Object freeze', function() {
     var FunctionClosedPerson = function(age) {
         return {
             age: function() {
                 return age;
             }
         };
     };
 
     it('results in the use of function based declaration', function(done) {
         var p = new FunctionClosedPerson(1);
         var age = p.age();
         age++;
         age.should.eql(2);
         p.age().should.eql(1);
         done();
     });
 
     it('still allows the deletion of the member', function(done) {
         var p = new FunctionClosedPerson(1);
         delete p.age;
         should(p.age).eql(undefined);
         done();
     });
 });
 

The final example is using Object.freeze. Here we see that we maintain encapsulation, we maintain property based access and also we know that our objects will stay the way we left them. The errors which I assert on here show that the property is now recognized formally as readonly and is unable to be deleted.

describe('achieving encapsulation with Object freeze', function() {
     var FrozenPerson = function(age) {
         return Object.freeze({
             age: age
         });
     };
 
     it('allows for property based access as opposed to function based access', function(done) {
         var p = new FrozenPerson(1);
         p.age.should.eql(1);
         done();
     });
 
     it('does not allow modification of any property', function(done) {
         var p = new FrozenPerson(1);
         should(function() {
             p.age++;
         }).
         throw (/Cannot assign to read only property 'age'/);
         done();
     });
 
     it('does not allow removal of members of a frozen object', function(done) {
         var p = new FrozenPerson(1);
         should(function() {
             delete p.age;
         }).
         throw (/Cannot delete property 'age'/);
         done();
     });
 });
 

When working on a node.js project, the above gives you great benefits in the fact that this is one less thing which you need to test for i.e. "Is my property still there?" and "Is the type of my property what I expect?". I say node.js and not JavaScript as you could be developing JavaScript in the Browser which means that Object.freeze support will differ. Doing the JavaScript development on the node.js platform alleviates this issue, as is the target and the context for this POST. Saying that I would still aim to do this in as many places as I can even in Browser based development, providing sufficient handling for those browsers which do not support this.

An alternative to this would be to lean on your test suites and extend to assert on property existence and type (as much as possible in JavaScript). I would expect both the above and rigorous testing, only not testing for the things which I now have nailed using the Object.freeze method.

I would still recommend that careful thought is given before any decision is made to use getters and setters. It is much more beneficial to identify and model behaviours and hide as much information as is possible inline with "the principle of least knowledge."

Encapsulation with JavaScript

Date: Apr 6th 2014

All of the example make use of the Revealing Module Pattern and the Object.freeze method in JavaScript. All of the examples are using mocha and should libraries to implement the tests and the assertions. Whilst working on a recent project where I decided to use node.js, I wanted to achieve a much higher level of encapsulation that you see in in the majority of JavaScript code. This is nothing new, I just wanted to collect together a set of examples which I can use to demonstrate how we can do encapsulation and achieve immutability with JavaScript. I have included an example of method chaining also which was a nice surprise to me when I figured out how it can be done.

Instantiation of an object

If you omit the surrounding brackets of the classic Revealing Module Pattern implementation you can instantiate your objects just as you could if you were using the prototype style.

Implementation

    var Person = function() {
 
     }
 

Test Code

    it('can be modelled:', function() {
         var bob = new Person();
         should(bob).not.eql(null);
     });
 

Support instance methods

This is just the same as with the classic Revealing Module Pattern only here we are using the Object.freeze method on the object being returned. This means that to extend this object with further behaviour you would have to use composition, but this is not a bad thing. For this example the Person object will get two methods, promote and demote. Another method is also added called reportRank so we can use a Tell Don`t Ask approach to asserting on the Person object (this is also very closely related to the Visitor Pattern)

Implementation

var Person = function () {
 
     var rank = 0;
 
     function promote() {
         rank++;
         return funcs;
     }
 
     function demote() {
         rank--;
         return funcs;
     }
 
     function reportRank(writer) {
         writer.write(rank);
     }
 
     var funcs = Object.freeze({
         promote: promote,
         demote: demote,
         reportRank: reportRank
     });
 
     return funcs;
 }
 

Test Code

it('can be promoted', function(done) {
     var bob = new Person();
     bob.promote();
     var assertWriter = {
         write : function(obj){
             obj.should.eql(1);
             done();
         }
     };  
     bob.reportRank(assertWriter);
 });
 

Support method chaining with an instance

One of the handy implementatioasn when instantiating objects is when you return the this keyword in the instance methods. This allows you to then call another method on the instance one after the other. To achieve this, the methods which are returned by the main function should also be returned by the instance methods. This then allows the implementations to do the method chaining.

Implementation

    var Person = function() {
 
         var rank = 0;
 
         function promote() {
             rank++;
             return funcs;
         }
 
         function demote() {
             rank--;
             return funcs;
         }
 
         function reportRank(writer) {
             writer.write(rank);
         }
 
         var funcs = Object.freeze({
             promote: promote,
             demote: demote,
             reportRank: reportRank
         });
 
         return funcs;
     };
 

Test Code

    it('can be demoted', function(done) {
         var bob = new Person();
         bob.promote().promote().demote();
         var assertWriter = {
             write: function(obj) {
                 obj.should.eql(1);
                 done();
             }
         };
         bob.reportRank(assertWriter);
     });
 

Composition

The following example shows composition of objects where the Person object is now wrapped with an object which reports a different medal depending on the rank. The important thing here is to ensure that any methods exposed by the object being wrapped, need to be exposed by the object doing the wrapping. Some helper extension could easily be made to reduce the required coding here and enable only methods which need to be changed to be re-declared.

Implementation

var personWithMedals = function(person) {
 
     var medals = {
         0: 'none',
         3: 'bronze',
         4: 'silver',
         5: 'gold'
     };
     var medal = medals[0];
 
     var rankWriter = {
         write : assignMedal
     }
 
     function reportMedals(writer) {
         writer.write(medal);
     }
 
     function assignMedal(rank) {
         if (medals[rank] === undefined) {
             medal = medals[3];
         } else {
             medal = medals[rank];
         }
     }
 
     function promote() {
         person.promote();
         person.reportRank(rankWriter);
         return funcs;
     }
 
     function demote() {
         person.demote();
         person.reportRank(rankWriter);
         return funcs;
     }
 
     var funcs = Object.freeze({
         reportMedals: reportMedals,
         promote: promote,
         demote: demote,
         reportRank: person.reportRank
     });
 
     return funcs;
 }
 

Test Code

it('gets no medals when they have no promotions', function(done) {
     var bob = new Person();
     bob = new PersonWithMedals(bob);
     assertMedal(bob, 'none', done);
 });
 
 it('gets a bronze medal with three promotions', function(done) {
     var bob = new Person();
     bob = new PersonWithMedals(bob);
     bob.promote().promote().promote();
     assertMedal(bob, 'bronze', done);
 });
 
 it('gets a silver medal with four promotions', function(done) {
     var bob = new Person();
     bob = new PersonWithMedals(bob);
     bob.promote().promote().promote().promote();
     assertMedal(bob, 'silver', done);
 });
 
 it('gets a gold medal with five promotions', function(done) {
     var bob = new Person();
     bob = new PersonWithMedals(bob);
     bob.promote().promote().promote().promote().promote();
     assertMedal(bob, 'gold', done);
 });
 
 function assertMedal(person, medal, callback) {
     var medalWriter = {
         write: function(obj) {
             obj.should.eql(medal);
             callback();
         }
     };
     person.reportMedals(medalWriter);
 }
 

Exporting your objects in node.js

The above objects were exported in the example project with the following code. The definitions were made in camelCase and exported in pascal case.

Implementation

    module.exports = {
         Person: person,
         PersonWithMedals: personWithMedals
     };
 

Compatible with super strict jshint profile

Please see the .jshintrc to see the profile of JSHint.