JMeter - Strange Behavior when Variables used in CookieManager - jmeter

JMeter Version 2.13 r1665067
So I seem to be having some trouble when using User-Defined Variables and/or JMeter Property Variables inside a CookieManager.
If I use a variable as the value for a Cookie inside the CookieManager, whether or not it's a User-Defined Var or a Property Var I have the same problem when trying to view the Cookie's value(s) inside a BeanShell Pre and PostProcessor.
If my Cookie Manager has this below: *The 1st line is when using properties variable and 2nd line is when using a var from a User Defined Variable, *FYI both lines are NOT used at the same time:
CookieManager:
NAME VALUE DOMAIN PATH
1st) MYID ${__P(propCookie)} www.mydomain.com /
OR
2nd) MYID ${userCookie} www.mydomain.com /
The propCookie variable is passed on the CLI or defined in a .properties file like below:
COMMAND-LINE --> -JpropCookie=SRV1
IN PROP FILE --> propCookie=SRV1
And the userCookie variable is defined inside a User Defined Variables Config Element like so:
NAME VALUE DESCRIPTION
userCookie ${__P(propCookie)} User var using prop variable as value
Then, when I run my test I can see in the Request Tab of the Results Tree that it is showing the Cookie and it has the correct value assigned to it, which is good... But when I attempt to view the Cookies in a BeanShell Pre/Post-Processor, it simply shows the Variable and NOT the actual value.
BeanShell PreProcessor Code
import org.apache.jmeter.protocol.http.control.Cookie;
import org.apache.jmeter.protocol.http.control.CookieManager;
log.info("### Inside BeanShell PreProcessor:");
CookieManager manager = sampler.getCookieManager();
log.info("Cookie Count = '" + manager.getCookieCount() + "'");
for (int i = 0; i < manager.getCookieCount(); i++) {
Cookie cookie = manager.get(i);
log.info("\t\t Cookie.getName() = '" + cookie.getName() + "'");
log.info("\t\t Cookie.getValue() = '" + cookie.getValue() + "'");
}
Here is the BeanShell Script's Output in the Log:
2015/04/29 14:33:00 INFO - jmeter.util.BeanShellTestElement: ### Inside BeanShell PreProcessor:
2015/04/29 14:45:58 INFO - jmeter.util.BeanShellTestElement: Cookie Count = '1'
2015/04/29 14:33:00 INFO - jmeter.util.BeanShellTestElement: Cookie.getName() = 'MYID'
2015/04/29 14:33:00 INFO - jmeter.util.BeanShellTestElement: Cookie.getValue() = '${userCookie}'
So as you can see in the output from the BeanShell, the getValue() function is printing the Variable assigned to the Cookie's value exactly like this --> "${userCookie}", and NOT what the actual Cookie's value is, which is "SRV1"...
Lastly, if I try to use the "COOKIE_" variable which is supposed to get automatically created, and I use this in BeanShell, vars.get("COOKIE_MYID"), it prints "null" every time... I have all the proper Cookie properties set in the jmeter.properties file, like these here, so I'm not sure what the problem is:
CookieManager.allow_variable_cookies=true
CookieManager.save.cookies=true
CookieManager.name.prefix=COOKIE_
I'm pretty much stumped for why this is happening so if anyone has any ideas for why this is happening, please feel free it would be greatly appreciated!
Thanks in Advance,
Matt

HTTP Request Sampler actually sets the cookie using CookieManager's getCookieHeaderForURL method which substitutes the value properly.
In Beanshell,
import org.apache.jmeter.protocol.http.control.Cookie;
import org.apache.jmeter.protocol.http.control.CookieManager;
manager = sampler.getCookieManager();
log.info(manager.getCookieHeaderForURL(new URL("http://www.google.com"))); //update the URL
This gives the cookies with updated values.
CookieManager's get & add methods are used to get & add cookies to the HTTP Cookie Manager at run time. So, getValue method gives the value as it is. getCookieHeaderForURL gets the appropriate cookies from the Cookie Manager for the domain with updated values.

Related

