Go back to all articles

Virtual Table Server

Jul 22, 2020
7 min read

I think that many readers are actively using LoadRunner. So I’ve got a question for you – where do you take the test data from? The first option is to parametrize everything and save the dataset in .dat-files. It’s a good solution, but what if there are many scripts with common parameters in the use case? The second option is to use a database. It’s already better, because the common parameters can be shared, but the configuration for some databases can be a nightmare for a newbie. I’ve got one more option that is both simple and effective.

Our topic will be a LoadRunner component – Virtual Table Server (VTS). To begin with, let’s sort out, what it is and what to do with it. Its last versions have a js-node server on the back-end and its architecture reminds a database. But it just seems so on the first glance. Actually, I’d rather compare VTS with a simple table, because we can access practically any cell, row or column using the column name or the row number. We can read, delete and add data, as well as empty the table – all of it without leaving LR. The details can be found below. First let’s discuss, where to find it and how to install it.

Installation

Habitation area is the folder \Additional Components\Virtual Table Server or MicroFocus site (registration required to download the files). There shouldn’t be any difficulties during the installation. First the temp folder should be selected, then the main installer will run. During the installation there will be an option to change the program folder, as well as an option to choose a server management port. It’s recommended to keep the default value: 4000 (of course, if the port is not already in use). For those, who are lazy or value their time, there is an opportunity to automatically start the VTS. We activate the check-box, and after the install the browser with the application web-interface will open.

Don’t forget to switch on the script connection to the server through “Access from Script” on the right top menu.

Data input

We’ve got several options: send the data from the database, import it from a csv-file or using a script, do everything manually in the browser In my opinion the optimal version is to import data from a csv-file or using a script. I’m going to explain these two approaches. In case you are interested in the database import, take a look here.

CSV import

To begin with, we’ve got a csv – a regular text file with comma separators is enough. The first option is to use Import ->Import from CSV file in the web-interface. Then we just need to choose the file, whisper the incantation and olè – your data has already been pasted in the table. The second option is to use a script that will do the job for you You’ll need the file \VTS\web\vtscmd.js.

It works like that: 

node vtscmd /import samples/Customers.csv /port 8888

The script can also carry out other useful tasks, such as empty a table:

node vtscmd /delete_data /port 8888

Or create another one:

node vtscmd /start /port 2000 /name table_one

The full command list: 

/help or /? Help

/start Start a new table (requires /port and /name)

/stop Delete a table (requires /port and /name)

/stop_all Delete all tables

/import Load data from a CSV file (requires /port)

/delete_data Empty a table (requires /port)

/list Display the list of existing tables

and parameters:

/port Table port

/name Table name. If the table name is not shown, then the main table is used

/delimiter Data separator in the CSV file. It is used in the /import command

/domain Domain for the NTML authorization

/username Username for the NTML authorization

/password Password for the NTML authorization

/cert It refers to the client certificate for authorization

/key It refers to the client key for authentication

The only problem with it is that it doesn’t work with a remote host. For this purpose we have to write scripts of our own. On the project we are using a java-utility that empties a table and imports a csv. The data is sent via a POST query, here are several examples:adding the data to a cell:

curl –data ‘key=&value=&id=&oper=edit’
http://server:port/data/edit_cell

emptying a table:

curl http://server:port/data/delete_all

finally here’s the most precious – csv import. The file path can be full or relative, but @ sign is necessary. Command run example from the folder with the file:

curl -F fileToUpload=@data.csv -H Accept:text/html,application/xhtml+xml,application/xml http://server:port/data/import_csv/

This requests are not working with the main table that is created by default. It’s needed to create one more table on a separate port and work with it.

Generally, if one expects that tables contain different sized columns, I recommend to create several tables in such a way that the data is comparable by size. For example, we create the first table with parameters with one value, the second table with parameters for 10 values and so on. Of course, all of this should be used without exaggerations. A bit later I’m going to show the LR functions – they are very useful to receive the whole parameter set, so it’s worth thinking about the data management.The queries can be turned into a full-fledged application and simply used from the Jenkins script.

