Thursday, June 7, 2007

Grinder

The Grinder is a Java load-testing framework. It is freely available under the BSD-style open source license.

The Grinder makes it easy to create the activities of a test script in many processes across many machines, using a graphical console application. Test scripts make use of client code embodied in Java plug-ins. Most users of The Grinder do not write plug-ins themselves, instead they use one of the supplied plug-ins. The Grinder comes with a mature plug-in for testing HTTP services, as well as a tool which allows HTTP scripts to be automatically recorded. The Grinder 3.0 which I used is still in the beta version. It uses a scripting language called Jython.

How Do One Start Grinder.

  1. Create a grinder.properties file. This file specifies general control information (how the worker processes should contact the console, how many worker processes to use, ..), as well as the name of the Jython script that will be used to run the tests.
  2. Set your CLASSPATH to include the grinder.jar file which can be found in the lib directory.
  3. Start the console on one of the test machines:
   java net.grinder.Console
  1. For each test machine, do steps 1. and 2. and start an agent process:
    java net.grinder.Grinder

You can also specify an explicit properties file as the first argument. For example:

java net.grinder.Grinder myproperties

Working of Grinder

Now coming on to the working of Grinder.

The framework is comprised of three types of process (or program). Worker processes, agent processes, and the console. The responsibilities of each of the process types are:

  • Worker processes
    • Interpret Jython test scripts and performs tests using a number of worker threads
  • Agent processes
    • Manage worker processes
  • The console
    • Coordinates the other processes
    • Collates and displays statistics

As The Grinder is written in Java, each of these processes is a Java Virtual Machine (JVM).

For heavy duty testing, you start an agent process on each of several client machines. The worker processes they launch can be controlled and monitored using the console. One can run more than one agents from a single machine too.

Going on to working an example.

Jython is java adapted version of Python.

Writing Script:

Scripts must conform to a few conventions in order to work with The Grinder framework.

Scripts must define a class called TestRunner

When a worker process starts up it runs the test script once. The test script must define a class called TestRunner. The Grinder engine then creates an instance of TestRunner for each worker thread. A thread's TestRunner instance can be used to store information specific to that thread.

The TestRunner instance must be callable

A Jython object is callable if it defines a __call__ method. Each worker thread performs a number of runs of the test script, as configured by the property grinder.runs.

The test script can access services through the grinder object

The engine makes an object called grinder available for the script to import. It can also be imported by any modules that the script calls. This is an instance of the GrinderScriptContext class and provides access to context information (such as the worker thread ID) and services (such as logging and statistics).

An Example

This is an example of a script that conforms to the rules above. It doesn't do very much - every run will log Hello World to the output log.

from net.grinder.script.Grinder import grinder
 
# An instance of this class is created for every thread.
class TestRunner:
    # This method is called for every run.
    def __call__(self):
        # Per thread scripting goes here.
        grinder.logger.output("Hello World")

This is a simple script that says to write “Hello World” in the log file, everytime the suite is called.

Each worker process writes logging information to a file called out-host-n.log, where host is the machine host name and n is the worker process number. Errors are written to error-host-n.log. If no errors occur, an error file will not be created.

Although our simple test script can be used with The Grinder framework and can easily be started in many times in many worker processes on many machines, it doesn't report any statistics. For this we need to create some tests.

A Test has a unique test number and description.

Let's add a Test to our script.

from net.grinder.script import Test
from net.grinder.script.Grinder import grinder
 
# Create a Test with a test number and a description.
test1 = Test(1, "Log method")
 
class TestRunner:
    def __call__(self):
        log("Hello World")
 
Here we have created a single Test with the
test number 1 and the description Log method.
Note how must import the Test class in a similar manner to Java.


1 comment:

Anonymous said...

Good for people to know.