Thursday, March 22, 2012

How to Test REST Web Service Using The Grinder

A simple and easy method of load testing a REST service using The Grinder open source load testing tool is as follows:
  • use the HttpRequest object
  • use the appropriate REST method on the HttpRequest object: 
    • Method=PUT
    • Method=GET
    • Method=DELETE


















The following script gives an example of this method in the case of REST PUT request using a JSON request message.  (XML request message would be similar).

Script

# The Grinder 3.7.1

from net.grinder.script import Test
from net.grinder.script.Grinder import grinder
from net.grinder.plugin.http import HTTPPluginControl, HTTPRequest
from HTTPClient import NVPair
connectionDefaults = HTTPPluginControl.getConnectionDefaults()
httpUtilities = HTTPPluginControl.getHTTPUtilities()

# headers
headers0= \
  [ ]

# Http URL
url0 = 'http://servername:8080'

# Create an HTTPRequest for each request, then replace the
request101 = HTTPRequest(url=url0, headers=headers0)
request101 = Test(101, 'PUT Test').wrap(request101)

request102 = Test(102, 'PUT Test 2').wrap(request101)

json1 = '''{
              \"key1\"        :  \"BD6632F8569D4D609BB8ED902E9F6585\",    
              \"key2\"        :  \"65EE35B00655100625F85498A6092F80\",    
              \"key3\"        :  \"984921672\",\r\n    
              \"id1\"         :  \"6\",\r\n    
              \"id2\"         :  \"1\",\r\n    
              \"descr\"       :  \"4724711\",\r\n    
        }'''
json2 = '''{   
              \"key4\"        :  \"6\",\r\n    
              \"key5\"        :  \"1\",\r\n    
              \"key6\"        :  \"0\",\r\n    
              \"key7\"        :  \"2\",\r\n    
              \"name1\"       :  \"Green Bay\",\r\n    
              \"name2\"    :  \"GRBay\",\r\n    
        }'''


class TestRunner:
  """A TestRunner instance is created for each worker thread."""

  # A method for each recorded page.
  def page1(self):
    """PUT Test (request 101)."""
    result = request101.PUT('/Capture/Test', json1,   ( NVPair('Content-Type', 'application/json'), ))

    return result
# A method for each recorded page.
  def page2(self):
    """PUT Test (request 101)."""
    result = request102.PUT('/Capture/Test', json2,   ( NVPair('Content-Type', 'application/json'), ))

    return result

  def __call__(self):
    """Called for every run performed by the worker thread."""
    self.page1()      # PUT Test (request 101)
    self.page2()      # PUT Test (request 102)

Output

Monday, March 19, 2012

How To Integrate Jmeter Java Request Into Ant Build System

Install Jmeter

Install Ant-Jmeter

The jar should be put in the ant\lib directory, for example here: <path>\apache-ant-1.8.1\lib\ant-jmeter-1.1.1.jar

Integrate Ant-Jmeter with Build system

Upload jars needed to create meter java requests
The ApacheJMeter_core.jar and ApacheJMeter_java.jar libraries in jmeter\lib\ext are needed to write jmeter java request classes, so they need to be visible.
  • \ApacheJMeter_core-1.0.jar
  • ApacheJMeter_java-1.0.jar

Create A JMeter Plan








Integrate Jmeter into Build project

Add a jmeter-run ant target to ant build.xml.  Also copy the jmeter plan file to the output directory
<?xml version="1.0" encoding="UTF-8"?>
<project name="test.JmeterTest" default="build">
 
 <target name="copy-jmeter-plan">
   <!-- copy jmeter plan file --> 
   <copy todir="${output.root}">
    <fileset dir="${project.root}" includes="*.jmx"/>
   </copy>
   
   <!-- make out directory --> 
   <mkdir dir="${output.root}/out" />
  </target> 
 
 <!-- define jmeter task --> 
 <taskdef
      name="jmeter"
      classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask"/>
 
 <target name="jmeter-run">
  <jmeter
       jmeterhome="c:\dev\jmeter\apache-jmeter-2.6"
       testplan="${output.root}\CaptureJSONRequest.jmx"
       resultlog="${output.root}\out\CaptureJSONRequest.jtl">
   <property name="user.classpath" value="${output.root}\lib\ApacheJMeter_core-1.0;${output.root}\lib\ApacheJMeter_java-1.0"/>
  </jmeter>
  
  <xslt
          in="${output.root}\out\CaptureJSONRequest.jtl"
   out="${output.root}\out\jmeter-results-report.html"
   style="C:\dev\jmeter\apache-jmeter-2.6\extras\jmeter-results-report_21.xsl"/>
 </target>
