Load-Testing-101-eBook-CTA-1

Creating a New Load Generator in LoadUI

loadui-vertical-logo-med_In this post, I will quickly introduce LoadUI and how you can use it to load test your online APIs. I will show how, in certain cases, you’ll need something that LoadUI does not already do, and how you can create LoadUI components to do exactly what you want using your basic Groovy skills… and I hope to show how fun it can be to do that in the process.”

Introduction to LoadUI

LoadUI is an API load testing tool that implements a visual programming model to allow testers to design flexible, configurable test scenarios without writing any code. This is great because the user can focus on the test strategy and design rather than on the nuts and bolts that make it all happen (read code).
When creating a load test, all you need to do is connect different components graphically to implement the logic of the test. After that, you can create charts to show the data from each component you’re interested in, such as requests/second, average response time, standard deviation, among many others.
LoadUI components can be of the following categories:
  • Generators: generate a certain kind of load, such as fixed, ramp, random etc.
  • Runners: run actions which will affect the system being tested. For example: run a HTTP request, a script, or even a SoapUI test-case.
  • Flow: allow more advanced logic to be implemented. Examples include the Splitter, which can split the load generated by a single Generator between several Runners, and the condition component, which only sends a signal on to the next component if a certain condition (eg. response time > 1000ms) is satisfied.
  • Schedulers: can schedule when other components, such as generators, will be activate/deactivated.
  • Output: currently, the only output component is the table log, which shows in a table all data produced by the component connected to its input.

Do you have a component for <enter your load test scenario here>?

If you have ever used a visual programming tool, you’ll probably be skeptical if anyone claimed that it allows users to come up with any scenario imagined in the way that a Turing-complete programming language mostly does. And if you’re familiar with LoadUI, you’ve probably already started thinking of test scenarios you came up with in the past that you could not implement easily in LoadUI. You may have ended up with a gobbled mess of interconnected components that probably looks, literally, like spaghetti (visual) code.
This was made patently clear to me when a frustrated customer emailed us (the LoadUI development team) through support with this exact problem. He wanted to generate a step-increasing load with LoadUI and found out that for each load increase, two LoadUI components were required. He needed quite a few increases, so he ended up with the following project:

loadui-c-users-bottenheim-desktop-cloggedUnfortunately, none of the LoadUI standard components or custom components available at the time from the LoadUI’s website made that apparently simple scenario any easier to implement.

That’s when knowing a little code (or knowing someone who does!) can get you out of the mess and save you hours of frustration! But do not despair! The coding skills required to extend LoadUI by creating your own components is pretty basic. If you don’t believe me, keep reading as I go through the process of creating a new generator component for LoadUI that addresses our customer’s scenario.

Anyone can Write a Component for LoadUI

All LoadUI components (with the notable exception of the SoapUI Runner, which is part of the LoadUI source code itself) consist of just one Groovy file and an icon, which is just a picture file with the same name as the groovy file. They are stored in the script-components directory, directly under the LoadUI installation directory. Go on and have a look at some of the groovy files!

You may notice that Groovy is very similar to Java. So similar that in many cases you can simply write code in Java and it will just work in Groovy. I believe you will also appreciate the simplicity. There are several blocks that make use of the Component DSL, of which you can find more information on the Custom Components Reference page.

You should also check out this blog post by my SmartBear colleague, Ole Lensmar, that explains a little more on how to write a LoadUI component from scratch (ending up with the DropRate Component and all of its 14 lines of code!).

Writing the Stepped Rate Generator Component

First of all, you should check the LoadUI components which are already available, including the custom components, to see if there’s anything that does something similar to what you need. Chances are that you’ll find something that at least can be used as a good starting point for your own component.

In our example, we’re going to write a Stepped Rate Generator which generates a load in the shape of an upwards step, as shown below:

SteppedRateChartThe closest LoadUI component that does something like this seems to be the simple Fixed Rate Generator, which just generates, well, a fixed load.

The fact that it is a very simple component also makes it perfect as a starting point for writing our first component.

So, let’s get started by making a copy of FixedRate.groovy, calling it SteppedRate.groovy, and having a look at the code.

We need to change the component description in the GroovyDocs at the beginning of the file (especially its ID and name) so that LoadUI recognizes our new component correctly:

/**
 * Sends an empty message periodically, at a set rate, increasing at a fixed interval
 * 
 * @id com.eviware.SteppedRate
 * @help http://loadui.org/Custom-Components/
 * @name Stepped Rate
 * @category generators
 * @nonBlocking true
 */ 

