Thursday, March 15, 2012

Gatling-Tool Plugin for Play 2.0

Goal

This post will be a kind of write-up of what I'm trying to do now. And for what I already achieved some tasks.

Since I'll soon start products in my company that will be based on technologies like Scala, Play 2.0, Neo4J, MongoDB, Heroku and misc, and that I'm a bit control freak; I wanted to be sure that what I'll build will mach the requirements in terms of capacity.

This is where Gatling-Tool comes in the equation, this is a very powerful (and scala based) stress testing tool, which the name recall.

We're about to have some words on it, but first let me tell you that a GitHub ready to be fork is available with my first step into a gatling plugin, find it here.

Gatling Tool

Gatling Tool is a cute, smart and intuitive stress testing tool for web application, which a neat DSL for http request and asserts.

The DSL written in scala, and following the good conventions for it will aim anybody to be able to write stress tools. In a way that even non-programmer peoples with a basic understanding will be able to do basic stress tests with a good learning curve.

It's integration with browsers (Firefox, through a proxy) ease much more the work because you'll be able to register like macros (or like badboy does) your scenario to be repeated again and again. This is what is called the recorder.

Scenarios could be written with a custom external DSL, but they're also available as regular scala code (internal DSL) and there is where the coupling with Play 2.0 scala should pay.

Integration with Play2.0

Akka 2.0

Fact: since the RC-5, Play 2.0 comes with the Akka 2.0 support.
Fact: Gatling being it-self based on Akka (and they're right for that) but on a previous version for the stable version (logical because Akka 2.0 is pretty new).

So an integration must go through an update of the Gatling-Tool to the same version of Akka 2.0 in order to be able to use them correctly using the same project (testing phase, but still).

That's why I decided to fork the Gatling-Tool on GitHub (aaah the great world of open source), in order to switch the support of Akka from their 1.x to 2.0.

Even if it is true that I did it roughly (at first), it remains that it works and is the two needed projects for the following are:
  • https://github.com/andypetrella/gatling
  • https://github.com/andypetrella/gatling-highcharts
So fork, clone them and build them locally using maven using the classical mvn clean install.

You'll have a brand new version of gatling 1.1.0-SNAPSHOT.

NOTE: I had some difficult choices when doing the migration, some are breaking the runtime behavior (a bit) and I'll have to discuss them further with the Gatling team. I've already been contacted by St├ęphane Landelle who told me that we was interested by the work since it was planned the 1.2 release.
So don't be afraid, the official release will match the needs soon. (But ping me if you want more info and help me.)

Typesafe Stack 2.0

I recommend you to install this brand new stack that integrates all stuffs that you'll need for scala development, including Play 2.0 project. 
Now, simply follows this link for further steps, and then create a play-scala project.

Sbt

Since Play 2.0 is using Sbt for building its project, and the custom gatling library we built is in our .m2 repo, we have first to add our local maven repo to the repositories list this way (updating your Build.scala):

Tada, now we have a Play 2.0 project having our custom gatling as dependency.

Plugin

Before going in further details with integrating Gatling as a Play 2.0 plugin, I'm gonna talk about an uncovered subject in Play 2.0 (or not easy to track); the Plugin feature.

Play 2.0 comes with a pretty easy simple Plugin integration, this through the specific file, in the conf folder, named play.plugins. This file is meant to contain one single line by defined plugin, shaped this way: {priority}:{plugin's class path}.

But what is a plugin finally, this is a classical class extending play.api.Plugin... simply. This Plugin trait only defines three methods which are:
  • onStart: this adds a hook when the application starts, helpful for initializing objects.
  • onStop: cleaning the fields.
  • enabled: helpful to disable the plugin in some specific cases.
Another point, that I have to highlight is that it seems that such Plugin's constructor must have an argument being the application it-self.

Test only

Hey wait gatling should be available in tests only ?! Right!
The first way to achieve this is the easies also, while implementing isEnabled, you can use the application (remember it is part of the constructor) which has a method isTest that should toggle the plugin.

The second way is to create a Specification that starts a FakeServer (since we'll stress the entire Play 2.0 flows) and give it a FakeApplication which is defined with the Plugins you wish. 1000 words replaced by one Gist:

Gatling integration

Now you're wondering what the heck is that Gatling Plugin class, don't you?
Gatling Plugin
The Gatling plugin class, located in my repo under the test/gatling folder, is extending the play.Plugin class (which defines dummy implementation of the three methods), this way I can concentrate on the only method I need, onStart

Actually I need some initialization in order to use gatling, it needs some folder to be defined, including the one interesting use the more: results.

So, the Gatling#onStart method is creating ephemeres folders under the target directory (that can be cleaned) and also the needed Gatling configuration file. And that's it.

We can now stress test our app.

How?
Gatling is able to understand Scala written scenarios, those Scala script have only one constraint: being an instance of com.excilys.ebi.gatling.core.scenario.configuration.Simulation.

This trait is actually a Function0 and thus defines only one helpful method which is apply(). The latter method is the container for building the stress test that we want to execute.

What is very common now is that you can write Gatling scenarios using the Scala Type System being checked in your favorite IDE, and they will be compiled by Sbt it self when requested (and hot swapped ^^). Where the classical Gatling workflow is to compile them on the fly, using their internal routines.

Run 'em
Having simulations written (example here), you can now ask Gatling to run them by creating a gatling runner instance on them. I won't go into deep details because it is not the purpose here, but here is how you can do.

See 'em in action
That's the easiest part, entering the play environment using sbt in console, you can launch the tests by typing test.

What'll be done is:
  1. enter the specification
  2. create the fake application
  3. load the additional plugin
  4. create the gatling folder and conf
  5. configure the gatling system
  6. create the fake server on 3333
  7. create the simulations
  8. run them
  9. generate reports on them (located in the target folder => look 'em in your browser and you'll see how they're cute)

Problems

There are problems for now when executing several tests, because streams are closed (while generating further reports), that comes from a choice that I've have to do and which is commented on github here. This is mainly related to a feature that is no more available in Akka 2.0 (for good reasons, I'd say).

To be continued

If you want to help me going further, don't hesitate to contact me on my mailbox, or comment this post or on twitter.

What I like to have in the future is :
  • clear Specification for Gatling (preventing the need to define each time the server and plugin)
  • website for enabling test one by one, or any, or...
  • redirecting to results reports
  • more
  • and more