Denodo Load Testing with LoadRunner

Applies to: Denodo 8.0
Last modified on: 24 Feb 2021
Tags: Administration LoadRunner Optimization Performance

Download document

You can translate the document:

Introduction

LoadRunner is a software testing tool provided by Micro Focus used to perform load/stress tests in your applications, measuring the behaviour and performance of your system under high workload.

LoadRunner simulates user activity by generating requests that are executed against an application. These interactions are stored in scripts.

Depending on the type of interaction, LoadRunner can generate the scripts by recording them using some wizards but also allows you to create customized scripts manually by writing a few lines of code on your own.

In this article we will focus on how to configure Loadrunner to connect to Denodo and create script tests using JDBC, ODBC and REST API interfaces. The tests will be generated using the Virtual User Generator or VuGen, which is the tool used for creating and editing scripts.

Preparing the scenarios for the testing and analyzing the results are out of the scope of this document.

Setting up the testing plan

The scenario proposed is quite simple. We have a “demo” database with a derived view representing the cities in the world by country. We will run queries on the view “cities_by_country” to execute our performance tests.

JDBC scripts

In order to create a JDBC script in LoadRunner, go to “File” -> “New Script and Solution”.

This will open a new dialog to select the type of interaction or application we want to check. We will select “Java Vuser”, provide a script name and the location to generate it.

Once we click on create, the empty script structure will be displayed as follows:

Let's take a look at the main elements of the structure:

Actions

The Action.java class is an empty class with a simple do-nothing test that can be used to start working on your code. It contains three methods.

  1. init() will be executed once at the beginning of the test. This method can be useful to create connections or initialize objects or variables used in your test.
  2. action() contains the test to perform and will be executed one or many times depending on how the script is configured. We will cover that later.
  3. end() will be executed once at the end of all the executions of action().

vuser_init and vuser_end are classes autogenerated from a common template and we do not need to modify them for a JavaVuser script so we will leave them as they are.

Runtime Settings

The Runtime Settings is where we will define how the test will be executed as well as define the external libraries or Java Virtual Machine required to run the tests.

First thing to do is selecting the Java JVM used.

You can select a specific JDK or check “Use internal logic to locate JDK” to let Loadrunner search for your default JVM.

We would also need to modify the classpath to make sure we include the Denodo JDBC Driver. The “Add File” button will open a dialog to locate the JDBC driver which is located under the <DENODO_HOME>/tools/client-drivers/jdbc folder.

The last section for this sample is “Pacing”, where the number of times the action will be repeated is defined as well as how these iterations will be launched.

In order to keep this example simple, we will define 10 iterations that will be executed sequentially.

We already have the Script configured and we just need to prepare Java code for our test that will be embedded in the methods init, action and end.

A possible sample of code could be:

import lrapi.lr;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.ResultSetMetaData;

import java.sql.SQLException;

public class Actions

{

        

        private Connection connection;

                

        public int init() throws Throwable {

        

                // JDBC Driver load

           try {

                Class.forName("com.denodo.vdp.jdbc.Driver");

                    // Connect the driver to the database

                this.connection = DriverManager.

                 getConnection(

                  "jdbc:vdb://localhost:9999/demo", "demo", "demo");

           } catch (Exception e) {

                System.err.println("Error loading VDPDriver ... " +                    

                 e.getMessage());

                System.exit(-1);

           }

        

                return 0;

        }//end of init

        public int action() throws Throwable {

        

                lr.start_transaction("Test");

                // Create the statement from the user query

           PreparedStatement statement = connection.

              prepareStatement(

               "SELECT * FROM cities_by_country");

           // Execute the query

           statement.execute();

           // Obtaining the result of the query and printing it.

           ResultSet result = statement.getResultSet();

                if (result != null) {

                    // Iterate over the rows returned

                while (result.next()) {

                                        // Do nothing it just a test

                }

            } else {

                System.err.println("Error in result");

            }

       

                lr.end_transaction("Test", lr.AUTO);

                return 0;

        }//end of action

        public int end() throws Throwable {

                // The connection must be closed.

           if (connection != null) {

                 try {

                             connection.close();

                 } catch (SQLException e) {

                     e.printStackTrace();

                 }

           }

                

                return 0;

        }//end of end

        

}

Note that the code above is nothing more than a very simple Java JDBC client code. You can find a code similar to this one under the <DENODO_HOME>/samples/vdp/vdp-clients folder.

Now, the Script is ready and we can execute it from the “Replay > Run” option or just pressing F5.

The Replay Summary will show the results of the execution:

Note that you can use the option “Select result scope” to check individually the different iterations to analyze the individual execution time.

ODBC scripts

Configuring an ODBC script is the same as a JDBC script but with a few differences apart from the code that will be written in C instead of Java.

In order to create the ODBC script, go to “File > New Script and Solution”.

If we inspect the structure created we will see that it is similar to the JBDC one so we will only focus on the differences.