LoadRunner Script

Another option to add data is a VUGen script. For this purpose a simple script is enough. To begin with let’s prepare the data: it needs to be saved in VTS as regular parameters. Then we write in the script the following:

char *VtsServer = “myVTSserver”;
int nPort = 8888;
int rc;
rc = lrvtc_connect(VtsServer,nPort,VTOPT_KEEP_ALIVE);
lr_log_message(“Connect result rc=%d\n”, rc);
rc = lrvtc_send_row1(“C_ID;C_info;C_credit”,
“{p_cid};{p_cid}_info;0”, “;”, VTSEND_SAME_ROW);
lr_log_message(“Send result rc=%d\n”, rc);

I recommend to check the data and/or the return value to prevent invalidated data or script failures. It’s especially important during the data reception – I received in some cases an empty line instead of the required value.

int rc;
int colSize;

colSize = lrvtc_column_size(“O_ID”);
rc = lrvtc_query_row(colSize);
if (strcmp(lr_eval_string(“{O_ID}”),””)) {
lr_exit(LR_EXIT_VUSER, LR_FAIL);
}
lr_log_message(“query_row rc=%d\n”, rc);
lr_log_message(“%s, %s, %s, %s”,
lr_eval_string(“{O_ID}”),
lr_eval_string(“{O_customerID}”),
lr_eval_string(“{O_info}”),
lr_eval_string(“{O_status}”));

Finally, don’t forget to close the connection after finishing working with the table:

rc = lrvtc_disconnect();
lr_log_message(“Disconnect result rc=%d\n”, rc);

Data communication

I’m going to explain several functions that I’m using in my work: lrvtc_query_row ( int index ) – it retrieves for the table all parameters that are located in the index row. Each column corresponds to a parameter with the same name that is saved as string. If there are no data in some cell, then NULL is written to the parameter.

lrvtc_query_column ( char *columnName, int rowIndex ) – it is the same function as previous, but it is applied to one column.

lrvtc_retrieve_row ( ) – it is analogous to the first function, but it saves all raw to the corresponding parameters. At the same time all the row is deleted from the table. All lower rows are lifted by a row.

lrvtc_retrieve_message ( char *columnName ) – it receives the first row value from the given column and deletes it from the table. All lower rows are lifted by a row.

lrvtc_retrieve_messages1 ( char *columnNames, char *delimiter ) – it is the same function, but it is applied to several columns. delimiter is a line or symbol that divides column names in the columnNames line.

lrvtc_rotate_row ( sendflag ) – it retrieves values from a row, deletes it from the first row and saves them to the last row. Here are the possible fag values: VTSEND_SAME_ROW – save the data to the same row. VTSEND_STACKED – save the data to a free cell on the table bottom. VTSEND_STACKED_UNIQUE – the data is only saved back to the table if it is unique, otherwise it is only saved in the parameters.

lrvtc_rotate_message ( columnName, sendflag ) – it is analogue to the previous functions, receives the data from a required column and reverts the column in the table. Flags: VTSEND_STACKED и VTSEND_STACKED_UNIQUE.

lrvtc_rotate_messages1 ( char *columnNames, char *delimiter, char *sendflag ) – it is functioning analogue to the previous functions. Flags as in lrvtc_rotate_row.

lrvtc_update_row1 ( char *columnNames, int rowIndex , char *values, char *delimiter ) – update the data in the indicated columns and line.

lrvtc_update_message ( char *columnName, int rowIndex , char *value ) – update the data in one cell with a required address.

lrvtc_update_message_ifequals ( char *columnName, int rowIndex , char *value, char *ifEqualValue ) – change the value at the indicated address if it equals ifEqualValue.

