Learning center

The Load Impact load script API 1.2


Load script API version: 1.2


Introduction:
Load scripts are used to program the behaviour of simulated clients in a load test. Each user scenario has its own load script that determines exactly what objects the simulated user will load from the target site during the load test. Simulated users in a load test can run different user scenarios and load scripts, allowing the emulation of multiple user types in the same load test.

Load scripts are programs written using the high-level programming language Lua and can be very simple or very complex, depending on the requirements and programming skills of the tester.

Apart from native functionality of the Lua language, load script programmers can also use the Load Impact load script API to write their load scripts. This API consists of a subset of the Lua standard library, plus a number of Load Impact-specific functions and helper routines, all callable from within the Lua load script. This document describes all the API functionality available to the script programmer.







1. Client/VU module

This module contains functionality to control or extract information from the client that is currently executing.


    1.1. Client/VU module functions



      1.1.1. client.get_id()

      Description:
      Get the ID of the client who calls this function. The client ID is essentially just the number of the
      client out of all the clients running in the current load generator instance – i.e. in the current user scenario on the current load generator host. For example, you might have a test with 3 clients running user scenario X from Ashburn, Virginia, and 4 clients running the same scenario but from Dublin, Ireland. The clients in Ashburn will have the IDs 1, 2 and 3 and the clients in Dublin will have the IDs 1, 2, 3 and 4.

      Parameters
      [None]    

      Returns:
      integer or (nil, error message)




      1.1.2. client.get_repetition()

      Description:
      Get the current repetition (load script iteration) number of the client that calls the function.

      Parameters
      [None]    

      Returns:
      integer or (nil, error message)




      1.1.3. client.sleep(interval, [unit])

      Description:
      Pause client execution for interval * (1/unit) seconds.

      Parameters
      interval  number  The interval of unit time to sleep for
      unit number The unit of time to use. This parameter is optional – The default value is 1 (second)

      Returns:
      true or (nil, error message)




    1.2. Client/VU module examples

    Example 1a:

     -- Sleep client script for specified time
     client.sleep(2.5) -- Sleep for 2.5 seconds
     client.sleep(1, 1000) -- Sleep for 1 millisecond
     client.sleep(0.001) -- also sleep for 1 millisecond
    

    Example 1b:

     -- Get ID of client
     local client_id = client.get_id()
    








2. Datastore module

The Datastore module provides load scripts with API functionality to access predefined data stores, allowing easy data parameterization in load scripts. The load script programmer creates a named data store object in the Load Impact user scenario configuration interface, then uploads a text data file , in CSV format. The text data file should consist of a number of rows, where each row contains one or more column fields, separated by an arbitrary separator string (or character). The load script programmer is then able to use data store API functions to access the data store object, retrieving indivual rows from it. The rows retrieved will be returned as Lua tables.


    2.1. Datastore module functions



      2.1.1. datastore.open(name)

      Description:
      Initialize a data store object inside the load script. This function returns a data store object whose member functions can be used to access the data inside the data store.

      Parameters
      name string   The name of the data store we want to initialize. Currently, only one data store per user scenario is allowed, and the data store opened through the use of datastore.open() must be the one associated with the particular user scenario that is running.

      Returns:
      Datastore object or (nil, error message)


    2.2. Datastore object

    The Datastore object provides an instantiation of a named data store. The programmer can use member functions of the Datastore object to query the data store, or to retrieve data from it.



      2.2.1. Datastore:get(index)

      Description:
      Returns a specific row from the data store object. The data store object must first have been initialized through the use of datastore.open()

      Parameters
      index  integer  The row number to retrieve from the data store

      Returns:
      table or (nil, error message)



      2.2.2. Datastore:get_random([unique])

      Description:
      Returns a random row from the data store object. The optional parameter unique is a boolean that defaults to false, and which causes rows to only be returned once. I.e. repeated calls to get_random() with the unique parameter set to true will never return the same row from the data store more than once. Before using get_random(), the data store object must first have been initialized through the use of datastore.open()

      Note that the unique parameter only makes certain rows are unique within the same client thread execution context. I.e. client #1 and client #2 may get the same data if they both call get_random() using the unique flag.

      Parameters
      unique  boolean  controls whether the function should return unique rows or not. Defaults to false

      Returns:
      table or (nil, error message)




      2.2.3. Datastore:get_length()

      Description:
      Returns the number of rows in the data store. Before using get_length(), the data store object must first have been initialized through the use of datastore.open()

      Parameters
      [None]    

      Returns:
      integer or (nil, error message)




    2.3. Data store module examples

    Example 2a:

     -- Initialize the data store named "my data store"
    local ds = datastore.open("my data store")
    -- Fetch a random row from the data store
    local a_random_row = ds:get_random()
    -- Fetch row #43 from the data store
    local another_row = ds:get(43)
    

    For more examples on how to use data stores, see our FAQ section: How do I use parameterized data?