how save value in string variable by Javascript executor in jmeter web sampler

Hi I want to store the value return by below code in JMeter webDriver Sampler . but i am getting error.
String access_token = WDS.browser.executeScript("return window.localStorage.getItem(localStorage.key(2))");
WDS.log.info("access_token : " + access_token);
OR
var access_token = WDS.browser.executeScript("return window.localStorage.getItem(localStorage.key(2))");
WDS.log.info("access_token : " + access_token);
Both above ways are not working?
In order to be able to help we need to know the details of the error "you are getting". Also it's unclear what localStorage.key(2) object stands for.
Here is an example of getting se:fkey value from https://stackoverflow.com website:
I used default language for WebDriver Sampler: javascript and the following piece of code:
WDS.sampleResult.sampleStart()
WDS.browser.get('https://stackoverflow.com')
var access_token = WDS.browser.executeScript('return window.localStorage.getItem("se:fkey")')
WDS.log.info('Got the following value from local storage: ' + access_token)
WDS.sampleResult.sampleEnd()
And it works just fine:
If you additionally need to store the value into a JMeter Variable add the following line:
WDS.vars.put('access_token', access_token)
and you will be able to access the extracted value as ${access_token} where required.
More information: The WebDriver Sampler: Your Top 10 Questions Answered

Can we pass the beanshell assertion variable (in a thread) to cookie manager user defined variable (outside the thread) in jmeter?

Can we pass the beanshell assertion variable (in a thread) to cookie manager user defined variable (outside the thread) in jmeter ?
This is the image of user defined cookies which are been used on my request
This is bean shell variable
I don't think it will work this way, you can use something like:
In "init" thread group:
import org.apache.jmeter.protocol.http.control.CookieManager;
CookieManager manager = ctx.getCurrentSampler().getProperty("HTTPSampler.cookie_manager").getObjectValue();
props.put("cookiecount",String.valueOf(manager.getCookieCount()));
for (int i=0;i<manager.getCookieCount();i++){
// code to convert Cookie information to JMeter Properties
props.put("cookie_name_" + i, manager.get(i).getName());
//…..
}
In "Action" thread group:
import org.apache.jmeter.protocol.http.control.CookieManager;
import org.apache.jmeter.protocol.http.control.Cookie;
import org.apache.jmeter.testelement.property.JMeterProperty;
CookieManager manager = ctx.getCurrentSampler().getProperty("HTTPSampler.cookie_manager").getObjectValue();
int count = Integer.parseInt(props.getProperty("cookiecount"));
for (int i=0;i<count;i++) {
Cookie cookie = new Cookie(props.getProperty("cookie_name"+i),props.getProperty("cookie_value"+i), props.getProperty("cookie_domain"+i),props.getProperty("cookie_path"+i), Boolean.parseBoolean(props.getProperty("cookie_secure"+i)), Long.parseLong(props.getProperty("cookie_expires"+i)));
manager.add(cookie);
}
JMeterProperty cookieprop = ctx.getCurrentSampler().getProperty("HTTPSampler.cookie_manager");
cookieprop.setObjectValue(manager);
ctx.getCurrentSampler().setProperty(myprop);
Instead of having global HTTP Cookie Manager it is better to use 2 (or 3) separate ones local to the Thread Groups.
Consider moving to JSR223 Assertion and Groovy language as Beanshell performance might be a big question mark in case of high loads. See Scripting JMeter Assertions in Groovy - A Tutorial article for more details.

JMeter: Extracting and passing Transaction controller name in JMeter test plan

