How to get value from property in BeanShell (jmeter) - variables

I have got several thread groups. I want to use variable from the first group. In second group this var should be used in BeanShell.
So: in first thread group I created BeanShell Assertion with this code:
${__setProperty(erroriden, ${erroriden1})};
In second thread group I have BeanShell pre-processor.
If has line like this:
String[] erroriden = (vars.get("erroriden")).split(",");
I tried some variations like this:
String[] erroriden = (vars.get("__property(erroriden)")).split(",");
String[] erroriden = (vars.get("${__property(erroriden)}")).split(",");
but it doesn't work.
Please help to use ${__property(erroriden)} in BeanShell pre-processor.

In the first Thread Group:
props.put("erroriden", vars.get("erroriden1"));
In the second Thread Group:
String[] erroriden = props.get("erroriden").split(",");
JMeterVariables scope is limited to the current thread group only
JMeter Properties are usual Java Properties which are global for JVM instance
See How to use BeanShell: JMeter's favorite built-in component guide for more information on using Beanshell in JMeter.

Related

Flowable - concat dynamic variable and a string in http task (url)

I need to convert the base url according to the production and other environments.
I am using script task before a http task to perform this logic.
baseUrl = http://localhost:8080
baseUrl, is the output of the script task. Now I need to add this base url as a prefix in http task url
Url = ${baseUrl}/application/find (something like this).
I am getting the following issue
Unknown Property used in the expression ${baseUrl}/application/find
Script
var env = execution.getVariable("env")
if(env == "prod") {
var baseUrl = "http://localhost:8080";
execution.setVariable("baseUrl", baseUrl);
}
Please assist.
This typically means that it is unable to find a property in the expression (as the message says). The only expression you are using is baseUrl which means that the issue is around the baseUrl. The concatenation as you have done it is correct and doesn't need to have an adaption.
You should check if the variable really exists, this you can do by introducing a wait state before your HTTP task and check afterwards if the variable is created. Rather than using outputs, you can also use the Java API in your script task to create the variable:
execution.setVariable("baseUrl", "http://localhost:8080");
Assuming you are using Spring Boot, for your specific use-case it would be also an option to use the application.properties to specify your base-url and then refer to the baseUrl with the following expression:
${environment.getProperty("baseUrl")}/application/find
This will allow you to change the baseUrl independent of your process definition.

How to set variables to custom function in Jmeter?

I have a basic function in BeanShellSampler.bshrc at Jmeter 4.0
String getMyString(String strParam) {
return "MyString: "+strParam;
}
I called in BeanShell Sampler as below
String N = "123123";
log.info("${__BeanShell(getMyString("${__V(Var${N})}"),)}");
When I run Sampler output is somthing like that.
2018-06-18 15:25:40,080 INFO o.a.j.u.BeanShellTestElement: MyString: Var${N}
How can I set string variable to my function?
I read function articles in Jmeter web site
Thank you.
Add the next line to user.properties file:
beanshell.sampler.init=BeanShellSampler.bshrc
Amend your code to look like:
String N = "123123";
log.info(getMyString(N));
That's it, you should get MyString: 123123 in jmeter.log file
Be aware that starting from Jmeter 3.1 it is recommended to use Groovy for all forms of scripting as Groovy performance is much better comparing to Beanshell so consider taking the following steps instead:
Create a file, i.e. foo.groovy in "bin" folder of your JMeter installation and put your function there:
String getMyString(String strParam) {
return "MyString: " + strParam;
}
Add the next line to user.properties file:
You should be able to refer your custom code from __groovy() function like:
${__groovy(log.info(getMyString("123123")),)}
functions can be used anywhere in the Test Plan
For each BeanShell Program type there are different beanshell.*.init properties defined in bin/user.properties
beanshell.function.init=BeanShellFunction.bshrc
beanshell.preprocessor.init=BeanShellSampler.bshrc
beanshell.postprocessor.init=BeanShellSampler.bshrc
beanshell.assertion.init=BeanShellFunction.bshrc
Hence the same function which needs to be called from any program(preprocessor, postprocessor, etc) we need to copy the function to every .bshrc file OR use same .bshrc file for every program init property.
In your case if you are using local string variable N and passing it along with the script. If you use ${Variable} there must be a JMeter variable defined so that JMeter can pick its value. To do that you can use vars.put , write N value to JMeter variables and use ${N} .
I have defined Var123123 value as FinalValue as shown below
And 2 beanshell samplers one is to put String variable N to Jmeter variable and one is beanshell script as shown below
You can see in the log its printed VAR123123's value which is FinalValue
The reason why i took 2 beashell samplers is if i write N to JMeter variables and use it in same script its not updating N value until the sampler executed..
References :
Configuring JMeter
JMeter Beanshell
Please let me know if it helps