3. HTTP module

The HTTP module provides load scripts with an API to generate HTTP requests and handle HTTP responses.


    3.1. HTTP module classes




      3.1.1. Class http.Response

      The http.Response class is a data container class that contains information about a completed HTTP transaction.


      3.1.1.1. http.Response member data fields
      Name Type Description
      body string The HTTP response body
      body_size integer The size of the HTTP response body
      compressed boolean A boolean that indicates whether the body of the HTTP response was compressed or not
      compressed_body_size integer The size of the HTTP response body if the HTTP response body was compressed, otherwise -1
      connect_time number The time, in decimal seconds, it took to establish a TCP connection with the server
      content_type string The content type reported by the server in the HTTP response
      cookies  table  The cookies sent by the server in the HTTP response
      dns_lookup_time  number The time, in decimal seconds, it took to perform a hostname->IP lookup for the server host
      download_time  number The time, in decimal seconds, it took from reading the first byte of data and until the entire resource was downloaded from the server
      header_size integer  The size of the HTTP response headers
       headers table The HTTP response headers
      ip string The IP address of the host to which the request was sent
      redirect_time number The time, in decimal seconds, that was spent redirecting. This is the roundtrip time (RTT) for the HTTP messages. Excluding DNS lookup time and TCP connection time
      request_method  string The HTTP request method used by the original HTTP request that led to this HTTP response – can be “GET”, “POST”, “PUT”, “HEAD”, “DELETE”, “OPTIONS”, “TRACE
       request_size integer  The size of the sent HTTP request
      request_url string The URL of the original HTTP request that led to this response
      ssl_handshake_time number The time, in decimal seconds, it took to perform the SSL handshake for an HTTPS request
      status_code  integer The HTTP return status code
      status_messages  string  The HTTP return status line
      time_to_first_byte number The time, in decimal seconds, until the first byte of the HTTP response was received from the server
      total_load_time  number  The total load time for this resource
      url string The effective URL that the initial request ended up pointing to, after redirects




    3.2. HTTP module functions



      3.2.1. http.request(method, url, [ip, [headers, [data, [follow_redirects, [auto_decompress, [response_body_bytes, [base64_encoded_body]]]]]]])

      Transmit an HTTP request and wait for a response from the remote server. This function is blocking and will only return once the transfer has completed.

      Parameters
      method  string  The HTTP request method to use when sending the request. Can be any of “GET”, “POST”, “PUT”, “HEAD”, “DELETE”, “OPTIONS” or “TRACE
      url string The URL for the resource we are requesting
      ip string IP to connect to. This allows the script programmer to bypass DNS lookups for individual requests. It offers the same functionality as DNS.remap() but with more fine-grained control. This parameter is optional
      headers table A table of custom HTTP headers to send along with the request. This parameter is optional
      data string The body data of the request. Only valid for “POST” requests, this parameter is ignored for other request types. This parameter is optional.
      follow_redirects boolean If set to true, redirects will be handled automatically (the client will follow them). If set to false, any redirect will result in the completion of this request, which means that any subsequent requests that follow the redirect path have to be issued by the script programmer through new http.request() calls. This parameter is optional and defaults to true. The default value can also be changed through the use of the http.set_option() functionality.
       auto_decompress  boolean  If set to true, compressed content will be automatically decompressed upon reception. This parameter is optional and defaults to false.
       response_body_bytes  number  Specifies how many bytes of body data from the server’s reply to save. This parameter is optional and defaults to zero (0).
      base64_encoded_body boolean If set to true, indicates that the data parameter contains base64-encoded data



      Returns:
      http.Response or (nil, error message)




      3.2.2. http.request_batch(requests)

      Description:

      Performs a number of HTTP requests, using multiple concurrent TCP connections (when allowed to do so). This function is blocking and will only return once all transfers have been completed.

      Parameters
      requests  table  A table of requests to execute. Each request item is by itself a table containing http.request() parameters for the request



      Returns:
      a table with http.Response objects or (nil, error message)





      3.2.3. http.get(url, [ip, [headers, [follow_redirects, [auto_decompress, response_body_bytes]]]]])

      Transmit an HTTP GET request and wait for a response from the remote server. This function is blocking and will only return once the transfer has completed. This is a wrapper function around http.request()

      Parameters
      url string The URL for the resource we are requesting
      ip string IP to connect to. This allows the script programmer to bypass DNS lookups for individual requests. It offers the same functionality as DNS.remap() but with more fine-grained control. This parameter is optional
      headers table A table of custom HTTP headers to send along with the request. This parameter is optional
      follow_redirects boolean If set to true, redirects will be handled automatically (the client will follow them). If set to false, any redirect will result in the completion of this request, which means that any subsequent requests that follow the redirect path have to be issued by the script programmer through new http.request() calls. This parameter is optional and defaults to true. The default value can also be changed through the use of the http.set_option() functionality
       auto_decompress  boolean  If set to true, compressed content will be automatically decompressed upon reception. This parameter is optional and defaults to false.
       response_body_bytes  number  Specifies how many bytes of body data from the server’s reply to save. This parameter is optional and defaults to zero (0).



      Returns:
      http.Response or (nil, error message)




      3.2.4. http.post(url, [ip, [headers, [data, [follow_redirects, [auto_decompress, [response_body_bytes, [base64_encoded_body]]]]]]])

      Transmit an HTTP POST request and wait for a response from the remote server. This function is blocking and will only return once the transfer has completed. This is a wrapper function around http.request()

      Parameters
      url string The URL for the resource we are requesting
      ip string IP to connect to. This allows the script programmer to bypass DNS lookups for individual requests. It offers the same functionality as DNS.remap() but with more fine-grained control. This parameter is optional
      headers table A table of custom HTTP headers to send along with the request. This parameter is optional
      data string The body data of the request. Only valid for “POST” requests, this parameter is ignored for other request types. This parameter is optional.
      follow_redirects boolean If set to true, redirects will be handled automatically (the client will follow them). If set to false, any redirect will result in the completion of this request, which means that any subsequent requests that follow the redirect path have to be issued by the script programmer through new http.request() calls. This parameter is optional and defaults to true. The default value can also be changed through the use of the http.set_option() functionality.
       auto_decompress  boolean  If set to true, compressed content will be automatically decompressed upon reception. This parameter is optional and defaults to false.
       response_body_bytes  number  Specifies how many bytes of body data from the server’s reply to save. This parameter is optional and defaults to zero (0).
      base64_encoded_body boolean If set to true, indicates that the data parameter contains base64-encoded data



      Returns:
      http.Response or (nil, error message)




      3.2.5. http.head(url, [ip, [headers, [follow_redirects, [auto_decompress]]]])

      Transmit an HTTP HEAD request and wait for a response from the remote server. This function is blocking and will only return once the transfer has completed. This is a wrapper function around http.request()

      Parameters
      url string The URL for the resource we are requesting
      ip string IP to connect to. This allows the script programmer to bypass DNS lookups for individual requests. It offers the same functionality as DNS.remap() but with more fine-grained control. This parameter is optional
      headers table A table of custom HTTP headers to send along with the request. This parameter is optional
      follow_redirects boolean If set to true, redirects will be handled automatically (the client will follow them). If set to false, any redirect will result in the completion of this request, which means that any subsequent requests that follow the redirect path have to be issued by the script programmer through new http.request() calls. This parameter is optional and defaults to true. The default value can also be changed through the use of the http.set_option() functionality.
       auto_decompress  boolean  If set to true, compressed content will be automatically decompressed upon reception. This parameter is optional and defaults to false.



      Returns:
      http.Response or (nil, error message)




      3.2.6. http.options(url, [ip, [headers, [follow_redirects, [auto_decompress, [response_body_bytes]]]]])

      Transmit an HTTP OPTIONS request and wait for a response from the remote server. This function is blocking and will only return once the transfer has completed. This is a wrapper function around http.request()

      Parameters
      url string The URL for the resource we are requesting
      ip string IP to connect to. This allows the script programmer to bypass DNS lookups for individual requests. It offers the same functionality as DNS.remap() but with more fine-grained control. This parameter is optional
      headers table A table of custom HTTP headers to send along with the request. This parameter is optional
      follow_redirects boolean If set to true, redirects will be handled automatically (the client will follow them). If set to false, any redirect will result in the completion of this request, which means that any subsequent requests that follow the redirect path have to be issued by the script programmer through new http.request() calls. This parameter is optional and defaults to true. The default value can also be changed through the use of the http.set_option() functionality.
       auto_decompress  boolean  If set to true, compressed content will be automatically decompressed upon reception. This parameter is optional and defaults to false.
       response_body_bytes  number  Specifies how many bytes of body data from the server’s reply to save. This parameter is optional and defaults to zero (0).



      Returns:
      http.Response or (nil, error message)




      3.2.7. http.put(url, [ip, [headers, [data, [follow_redirects, [auto_decompress, [response_body_bytes, [base64_encoded_body]]]]]]])

      Transmit an HTTP PUT request and wait for a response from the remote server. This function is blocking and will only return once the transfer has completed. This is a wrapper function around http.request()

      Parameters
      url string The URL for the resource we are requesting
      ip string IP to connect to. This allows the script programmer to bypass DNS lookups for individual requests. It offers the same functionality as DNS.remap() but with more fine-grained control. This parameter is optional
      headers table A table of custom HTTP headers to send along with the request. This parameter is optional
      data string The body data of the request. Only valid for “POST” requests, this parameter is ignored for other request types. This parameter is optional.
      follow_redirects boolean If set to true, redirects will be handled automatically (the client will follow them). If set to false, any redirect will result in the completion of this request, which means that any subsequent requests that follow the redirect path have to be issued by the script programmer through new http.request() calls. This parameter is optional and defaults to true.
       auto_decompress  boolean  If set to true, compressed content will be automatically decompressed upon reception. This parameter is optional and defaults to false. The default value can also be changed through the use of the http.set_option() functionality.
       response_body_bytes  number  Specifies how many bytes of body data from the server’s reply to save. This parameter is optional and defaults to zero (0).
      base64_encoded_body boolean If set to true, indicates that the data parameter contains base64-encoded data



      Returns:
      http.Response or (nil, error message)




      3.2.8. http.trace(url, [ip, [headers, [follow_redirects, [auto_decompress, [response_body_bytes]]]]])

      Transmit an HTTP TRACE request and wait for a response from the remote server. This function is blocking and will only return once the transfer has completed. This is a wrapper function around http.request()

      Parameters
      url string The URL for the resource we are requesting
      ip string IP to connect to. This allows the script programmer to bypass DNS lookups for individual requests. It offers the same functionality as DNS.remap() but with more fine-grained control. This parameter is optional
      headers table A table of custom HTTP headers to send along with the request. This parameter is optional
      follow_redirects boolean If set to true, redirects will be handled automatically (the client will follow them). If set to false, any redirect will result in the completion of this request, which means that any subsequent requests that follow the redirect path have to be issued by the script programmer through new http.request() calls. This parameter is optional and defaults to true. The default value can also be changed through the use of the http.set_option() functionality.
       auto_decompress  boolean  If set to true, compressed content will be automatically decompressed upon reception. This parameter is optional and defaults to false.
       response_body_bytes  number  Specifies how many bytes of body data from the server’s reply to save. This parameter is optional and defaults to zero (0).



      Returns:
      http.Response or (nil, error message)




      3.2.9. http.set_option(name, value)

      Set a default behaviour for all future HTTP requests. The option set can usually be overridden in an individual HTTP request, when necessary.

      Note: this is not to be confused with the http.options() function, which is used to transmit HTTP OPTIONS requests

      Parameters
      name string The name of the option we want to set
      value mixed The option value

      The following option names are recognized:

      Name Description
      follow_redirects  Boolean. If set to true it makes the client follow redirects by default. Whatever is set here can be overridden for each individual HTTP request by using the follow_redirects parameter of the http.request() family of functions
       redirect_post_302  Boolean. If set to true, the client will, upon encountering a 302 response for a POST request, redirect its request in unaltered form – i.e. as a POST. The default value for this option is false, which means that clients will change redirected POST requests into GET requests (if the redirect code from the server was 302). The default behaviour – i.e. changing redirected POST requests into GET requests – is the more common one among browsers. Note also that if the client is instructed not to follow redirects automatically (through the use of the follow_redirects option) this option has no effect.



      Returns:
      true or (nil, error message)




      3.2.10. http.set_max_connections(max_connections, max_connections_per_host)

      Sets the maximum number of connections a single client may have open at any one time. Note that this setting is mostly interesting if the load test was configured to use SBU (simulated browser users) clients that may have multiple TCP connections open simultaneously. The other type of client – the VU – can only have one single connection open at a time, so for them the only possible parameter values are 1 (one) or 0 (zero).

      Note that this function used to be called ua.set_max_connections() in API version 1.0

      Parameters
      max_connections integer The total maximum number of concurrent TCP connections that the client may open during script execution
      max_connections_per_host integer The total maximum number of concurrent TCP connections that the client may open to a specific host during script execution



      Returns:
      true or (nil, error message)




      3.2.11. http.set_user_agent_string(ua_string)

      Sets the User-Agent HTTP header used by the simulated client in all subsequent HTTP requests.

      Note that this function used to be called ua.set_string() in API version 1.0

      Parameters
      ua_string string The User-Agent string the client should use



      Returns:
      true or (nil, error message)




    3.3. HTTP module examples

    Example 3a:

     -- Execute a batch of HTTP requests, set special HTTP headers in some of them
     responses = http.request_batch({
        { "GET", "http://loadimpact.com", nil, { ["X-Myheader"]="Something" } },
        { "GET", "http://loadimpact.com/image1.jpg" },
        { "POST", "http://loadimpact.com/login_ajax.php", nil, { ["X-Anotherheader"]="Something Else" }, "login=test&password=test" }
     })
    

    Example 3b:

     -- Make a a single HTTP request and use the response data
     response = http.request("GET", "http://loadimpact.com", nil, { ["X-Myheader"]="Something" })
     -- An equivalent request could also be made using the shorthand http.get() function:
     response = http.get("http://loadimpact.com", nil, { ["X-Myheader"]="Something" })
     -- Display some response data in the console log:
     log.info("DNS lookup time: " .. response.dns_lookup_time)
     -- and store some response data as our own, custom metric that we can create graphs from:
     result.custom_metric("time_to_first_byte", response.time_to_first_byte) 
    

    Example 3c: emulating IE6

     -- IE6 uses max 34 connections in total, and max 2 per host (*)
     http.set_max_connections(34, 2)
     -- Use the IE6 User-Agent string
     http.set_user_agent_string("Mozilla/5.0 (compatible; MSIE 6.0; Windows NT 5.1)")</i>
    

    (*) see browserscope.org for more details about unique browser behaviour that affects performance