In the ODBC scripts the code is written in C and the methods to execute the test will be defined in different files (Note that, in the Java test, the code is implemented on a single file):

  1. vuser_init will contain the code to be executed once before the test.
  2. Action will contain the code of the test and will be repeated according to the number of iterations defined in the Runtime Settings.
  3. vuser_end will contain the code to be executed after the execution of the tests.

A possible code for each file defined above could be:

           vuser_init file:

#include "lrd.h"

static LRD_INIT_INFO InitInfo = {LRD_INIT_INFO_EYECAT};

static LRD_DEFAULT_DB_VERSION DBTypeVersion[] = {{LRD_DBTYPE_NONE, LRD_DBVERSION_NONE}};

static LRD_CONTEXT FAR * Ctx1;

static LRD_CONNECTION   *Con;

char *        DEFAULT_TRANSACTION = "ODBC_SQL_Connection";

static LRD_CURSOR *Csr;

vuser_init()

{

        // Get Data Source Name

        lr_save_string("Denodo8-32","dsn");

        // Get SQL Statement

        lr_save_string("SELECT * from dual()","sql_statement");

        // Get Username        

        lr_save_string("demo","username");

        // Get Password

        lr_save_string("demo","password");        

        lrd_init(&InitInfo, DBTypeVersion);

    lrd_open_context(&Ctx1, LRD_DBTYPE_ODBC, 0, 0, 0);

        

        return 0;

}

        Action file:

Action()

{

        

        lr_start_transaction(DEFAULT_TRANSACTION);

        lrd_open_connection(&Con, LRD_DBTYPE_ODBC, "demo", "demo", "Denodo8-32", "", Ctx1, 0, 0);

           lrd_open_cursor(&Csr, Con, 0);

           lrd_stmt(Csr, lr_eval_string("SELECT code, country, name, district, population FROM cities_by_country"), -1, 1, 0, 0);

        lrd_fetch(Csr, -1, 1, 0, NULL, 0);

        lrd_close_cursor(&Csr, 0);

        lrd_close_connection(&Con, 0, 0);

        lr_end_transaction(DEFAULT_TRANSACTION,LR_AUTO);

        

        

        return 0;    

}

vuser_end file:

vuser_end()

{

        // Close cursor and connection if still open.

        if (Csr != 0) lrd_close_cursor(&Csr, 0);

        if (Con != 0) lrd_close_connection(&Con, 0, 0);

    lrd_close_context(&Ctx1, 0, 0);

        lrd_end(0);

        return 0;

}

Once the code is ready, you can define the number of iterations and other parameters in the Runtime Settings and run the tests as we did for the JDBC script.

REST API scripts

For this particular example, we are going to show some extra features provided by LoadRunner. Instead of creating the code manually, we will rely on LoadRunner to generate it automatically.

In order to create a REST API test we need to create a new Script selecting the protocol “Web - HTTP/HTML”.

Once it is created, the “Solution Explorer” will display the new script and its configuration.

The Action.c file will contain the logic to launch the http request to Denodo.

Now, the next step is to generate the request. This could be done editing manually the Action.c file or using the “Record” option to auto generate a request as follows:

 

When clicking on “Start Recording”, the Virtual User Generator will open a browser and complete the request on its own generating the sequence of steps that will be included in the Action.c file when stopping the recording.

The final result should be like this:

For this type of test, we can modify our script in the option “Runtime Settings” using an extra option available called “Run Logic Tree”, that defines the iterations of the test among other parameters.

We can customize the execution as follows:

In this example we have clicked on “Run” to specify in the “Group Properties”:

 

  • Run Logic: Random
  • Number of iterations: 10

So the test will consist of 10 requests sent to Denodo randomly in a short period of time.

Saving the new “Runtime Settings” and clicking on “Replay” again we will have the summary of the new test, having the data by iteration or the average response times.

Monitoring the behavior of the Denodo server

In combination with the reports generated by LoadRunner, it is also very useful to monitor the behavior of the Denodo server in real time with tools like the Denodo Diagnostic & Monitoring tool or VisualVM.

This will allow you to monitor not only the results of the queries, but also a number of interesting parameters like:

  • CPU usage.
  • Memory (Heap space) usage.
  • Memory Pools.
  • GC Time.
  • Status of the connection pools managed by Denodo to the data sources.

Denodo Diagnostic & Monitoring tool monitoring different tests launched from LoadRunner

Analyzing the results

Once the test is completed, it is time to analyze the results. If there are no errors in the execution, we can increase the number of iterations to test the server under a heavier load.

An analysis of several parameters in execution time (usually via JMX or using the Diagnostic & Monitoring tool) and the analysis of the logs of the server (found in <DENODO_HOME>/logs/vdp/vdp.log) will help in the tuning process.

Questions

Ask a question
You must sign in to ask a question. If you do not have an account, you can register here

Featured content

DENODO TRAINING

Ready for more? Great! We offer a comprehensive set of training courses, taught by our technical instructors in small, private groups for getting a full, in-depth guided training in the usage of the Denodo Platform. Check out our training courses.

Training