In my JMeter test plan, i have 3 transaction controllers.
I want to extract the transaction controller name and pass it to the Jmeter script.
I am unable to extract the transaction controller name, which is displayed into "Log viewer Panel".
To print transaction name , i have used BeanShell Listener, with following code :
String tname= sampleResult.toString();
if(tname.startsWith("T01_Login"))
{
log.info("*Transaction Name = " +sampleResult.toString() + " - Response time = " + sampleResult.getTime());
String temp = sampleResult.toString();
String temp2 = sampleResult.getTime().toString();
vars.put("Transaction_Name",temp);
vars.put("Response", temp2);
log.info(vars.get("Response"));
log.info(vars.get("Transaction_Name"));
}
I have used BSF post processor to store/extract the transaction name, by using following code:
Language selected in : Javascript
var transact = ${Transaction_Name};
vars.put ("TRANSACT",transact);
log.info(TRANSACT);
When checked into LogViewer panel, following text is displayed:
2017/03/27 17:06:13 INFO - jmeter.util.BeanShellTestElement: *Transaction Name = T01_Login - Response time = 39829
2017/03/27 17:06:13 INFO - jmeter.util.BeanShellTestElement: 39829
2017/03/27 17:06:13 INFO - jmeter.util.BeanShellTestElement: T01_Login
Kindly provide your valuable suggestion on this.
To resolve the error which prevents post-processor from running, use vars.get, instead of var transact = ${Transaction_Name};, i.e.
var transact = vars.get("Transaction_Name");
And setting another variable (vars.put ("TRANSACT",transact);) is unnecessary: just use Transaction_Name. (And another small note: BSF set of objects is now deprecated, so switch them to either JSR322 or BeanShell)
But it will not work anyways, because the order of execution is
Sampler > Post-processor > Listener > Transaction Controller > Listener
So the value of Transaction_Name inside post-processor will either be empty (on first iteration), or will be coming from previous iteration, which I guess is not what you want.
You don't mention your use case, but some options you have are:
Have a special sampler AFTER transaction controller to do what you wanted in that post-processor. For example:
Transaction Controller
Some Sampler
...
JSR223 / Beanshell sampler
This second sampler can obtain proper transaction name, since it's running after the transaction
Save transaction name into variable before calling a transaction. Set transaction controller name to that variable:
JSR223 / Beanshell sampler
sets variable: vars.put("Transaction_Name", "T01_Login");
${Transaction_Name} <-- this is the name of the transaction controller
Sampler
Post-processor <-- here the Transaction_Name can be obtained.

JMeter: doesn't increment counter value