</project>

Create a Jmeter Request Class

package org.apache.jmeter.protocol.java.test;
import java.io.Serializable;

import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.threads.JMeterContextService;
import org.apache.jmeter.threads.JMeterVariables;

public class JavaRequestTest extends AbstractJavaSamplerClient implements Serializable
{
  @Override
  public SampleResult runTest(JavaSamplerContext ctx) 
  {
    JMeterVariables vars = JMeterContextService.getContext().getVariables();
    vars.put("demo", "demoVariableContent");

    SampleResult sampleResult = new SampleResult();
    
    sampleResult.sampleStart();
    try 
    {
  Thread.sleep(100);
 } 
    catch (InterruptedException e) 
    {
  System.out.println(e.toString());
 }
    sampleResult.setSuccessful(true);
    
    sampleResult.setResponseCodeOK();
    sampleResult.setResponseMessageOK();
    return sampleResult;
  }  
}

Add Jmeter Request to jmeter plan

Jmeter should display the newly added JavaRequestTest class.

Configure output file locations

Make file locations relative to location of plan, which is in the output.root based on build file copy-support. Specify file location for summary report as something like this: ~/out/summary-report.xml

Run Jmeter

>ant jmeter-run

jmeter-run:
   [jmeter] Executing test plan: \outputroot\test.JmeterTest\CaptureJSONRequest.jmx ==> \outputroot\test.JmeterTest\out\CaptureJSO
NRequest.jtl
   [jmeter] Created the tree successfully using \outputroot\test.JmeterTest\CaptureJSONRequest.jmx
   [jmeter] Starting the test @ Wed Feb 08 16:09:22 PST 2012 (1328746162061)
   [jmeter] Waiting for possible shutdown message on port 4445
   [jmeter] Tidying up ...    @ Wed Feb 08 16:09:48 PST 2012 (1328746188084)
   [jmeter] ... end of run
     [xslt] Processing \outputroot\test.JmeterTest\out\CaptureJSONRequest.jtl to \outputroot\test.JmeterTest\out\jmeter-results-re
port.html
     [xslt] Loading stylesheet \jmeter\apache-jmeter-2.6\extras\jmeter-results-report_21.xsl

BUILD SUCCESSFUL
Total time: 28 seconds

Look at report

Look at the ant report:

Monday, March 12, 2012

How to Perform Mathematical Operations on Loadrunner Parameters

A simple way to perform calculations on parameters is as follows:

  • Convert the Loadrunner parameter to a C variable
  • Perform the calculation on the C variable
  • Push the C variable back to the parameter

The following shows how to do that in the case of addition and multiplication on a Loadrunner parameter.

Script

Action()
{
    // Assume you start with a parameter "{paramInt}"
    int i = 0;
    int result = 0;
    int num = 10; 
    lr_save_int(num, "paramInt"); 
    lr_log_message("Parameter value at start = %s", lr_eval_string( "{paramInt}" ));


    // Save the parameter to a C variable
    i = atoi( lr_eval_string( "{paramInt}" ));


    // Perform the calculation
    result = i + 10;
    
    // Save the calculation back to the parameter "{paramInt}"
    lr_save_int(result, "paramInt"); 
    lr_log_message("Parameter value after sample addition = %s", lr_eval_string( "{paramInt}" ));


    // Another example showing multiplication
    i = atoi( lr_eval_string( "{paramInt}" ));
    result = i * i;
    lr_save_int(result, "paramInt"); 
    lr_log_message("Parameter value after sample multiplication = %s", lr_eval_string( "{paramInt}" ));


    return 0;
}


Console Output

Running Vuser...
Starting iteration 1.
Starting action Action.
Parameter value at start = 10
Parameter value after sample addition = 20
Parameter value after sample multiplication = 400
Ending action Action.
Ending iteration 1.
Ending Vuser...