You’ll see that the central action of this component is the schedule closure, which apart from figuring out the delay value in micro-seconds, schedules an action to run at a fixed rate, as one would expect:

future = scheduleAtFixedRate( triggerBurst, delay, delay, TimeUnit.MICROSECONDS )

It should be easy to see that the action called triggerBurst (another closure) will be run every delay microseconds. Here is the triggerBurst closure:

triggerBurst = {
burstSize.value.times {
trigger()
}
}

Burst size here refers to a property of the component which can be set by the user. So we can see that the method trigger() will be called at a fixed rate, burstSize times. This method is what actually generates a load. All the rest of the code is basically concerned with creating all properties of the component and establishing the layout in the normal and compacted views.

Now it should be pretty clear that all we need to do here to get a component which increases the load at a certain interval is:

  1. Change the ‘rate’ property to ‘initial rate’ (because the rate will increase over time) and create a “currentRate” variable.
  2. Create a ‘increment’ property which determines by how much the load should increase at each interval.
  3. Create a ‘Interval’ setting which determines how often the load should be increased.
  4. Create a ‘displayNoteOnRateChange’ so that the user can choose to be notified when the load is increased.

Firstly, we make the changes to the properties so that it now looks like this:

//Properties
createProperty( 'startRate', Long, 10 ) { runCycle() }
createProperty( 'interval', Long, 5 ) { runCycle() }
createProperty( 'increment', Long, 5 ) { runCycle() }
createProperty( 'unit', String, 'Sec' ) { runCycle() }
createProperty( 'burstSize', Long, 1 )
createProperty( 'displayNoteOnRateChange', Boolean, true )

We also want these properties to be visible in the component’s graphic representation, so we need the following lines also:

//Layout
layout {
property( property:startRate, label:'Start Rate', min:1 )
property( property:increment, label:'Increment', min:1 )
property( property:interval, label:'Interval', min:1 )
separator( vertical:true )
property( property:unit, label:'Unit', options:['Sec','Min','Hour'] )
separator( vertical:true )
box( widget:'display', layout:'wrap 2, align right' ) {
node( label:'Start Rate', content: { "$startRate.value / $unit.value" }, constraints:'wmin 75' )
node( label:'Increment', content: { "$increment.value / $unit.value" }, constraints:'wmin 75' )
node( label:'Interval', content: { "$interval.value $unit.value" }, constraints:'wmin 75' )
node( label:'Current Rate', content: { "$currentRate / $unit.value" }, constraints:'wmin 75' )
}
}
 
//Compact Layout
compactLayout {
box( widget:'display' ) {
node( label:'Curr rate', content: { "$currentRate / $unit.value" } )
node( label:'Intvl', content: { "$interval.value $unit.value" } )
}
}

The property displayNoteOnRateChange can just go in the settings tab:

//Settings
settings( label: "General" ) {
property( property: burstSize, label: 'Burst size' )
property( property: displayNoteOnRateChange, label: 'Display Notification on rate update' )
}

Now everything “looks” ready…. if you open LoadUI and create your new component, you will see it and it will certainly look ready! However, we have not yet implemented the actual logic of the component, so if you run it, it will just use the ‘start rate’ as a fixed rate, ignoring all other settings.

To implement the logic, a little thought is needed… instead of scheduling the triggerBurst task to run forever (or until someone stops the test!) at a fixed rate, we need to, at regular intervals, increase the rate, which means decrease the value of delay.

It’s not hard to accomplish that. First, we must replace the variable rate that was used to calculate the value of delay with currentRate, as the rate will change overtime. Second, in theschedule closure, we add the following line that will schedule the next change of rate:

rateChangeFuture = schedule( rateUpdater, interval.value, timeUnitFor( unit.value ) )

Here’s the rateUpdater code:

rateUpdater = {
currentRate += increment.value
if ( displayNoteOnRateChange.value ) warn "Changed current rate to $currentRate"
schedule()
}

Every time it runs, it increases the current rate and re-schedules everything, which in turn schedules again the next rate increase. If the user checks the displayNoteOnRateChange option, a popup is shown to the user by calling the warn method.

A few more changes to ensure that the tasks are correctly started and canceled at the start and end of a test run and our component is ready for production. You can find the complete source for this component in the Custom Components page (just download the component).

Conclusion

I hope you enjoyed writing a LoadUI component starting from an existing one so that LoadUI can do exactly what you want. You might want to scroll up for a little moment and have a look at the project setup required to generate a stepped rate near the beginning of this post. Well, with the new component we’ve created, it would now look like this:

loadUI-steppedRateProject

Not too bad!

See also:

 

Speak Your Mind

*