4. Log module

The log module provides load scripts with an API to store log messages during execution. Log messages will be visible in the log window when a load test is executing (or after the test is finished). Note that rotating buffers are used to buffer and, sometimes, store log messages, so only a finite number of messages can be stored for a single load test. It is good to try and limit the number of log messages you write – for example by having only one of your clients log things (see code examples below).


    4.1. Log module functions




    4.2. Log module examples

    Example 4a:

     -- Add an entry to the log
     log.info("Hello world!")
    

    Example 4b:

     -- Have only client #1 add an entry to the log
     -- This can be very useful if you run a load test with 1,000 simulated clients and
     -- want to avoid getting your log swamped with 1,000 copies of the same log message
     if client.get_id() == 1 then log.info("Hello world!")
    








5. Result module

The result module contains functionality for controlling the aggregation and storage of measurement data. For example, the result.custom_metric() function allows you to store arbitrary result metrics during your load test.


    5.1. Result module functions



      5.1.1. result.custom_metric(name, value, [priority, [friendly_name]])

      This function allows you to store your own, custom result metrics. You can create any metrics you like, give them a name, and use this function to store result values for them throughout your load test. You will then be able to plot graphs of those results, or export them to CSV files, just like you can with any of our standard metrics.

      Parameters
      name string The name of your result metric. This is used to correlate all results of the same kind. It is case-sensitive and can be max 32 characters long.
       value number  An individual measurement value (sample point) for the metric. Store as many of these as you like, but be aware that results are aggregated every 3 seconds. This means that if you store e.g. 5 individual values per second, totaling 15 values in 3 seconds, the system will compute a min, max and average value from your 15 values and then store those three values as the sample point for the 3-second interval.
       priority integer  This parameter has no function in the current API version, you can safely ignore it
       friendly_name string  This parameter has no function in the current API version, you can safely ignore it



      Returns:
      true or (nil, error message)




    5.2. Result module examples

    Example 5a:

     -- Measure the time it takes to complete several HTTP requests, 
     -- and then store that time as the result metric "total_load_time"
     start_time = util.time()
     http.request_batch({
        { "GET", "http://loadimpact.com", nil, { ["X-Myheader"]="Something" } },
        { "GET", "http://loadimpact.com/image1.jpg" },
        { "POST", "http://loadimpact.com/login_ajax.php", nil, { ["X-Anotherheader"]="Something Else" }, "login=test&password=test" }
     })
     end_time = util.time()
     result.custom_metric("total_load_time", end_time - start_time)
    