lrvtc_send_row1 ( char *columnNames, char *values, char *delimiter, unsigned char sendflag ) – save the data in the table under the indicated columns. delimiter can be a line or a symbol. Flags as in lrvtc_rotate_row.

lrvtc_send_message ( char *columnName, char *value ) – save the value in the end of the given column.

lrvtc_send_if_unique ( char *columnName, char *value ) – save the data in the end of the given columns, if it is unique.

It’s recommended to use indexes in order to optimize and speed up search for unique values in tables with many lines.

lrvtc_ensure_index ( char *columnName ) – creates an index in the given column. Locks the column during index creation, so that all operations on the given column are queued until the function finishes.

lrvtc_drop_index ( char *columnName ) – deletes a created index.

lrvtc_clear_row ( int rowIndex ) – the values in the given row will equal to an empty line. The row amount in the table stays the same.

lrvtc_clear_column ( char *column_name ) – empty a column.

lrvtc_clear_message ( char *columnName, int rowIndex ) – empty a cell. The cell is not deleted, but its value is set to an empty line. The row amount in the table stays the same.

Have a Project in Mind?​
We have been working on performance testing projects since 2008.
Drop us a line to find out what our team can do for you.
Get a quote You’ll hear back from our tech account manager in one day if not sooner

Known problems

On one hand, the ease of configuration and communication with LR are a big plus. On the other hand, there are a couple of things that I don’t quite like. First, spaces appear in the table in some cases. We’ve observed that while using rotate_xxx function. It seems that the server has got problems with processing concurrent queries from virtual users.Another issue is that there is no satisfactory API for initial data input and data deletion from the tables. I hope that there will be such functions in the next versions, but at the present we have to invent our own bicycles.

I recommend the described approach to everyone who still keeps a lot of same parameters in different scripts. Just don’t forget to check the received values.

Table of contents
Let us know about your needs
We can provide multiple performance testing services and a lot more than that if the situation needs a far more complex approach.
Get a quote You’ll hear back from our tech account manager in one day if not sooner

Related insights in blog articles

Explore what we’ve learned from these experiences
11 min read

Roles and Responsibilities of Performance Tester

performance testing roles and responsibilities in a nutshell
Apr 9, 2024

The core of efficient performance testing is an experienced, certified and well-structured team of professionals, who have already worked in similar projects, and learned all the peculiarities of QA testing types, and protocols.  If consciously chosen, they can evaluate a product, test its behavior under a load, check its response time, etc., and thus, empower […]

11 min read

Tips for Efficient Web Application Performance Testing

tips for efficient web application performance testing
Apr 4, 2024

Performance testing is one of the most challenging components of web application testing. But it is worth it: if done right, performance testing can forecast product behavior and its response to user’s actions with an impressive amount of detail and precision. Irrelevant web performance test data or wrong metrics chosen during testing cost companies a lot of money and effort, while not monitoring your web application performance at all can lead directly to a crash, say, on Black Friday, if you are not prepared to handle an increased number of concurrent users. Business or product owners needn’t know exactly how to performance test a website, but it’s useful to have a basic understanding of procedures that you pay for. From this post, you can learn what web application performance testing is, when it should be done, and how. Then, you will be able to make an informed choice whether to hire testing specialists or run testing sessions on your own.

15 min read

Top Tools for Developers in 2024

top developers tools
Apr 2, 2024

The ratings of the best software development tools are time-sensitive: new tools emerge every now and then. Monitoring and mastering them is a full-time job, and sometimes a waste of time, too, since some oldies but goldies remain chosen by the team.  Having done all the hard choices for you, we are sharing our list […]

4 min read

Big Data Europe 2024

software testing conferences preview
Mar 22, 2024

Big Data Conference Europe is a four-day conference with technical talks in the fields of AI, Cloud and Data. The conference will take place both on-site and online, providing the opportunity for everyone to participate in their preferred format.

  • Be first to know

    Once a month we’ll be sending you a letter with all the useful insights that we could find and analise