I'm working on a load test for Eclipse RAP-based application in JMeter. I need to replace requestCounter in each http request with variable. Variable should be incremented by 1 in next requests.
Tried to use JMeter's __counter function ${__counter(FALSE)} for my ${COUNTER} variable:
1) in User Defined Variables (didn't increment counter http://screencast.com/t/5MP1ovdHJN5p),
2) in CSV Data Set (function body was inserted instead of number http://screencast.com/t/mUIaYF3Oc).
Replaced ${__counter(FALSE)} with ${__javaScript(${__counter(FALSE)})} - still no success.
3) Counter config element brings the same result as User Defined Variable - not incrementing value for next request.
Plan:
+Thread_group
+Counter config element/User Defined Variables/CSV Data Set
+Request group
++ HTTP request1: {"head":{"requestCounter":${COUNTER}} #should be 1
++ HTTP request2: {"head":{"requestCounter":${COUNTER}} #should be 2
++ HTTP request2: {"head":{"requestCounter":${COUNTER}} #should be 3
...
Any suggestions?
you don't need to update the request counter manually. For RAP 2.1+ we updated the Wiki with the current info about load testing:
https://wiki.eclipse.org/RAP/LoadTesting

Sending An HTTP Request using Intersystems Cache

I have the following Business Process defined within a Production on an Intersystems Cache Installation
/// Makes a call to Merlin based on the message sent to it from the pre-processor
Class sgh.Process.MerlinProcessor Extends Ens.BusinessProcess [ ClassType = persistent, ProcedureBlock ]
{
Property WorkingDirectory As %String;
Property WebServer As %String;
Property CacheServer As %String;
Property Port As %String;
Property Location As %String;
Parameter SETTINGS = "WorkingDirectory,WebServer,Location,Port,CacheServer";
Method OnRequest(pRequest As sgh.Message.MerlinTransmissionRequest, Output pResponse As Ens.Response) As %Status
{
Set tSC=$$$OK
Do ##class(sgh.Utils.Debug).LogDebugMsg("Packaging an HTTP request for Saved form "_pRequest.DateTimeSaved)
Set dateTimeSaved = pRequest.DateTimeSaved
Set patientId = pRequest.PatientId
Set latestDateTimeSaved = pRequest.LatestDateTimeSaved
Set formName = pRequest.FormName
Set formId = pRequest.FormId
Set episodeNumber = pRequest.EpisodeNumber
Set sentElectronically = pRequest.SentElectronically
Set styleSheet = pRequest.PrintName
Do ##class(sgh.Utils.Debug).LogDebugMsg("Creating HTTP Request Class")
set HTTPReq = ##class(%Net.HttpRequest).%New()
Set HTTPReq.Server = ..WebServer
Set HTTPReq.Port = ..Port
do HTTPReq.InsertParam("DateTimeSaved",dateTimeSaved)
do HTTPReq.InsertParam("HospitalNumber",patientId)
do HTTPReq.InsertParam("Episode",episodeNumber)
do HTTPReq.InsertParam("Stylesheet",styleSheet)
do HTTPReq.InsertParam("Server",..CacheServer)
Set Status = HTTPReq.Post(..Location,0) Quit:$$$ISERR(tSC)
Do ##class(sgh.Utils.Debug).LogDebugMsg("Sent the following request: "_Status)
Quit tSC
}
}
The thing is when I check the debug value (which is defined as a global) all I get is the number '1' - I have no idea therefore if the request has succeeded or even what is wrong (if it has not)
What do I need to do to find out
A) What is the actual web call being made?
B) What the response is?
There is a really slick way to get the answer the two questions you've asked, regardless of where you're using the code. Check the documentation out on the %Net.HttpRequest object here: http://docs.intersystems.com/ens20102/csp/docbook/DocBook.UI.Page.cls?KEY=GNET_http and the class reference here: http://docs.intersystems.com/ens20102/csp/documatic/%25CSP.Documatic.cls?APP=1&LIBRARY=ENSLIB&CLASSNAME=%25Net.HttpRequest
The class reference for the Post method has a parameter called test, that will do what you're looking for. Here's the excerpt:
method Post(location As %String = "", test As %Integer = 0, reset As %Boolean = 1) as %Status
Issue the Http 'post' request, this is used to send data to the web server such as the results of a form, or upload a file. If this completes correctly the response to this request will be in the HttpResponse. The location is the url to request, e.g. '/test.html'. This can contain parameters which are assumed to be already URL escaped, e.g. '/test.html?PARAM=%25VALUE' sets PARAM to %VALUE. If test is 1 then instead of connecting to a remote machine it will just output what it would have send to the web server to the current device, if test is 2 then it will output the response to the current device after the Post. This can be used to check that it will send what you are expecting. This calls Reset automatically after reading the response, except in test=1 mode or if reset=0.
I recommend moving this code to a test routine to view the output properly in terminal. It would look something like this:
// To view the REQUEST you are sending
Set sc = request.Post("/someserver/servlet/webmethod",1)
// To view the RESPONSE you are receiving
Set sc = request.Post("/someserver/servlet/webmethod",2)
// You could also do something like this to parse your RESPONSE stream
Write request.HttpResponse.Data.Read()
I believe the answer you want to A) is in the Server and Location properties of your %Net.HttpRequest object (e.g., HTTPReq.Server and HTTPReq.Location).
For B), the response information should be in the %Net.HttpResponse object stored in the HttpResponse property (e.g. HTTPReq.HttpResponse) after your call is completed.
I hope this helps!
-Derek
(edited for formatting)
From that code sample it looks like you're using Ensemble, not straight-up Cache.
In that case you should be doing this HTTP call in a Business Operation that uses the HTTP Outbound Adapter, not in your Business Process.
See this link for more info on HTTP Adapters:
http://docs.intersystems.com/ens20102/csp/docbook/DocBook.UI.Page.cls?KEY=EHTP
You should also look into how to use the Ensemble Message Browser. That should help with your logging needs.

Resources