Tag Archives: node.js

Executing Gatling tests from Node.js

So, I’ve been playing with Gatling quite a bit recently. It’s a really neat open source load testing tool.

Anyway, what I wanted to do was to have a remote instance that I could trigger a Gatling test on and then get the results back, all over http. Node.js seemed the obvious lightweight solution to do this in….

Now, how to trigger a Gatling test from Node.js. Well, there are a few complexities but generally it is not too bad.

Executing a Test

Gatling runs as a command line tool, so the first step is to use an NPM package called “sh”. This is a package that allows execution of commands and executes a callback on completion.

By default Gatling will run in an interactive mode, awaiting user response to determine the tests that should be run. Obviously this is not viable when running headless so we need to add some switches to the base command

-s class.classname [where class.classname is the class of the test you wish to run]
-sf path/to/script/folder [this can be avoided if scripts are stored in default Gatling directory]

Executing the Gating command with these two switches via the following line of node will successfully execute a test and execute the callback script on completion

var command = this.config.gatlingRoot + ' -sf ' + this.config.rootfolder + ' -s ' + this.config.testClass;
sh(command).result(function(){test.completeTest()});

Capturing the Results

Executing a test though is no use without being able to gather the results and this was slightly more of a challenge. Gatling creates a new folder for every test execution, by default this will be another folder within its standard results folder. The issue this created was that there was no way, as far as I could tell, of getting the details of that folder from the command line response.

What you can do however is to define the root folder for the results in the command line by adding the -rf switch.

-rf path/to/results/folder

Gatling however will still create a subfolder within that for every test run. This where NPM comes to the rescue again with the “fs” package which allow monitoring of a folder and raising of an event on any changes. Therefore you can create a folder specifically for the holding of your test results then execute a test and be confident that the next event on that folder will be the creation of the results folder. The fs callback includes the name of that folder.

function setupResultFolder(test){
var resultfolder = test.config.rootfolder + "results/"
fs.mkdirSync(resultfolder);
fs.watch(resultfolder, {
persistent: true
}, function(event, filename) {
test.setResultFile(filename);
});
return resultfolder;
}

Then to get to the results you can just access the relevant files within that folder. I was only interested in the raw results so I was looking at simulation.log.

Notifying of test completion

To finish off I just added a simple event that is raised when the test is complete

this.completeTest = function(){
this.complete = true;
this.emit("testComplete");
}

Complete code

The complete code comes in at <50 lines.

var fs = require('fs');
var sh = require('sh');
var events = require('events');
var eventEmitter = new events.EventEmitter();

var GattlingTest = function(id, config) {
events.EventEmitter.call(this); 

this.id = id;
this.complete = false;
this.resultfile = "";
this.resultfolder = "";
this.config = config; 

this.start = function(){
var test = this;
this.resultfolder = setupResultFolder(this);
var command = this.config.gatlingRoot + ' -sf ' + this.config.rootfolder + ' -s ' + this.config.testClass + ' -nr -rf '+ this.resultfolder;
console.log(command);
sh(command).result(function(){test.completeTest()});
}
this.setResultFile = function(resultfile){
console.log("resultfile for " + id + " set to " + resultfile);
this.resultfile=this.resultfolder + resultfile + config.resultFileName;
console.log(this.resultfile);
}
this.completeTest = function(){
console.log("complete");
this.complete = true;
this.emit("testComplete");
}
this.results = function(){
return fs.readFileSync(this.resultfile, "utf-8");
}
}

GattlingTest.prototype.__proto__ = events.EventEmitter.prototype;
module.exports = GattlingTest;

function setupResultFolder(test){
var resultfolder = test.config.rootfolder + "results/"
fs.mkdirSync(resultfolder);
console.log("Tracking ... " + resultfolder);
fs.watch(resultfolder, {
persistent: true
}, function(event, filename) {
console.log(event + " event occurred on " + filename);
test.setResultFile(filename);
});
return resultfolder;
} 

Leave a comment

Filed under Code