Activiti BPMN - How to pass username in variables/expression who have completed task?

I am very new to Activiti BPMN. I am creating a flow diagram in activiti. I m looking for how username (who has completed the task) can be pass into shell task arguments. so that I can fetch and save in db that user who has completed that task.
Any Help would be highly appreciated.
Thanks in advance...
Here's something I prepared for Java developers based on I think a blog post I saw
edit: https://community.alfresco.com/thread/224336-result-variable-in-javadelegate
RESULT VARIABLE
Option (1) – use expression language (EL) in the XML
<serviceTask id="serviceTask"
activiti:expression="#{myService.toUpperCase(myVar)}"
activiti:resultVariable="myVar" />
Java
public class MyService {
public String toUpperCase(String val) {
return val.toUpperCase();
}
}
The returned String is assigned to activiti:resultVariable
HACKING THE DATA MODEL DIRECTLY
Option (2) – use the execution environment
Java
public class MyService implements JavaDelegate {
public void execute(DelegateExecution execution) throws Exception {
String myVar = (String) execution.getVariable("myVar");
execution.setVariable("myVar", myVar.toUpperCase());
}
}
By contrast here we are being passed an ‘execution’, and we are pulling values out of it and twiddling them and putting them back.
This is somewhat analogous to a Servlet taking values we are passed in the HTMLRequest and then based on them doing different things in the response. (A stronger analogy would be a servlet Filter)
So in your particular instance (depnding on how you are invoking the shell script) using the Expression Language (EL) might be simplest and easiest.
Of course the value you want to pass has to be one that the process knows about (otherwise how can it pass a value it doesn't have a variable for?)
Hope that helps. :D
Usually in BPM engines you have a way to hook out listener to these kind of events. In Activiti if you are embedding it inside your service you can add an extra EventListener and then record the taskCompleted events which will contain the current logged in user.
https://www.activiti.org/userguide/#eventDispatcher
Hope this helps.
I have used activiti:taskListener from activiti app you need to configure below properties
1. I changed properties in task listener.
2. I used java script variable for holding task.assignee value.
Code Snip:-

Jmeter Beanshell: Accessing global lists of data

I'm using Jmeter to design a test that requires data to be randomly read from text files. To save memory, I have set up a "setUp Thread Group" with a BeanShell PreProcessor with the following:
//Imports
import org.apache.commons.io.FileUtils;
//Read data files
List items = FileUtils.readLines(new File(vars.get("DataFolder") + "/items.txt"));
//Store for future use
props.put("items", items);
I then attempt to read this in my other thread groups and am trying to access a random line in my text files with something like this:
(props.get("items")).get(new Random().nextInt((props.get("items")).size()))
However, this throws a "Typed variable declaration" error and I think it's because the get() method returns an object and I'm trying to invoke size() on it, since it's really a List. I'm not sure what to do here. My ultimate goal is to define some lists of data once to be used globally in my test so my tests don't have to store this data themselves.
Does anyone have any thoughts as to what might be wrong?
EDIT
I've also tried defining the variables in the setUp thread group as follows:
bsh.shared.items = items;
And then using them as this:
(bsh.shared.items).get(new Random().nextInt((bsh.shared.items).size()))
But that fails with the error "Method size() not found in class'bsh.Primitive'".
You were very close, just add casting to List so the interpreter will know what's the expected object:
log.info(((List)props.get("items")).get(new Random().nextInt((props.get("items")).size())));
Be aware that since JMeter 3.1 it is recommended to use Groovy for any form of scripting as:
Groovy performance is much better
Groovy supports more modern Java features while with Beanshell you're stuck at Java 5 level
Groovy has a plenty of JDK enhancements, i.e. File.readLines() function
So kindly find Groovy solution below:
In the first Thread Group:
props.put('items', new File(vars.get('DataFolder') + '/items.txt').readLines()
In the second Thread Group:
def items = props.get('items')
def randomLine = items.get(new Random().nextInt(items.size))

Saving a max value of counter to file in JMeter

I'm using a SOAP/XML-RPC Request to test a WSDL. Additionally I created a Counter element for this request. Each call of one of the functions has to contain other value in one of parameters.
Is there any possibility to save the maximum counter value to the file?
So when I start test, the value will be loaded from the file and increase by the counter.
At the end, this max value will be again saved to this file. And so on, so on...
Let's drop the built-in Counter and pass around the thread safe AtomicInteger.
Add a setUp Thread Group with a JSR223 Sampler (choose groovy as a scripting language) to your test plan. We will use it to read the value from the file. This thread group will be executed before all other thread groups and will provide us with the initial value.
Add the following code to the sampler:
import java.util.concurrent.atomic.AtomicInteger
counter = new File($/C:\Path\ToFile\fileName.txt/$).text
ai = new AtomicInteger(Integer.valueOf(counter))
props.put("sharedAtomicInteger", ai)
Then add another JSR223 Sampler after SOAP/XML-RPC Request in your regular Thread Group.
Add the following code to the sampler:
ai = props.get("sharedAtomicInteger")
variable = ai.incrementAndGet()
vars.put("variable", Integer.toString(variable))
Now the value of the improvised counter is stored in a variable and can be used in other requests issued by this thread.
Add a tearDown Thread Group with a JSR223 Sampler to your test plan. This thread group will be executed after all other thread groups and will write the maximum value to the file.
Add the following code to the sampler:
ai = props.get("sharedAtomicInteger")
new File($/C:\Path\ToFile\fileName.txt/$).write(ai.toString())
Finally, your test plan should look like this:
setUp Thread Group
JSR223 Sampler
Regular Thread Group
SOAP/XML-RPC Request
JSR223 Sampler
tearDown Thread Group
JSR223 Sampler
P.S.
Bear in mind that for brevity's sake I used the put() method of java.util.Properties class which is discouraged in the documentation.
To save value into a file (assumes a JSR223 Element and Groovy language)
new File("value.txt").text = vars.get("foo")
To read the value from file (assumes __FileToString() function)
${__FileToString(value.txt,,)}
I used tips from the first comment and do it in the following way:
transfer - Simple Controller
reading transactionId - JSR223 PreProcessor
transfer - SOAPXML-RPC Request
saving transactionId - JSR223 PostProcessor
JSR223 PreProcessor
Script language: groovy
import java.util.concurrent.atomic.AtomicInteger;
initial = new File("${absolute_path}transactionid.txt").text;
initial = initial.trim();
ai = new AtomicInteger(Integer.valueOf(initial));
transactionId = ai.incrementAndGet();
vars.put("transactionId", Integer.toString(transactionId));
SOAPXML-RPC Request
Here I'm using transactionId as one of the parameters in the SOAP Request.
JSR223 PostProcessor
Script language: groovy
transactionId = vars.get("transactionId");
new File("${absolute_path}transactionid.txt").write(transactionId.toString());
${absolute_path} is a variable defined in test plan as:
${__BeanShell(import org.apache.jmeter.services.FileServer; FileServer.getFileServer().getBaseDir();)}${__BeanShell(File.separator,)}
It is a path to folder with this JMeter project. This folder also contains file which is read to this test case.