How do I correlate data like with Loadrunner?

Loadrunner has a function called web_reg_save_param that allows you to tell Loadrunner that you want it to save certain parts of the results of the next operation (HTTP transaction). In essence, you do:

web_reg_save_param("param", ...);

and then you request the URL you want to extract data from:

web_url(url);

And after that you will have the data stored in a parameter called "param", which you can then use in future requests.

Load Impact has the same functionality, but the actions are done in the opposite order - first you issue an HTTP request, get some results back, and then you apply various tools like regular expressions to extract data from the results you got.

So with Load Impact you perform the request first:

local response = http.request(url)

...and then you extract data from the result. There are several ways to extract a smaller piece of data from a larger one, but regular expressions are handy:

local m = regex.match(...)
local param = m:match(...)


Below is a commented example of a script that will load the main HTML page at loadimpact.com, extract a hidden cross-site request forgery (CSRF) token sent to it by the server, and then use that token in a subsequent request to perform a real user login. You can copy and paste it into a user scenario of your own and run it using the validation feature to see what happens.

More info:

--
-- Dynamic data correlation/extraction example user scenario
--
-- This user scenario code demonstrates how to look for certain data in an HTTP response
-- using regular expression matching. The extracted data can then be used in future requests,
-- typically to simulate CSRF (cross-site request forgery) tokens, session keys or similar
-- dynamic data the server wants included in requests for security or other reasons.
--

-- In this particular example, we load the Load Impact main HTML page, where there is
-- a cross-site request forgery token that we need to extract and include in later requests
-- in order to be able to do many things on the Load Impact site. We then issue a login request
-- without and then with the token, to demonstrate how the login works when the token
-- is present, but not when it isn't.


-- Step 1: First we issue an HTTP request to get some HTML content with the token in it
--
-- Note the use of 'response_body_bytes' to make sure we save the body content
--
log.info('Step 1: Executing GET http://loadimpact.com/')
local response = http.get({ url="http://loadimpact.com/", response_body_bytes=1000000 })


-- Step 2: Using the regex module to find the data we're interested in
--
-- Within the HTML, we want to find a CSRF token that looks like this:
-- CSRF_TOKEN='a14f956c63e19d35c2272d5d1e1a15cff1ba1f01'
-- To find it, we perform a regular expression search in the HTML, looking for "CSRF_TOKEN='x'"
-- where "x" is allowed to be any number of a-z characters or the numbers 0-9
--
local m = regex.match("CSRF_TOKEN='([a-z,0-9]+)'", response.body)


-- Print out some debug information
--
log.info('Step 2: Full string matched by regex: ' .. m:capture(1))
log.info('Step 2: CSRF token was: ' .. m:capture(2))


-- Step 3: Store the extracted string in a local variable for later use
--
local csrf_token = m:capture(2)


-- Step 4-5: build and send a login request.
--
-- We login as user "test@loadimpact.com" with password "test"
--
local login_url = 'https://loadimpact.com/account/signin'
local username = 'test@loadimpact.com'
local password = 'test1234'


-- Step 4: First we build a request that does NOT include the CSRF token, to see what happens
--
local post_data = 'email=' .. url.escape(username) .. '&password=' .. url.escape(password)

-- Then we send it
local response = http.post({
url=login_url,
data=post_data,
response_body_bytes = 1000000
})

-- Print out some debug info
--
log.info('Step 4: First POST returned status code ' .. tostring(response.status_code))
log.info('Step 4: Content-length is ' .. tostring(response.body_size))

-- When logged in at loadimpact.com, you get a "Sign out" link at the top of the page
-- This means we can verify if the login operation worked, by seeing if the returned
-- HTML contains the string "Sign out" or not
--
if string.find(response.body, 'Sign out') == nil then
log.info('Step 4: Login failed on our first attempt')
else
log.info('Step 4: Login succeeded on our first attempt')
end


-- Step 5: Then we build a request that includes the CSRF token
--
local post_data = 'email=' .. url.escape(username) .. '&password=' .. url.escape(password) ..
'&csrf=' .. csrf_token

-- Then we send it
local response = http.post({
url=login_url,
data=post_data,
response_body_bytes = 1000000
})

-- Print out some debug info
--
log.info('Step 5: Second POST returned status code ' .. tostring(response.status_code))
log.info('Step 5: Content-length is ' .. tostring(response.body_size))

-- And check if we are logged on or not
--
if string.find(response.body, 'Sign out') == nil then
log.info('Step 5: Login failed on our second attempt')
else
log.info('Step 5: Login succeeded on our second attempt')
end


Feedback and Knowledge Base