Robot can be successfuly used to generate load for stress testing.
The idea is to start
many parallel testing processes to simulate a number of users accessing
a
service or using an application. As Robot simulates a real user
behavior in a graphical environment, such a scenario will
create load on the tested system which is very similar to real
production
environment.
Robot
supports has a Java API which allows to create multiple testing threads
within a single Java Virtual Machine. Each thread may independently
execute one test script on a single VNC
server instance. See the
RobotThread interface of the
Robot API for more information. Note that Unix/Linux systems are
preferred to host the load tests
because unlike Windows they are capable of running many VNC
server instances on a single machine.
Let's create an example program generating load on a tested
application. We need to create three components:
There is no test script included in this example. You need to create it before and integrate it with the Java and shell wrappers described below. See the previous examples in this document on how to create a test script in the Robot scripting language. You may easily use the Record & Replay feature to do so. It is highly recommended to use a small remote desktop size (e.g. 800x600 pixels) and avoid image comparison and taking of screenshots. All these factors significantly increase the amount of required memory and CPU time. Another good idea is to set your remote desktop background (wallpaper) to a solid color. In the next steps we will suppose that the test script already exists and is saved in a file called client.txt.
Java wrapper is a program which creates and starts the automated testing threads using the Robot API. A universal wrapper code is displayed below.:
LoadExample.java |
import com.Robot.Robot;
import com.Robot.api.RobotThread;
/**
* LoadExample.java
*
* This is an example of load testing based on Robot.
*
* (C) 2007, Robert Pes
*/
public class LoadExample {
// Default number of threads.
final static int DEFAULT_THREAD_COUNT = 50;
// Main method.
public static void main(String[] argv) {
// Number of threads
int threadCount = DEFAULT_THREAD_COUNT;
// Password
String password = null;
// Script path
String script = null;
// Parse the program arguments. We expect an integer
// indicating how many threads we will start followed by script name.
// The last argument, VNC password, is not mandatory because some
// VNC servers can be configured not to require authentication.
if (argv.length > 1 && argv.length < 4) {
try {
threadCount = Integer.parseInt(argv[0]);
script = argv[1];
if (argv.length > 2) {
password = argv[2];
}
} catch (NumberFormatException ex) {
System.out.println("Invalid number of threads - default of "
+ DEFAULT_THREAD_COUNT+" will be used.");
}
} else {
System.out.println(
"Usage: LoadExample <number_of_threads> <script_path> [<VNC_password>]");
return;
}
// Thread arguments. They are identical with Robot CLIoptions.
String[] threadArguments;
if (password == null) {
threadArguments = new String[] {
"--connect", // Connect option
"", // VNC host name and port - will be generated dynamically
"--run", // Run option
script, // Name and path of the script to run
"--nodisplay"// CLI execution mode option
};
} else {
threadArguments = new String[] {
"--connect", // Connect option
"", // VNC host name and port - will be generated dynamically
"--run", // Run option
script, // Name and path of the script to run
"--nodisplay", // CLI execution mode option
"--password", // Password option
password // Password
};
}
// Create an instance of Robot
Robot robot = new Robot();
RobotThread runnable;
Thread thread;
// Loop for index from 1 to specified number of threads
for (int i=1; i<=threadCount; i++) {
// Populate the VNC host name and port in the thread arguments
threadArguments[1] = "localhost:" + i;
// Create a new automated thread and start it
runnable = robot.createRobotThread(
threadArguments[1], threadArguments, System.out, false);
thread = newThread(runnable);
thread.start();
}
}
}
To run the wrapper compile the Java code to .class or take advantage of the precompiled class in the attached ZIP file. The program accepts up to three parameters - desired number of threads to be started (mandatory), path to the testing script (mandatory) and VNC password (optional). The command should look like:
java -classpath
.:./Robot.jar LoadExample <thread_number> <script_path>
[<password>]
Before you start the VNCRobot load testing, you always need to start all the necessary VNC servers. You should also verify whether any application involved in the testing allows only one instance per user. A typical example is Firefox which will not allow a single user to run more than one browser. To resolve this you will need to create a different user for each test thread and start the VNC server under his account.
All these necessary overhead tasks can be efficiently automated on Linux/Unix by simple shell scripts. Let's suppose that our example application doesn't have any instance limitations. All we need to do then is to start the VNC servers, execute the Java load application and kill the VNC servers after the testing gets finished. A Bash script handling these tasks follows.
runLoad.sh |
#!/bin/bash
# Number of threads to be executed
THREADCOUNT=10
# Path to the automated script
SCRIPT=client.txt
# VNC password. If your VNC server doesn't require password,
# leave the variable empty.
PASSWORD=welcome
# This 'for' statement will start VNC servers on local machine
# on ports 1 to THREADCOUNT
for ((i=1; i<=$THREADCOUNT; i++))
do
vncserver :$i
done
# The following command will execute the Java wrapper with Robot
# automated threads
java -Xmx512m -classpath .:./Robot.jar LoadExample $THREADCOUNT
$SCRIPT $PASSWORD
# This 'for' statement will kill all the VNC servers started
# at the beginning of this script
for ((i=1; i<=$THREADCOUNT; i++))
do
vncserver -kill :$i
done
The shell wrapper source together with the Java wrapper are available for download in the attached ZIP file. Before you execute it, set correct values of the THREADCOUNT, SCRIPT and PASSWORD variables. If you define the number of threads too high, some of them may start to fail with java.lang.OutOfMemoryError. To fix this issue increase the JVM memory heap size specified by the -Xmx Java option in runLoad.sh (default value is set to 512MB).
12 December 2014 |
Copyright © T-Plan Ltd. |
Version 1.0 |