Scripting RMI with Loadrunner VuGen 9.5x and 11

Performance test RMI

The Java Remote Method Invocation (RMI) is a Java application programming interface that supports an object-oriented way of  remote procedure calls (RPC). In this article I show you two ways to create performance tests scripts with Loadrunner for RMI-driven applications.

As RMI is a Java-specific protocol, the Java vuser or the Java Record replay protocols mush be used in the Virtual User Generator.

I demonstrate two approaches:

  1. Code RMI calls manually – using Java VUser script type
  2. Record the network traffic of the RMI application’s client and then play it back – using Java Record replay script type

Note: The respective Loadrunner licenses are necessary to run the created tests in the Controller.

The test application

I created a small RMI client-server test application using the Java Spring Framework. For simplicity the RMI server application is packaged as a WAR and can be run in a java web container (e.g. Tomcat). The client has been packaged into a single JAR file for easy execution. This JAR file will be reused in VUgen.  It contains the RMI interface of the application under test and the necessary Spring Framework APIs for easy RMI access.

If you would like to try the test application, here are the necessary tools:

  • Java Development kit (e.g. 1.6)
  • Apache Maven for build and dependency management
  • Apache Tomcat to execute the RMI test server application

The test application can be downloaded here: spring-rmi-poc-test-app.zip

Using Java VUser script type (using Loadrunner Virtual User Generator 9.5x)

  1. Create a new Java VUser script
  2. Use File/Add files to script… menu to add the test client jar to the script. Adding JAR files this way ensures that the contained classes will be placed to the Classpath, therefore will be available in script.
  3. Code the RMI call manually, as it would be done in any other Java program. In our example we used Spring Framework to facilitate that.
JAR file added to Java virtual user script
/*
* LoadRunner Java script. (Build: 3020)
*
* Script Description:
*
*/
import lrapi.lr;
import org.springframework.remoting.rmi.RmiProxyFactoryBean;
import rmitest.intf.AccountService;

public class Actions
{

  RmiProxyFactoryBean proxy = new RmiProxyFactoryBean();

  public int init() throws Throwable {
    // TODO update here the name of <a href="http://vigrxinfo.com/">vigrx wikipedia</a> the server and the port:
    proxy.setServiceUrl("rmi://localhost:1199/AccountService");
    proxy.setServiceInterface(AccountService.class);
    proxy.afterPropertiesSet();

    return 0;
  }//end of init

  public int action() throws Throwable {
    try {
      lr.start_transaction("getAccounts");

      Object obj = proxy.getObject();
      AccountService service = (AccountService) obj;
      service.getAccounts("akarmi");

      lr.end_transaction("getAccounts", lr.AUTO);
    } catch (Exception e) {
      lr.end_transaction("getAccounts", lr.FAIL);
    }
    return 0;
  }//end of action

  public int end() throws Throwable {
    return 0;
  }//end of end

}

Using Java Record replay script type

(This script type available in VuGen 9.5, however it functioned for me only in Loadrunner 11 well.)

This approach is useful, if it is possible to run the RMI client application together with Loadrunner capturing. For complex or platform- or environment-dependent application it is usually not the case however.

To start the example RMI client the following batch file has been created. It is to be specified in the Start Recording dialog, via seting Application type to „Executable\Batch”. I set the working directory to point the directory of the jar file.

%JAVA_HOME%\bin\java -jar spring-rmi-jar-with-dependencies.jar

Ensure, that in the Recording Options the RMI protocol is selected.

RMI is selected as a recorded protocol

The client application should now start and the RMI traffic will be recorded and transformed into java code.

Start recording dialog to capture RMI client application’s traffic

Here is a sample generated raw code:

/*
* Code generated by RMI support (Build: _build_number_) - Vugen [JAPATA] for LoadRunner Version 11.0.0
* Session was recorded on: Thu Dec 10 14:34:35 2011
*
* Using VM version : Executable
* Script Author    : Richard
* Script Description:
*
*/

import lrapi.lr;
import java.util.Properties;

public class Actions
{
  // Public function : init
  public int init() throws Throwable {
    // Set system properties...
    _properties1 = System.getProperties();
    _properties1.put("sun.desktop", "windows");
    _properties1.put("sun.jnu.encoding", "Cp1251");
    _properties1.put("sun.management.compiler", "HotSpot Client Compiler");
    _properties1.put("sun.java.launcher", "SUN_STANDARD");
    System.setProperties(_properties1);

    // Installing RMISecurityManager
    if (System.getSecurityManager() == null)
    System.setSecurityManager(new java.rmi.RMISecurityManager());
    return 0;
  }//end of init

  // Public function : action
  public int action() throws Throwable {
    // Lookup a remote object...
    _rmiinvocationhandler1 = (org.springframework.remoting.rmi.RmiInvocationHandler)java.rmi.Naming.lookup("rmi://localhost:1199/AccountService");
    _string1 = "org.springframework.remoting.support.RemoteInvocation __CURRENT_OBJECT = {" +
    "java.lang.Object arguments[] = {" +
    "java.lang.Object arguments[0] = #akarmi#" +
    "}" +
    "java.util.Map attributes = _NULL_" +
    "java.lang.String methodName = #getAccounts#" +
    "java.lang.Class parameterTypes[] = {" +
    "java.lang.Class parameterTypes[0] = {}" +
    "}" +
    "}";

    _remoteinvocation1 = (org.springframework.remoting.support.RemoteInvocation)lr.deserialize(_string1,0);&amp;amp;amp;nbsp; // RMIComponent
    _object1 = _rmiinvocationhandler1.invoke((org.springframework.remoting.support.RemoteInvocation)_remoteinvocation1);
    return 0;
  }//end of action

  // Public function : end

  public int end() throws Throwable {
    return 0;
  }//end of end

  // Variable section
  java.lang.Object[] _object_array1;
  java.util.Properties _properties1;
  org.springframework.remoting.rmi.RmiInvocationHandler _rmiinvocationhandler1;
  org.springframework.remoting.support.RemoteInvocation _remoteinvocation1;
  java.lang.String _string1;
  java.lang.Object[] _object_array2;
  java.lang.Object _object1;
}

Leave a Reply

Your email address will not be published. Required fields are marked *