6. Test module

The test module provides load scripts with an API to access test-wide settings and data.


    6.1. Test module functions



      6.1.1. test.get_repetitions()

      Get the total number of repetitions configured for the current test. I.e. how many times each client is supposed to iterate through the load script.

      NOTE: This function is obsolete

      Parameters
      None



      Returns:
      integer or (nil, error message)









7. Util module

The Util module contains miscellaneous functionality that can be useful in a load script, such as time functions etc.


    7.1. Util module functions



      7.1.1. util.dns_remap(host, ip)

      Description:
      Adds an entry to a hostname lookup table that will be checked before querying DNS when the client needs to lookup a hostname.

      Note: this function used to be called dns.remap() in API version 1.0

      Parameters
      host  string  The hostname to store a lookup table entry for
      ip string The IP address that the hostname should resolve to

      Returns:
      true or (nil, error message)




      7.1.2. util.time()

      Description:
      The time() function returns the number of seconds since Unix EPOCH as a number value, which means it includes fractional seconds with fairly high (microsecond-) precision. If you are a programmer with previous Lua experience, you can think of util.time() as a higher-precision version of the Lua standard os.time() function.

      Parameters
      None  

      Returns:
      number




    7.2. Util module examples

    Example 7a:

     -- Make sure clients that load things from loadimpact.com connects to 123.123.123.123
     util.dns_remap("loadimpact.com", "123.123.123.123")
    

    Example 7b:


     -- Find out how long it took to perform a sequence of requests
     starttime = util.time()
     http.request_batch({
        { "GET", "http://loadimpact.com" },
        { "GET", "http://loadimpact.com/image1.jpg" },
        { "GET", "http://loadimpact.com/image2.jpg" },
     })
     http.request_batch({
        { "GET", "http://loadimpact.com/page2/image3.jpg" },
        { "GET", "http://loadimpact.com/page2/image4.jpg" },
     })
     endtime = util.time()
     elapsed_time = endtime - starttime
    








8. Standard library modules/functions

The following standard Lua library modules and functions are also available for use in load scripts.