0
votes

I am trying to do setproperty across multiple threads in the same threadgroup, the postprocessor set new variable using setproperty, so that It can be accessed across multiple threads.

In Beanshell preprocessor, I'm having below line of code.

${__setProperty("url", "youtube")};

Under thread Group I'm having Beanshell post processor, having below one line in postprocessor.

${__setProperty("url", "google")};

under thread group, I have Http Sampler, in hostname field I have given ${__property(url)}.com

The Aim is, when it executes first time, the URL will be google.com and when first threads complete than the URL becomes youtube.com But the setProperty only set google, and the second one in postprocessor was not working.

Refer the below Image for details, it shows how I created the element in Jmeter.

enter image description here

Note: This was just a sample use case, but I have complex example, but answering to this question will help me to add the logic in complex script.

Thanks

2

2 Answers

0
votes

So is the goal that the very first thread to complete will change the URL for all subsequently created threads?

My understanding of the documentation is that you can't change the value of a property inside the thread-group: Properties can be referenced in test plans - see Functions - read a property - but cannot be used for thread-specific values. (see http://jmeter.apache.org/usermanual/test_plan.html#properties)

My assumption is that each thread in a thread-group gets a copy of the properties. If you change the value of the property inside the thread group, then you are actually changing the copy for that particular thread. Since you are changing it in the post-processor, the thread is very likely just about to be disposed, resulting in your change being lost. After disposal a new thread is created but with the original value of the property.

So what you need to do is figure out how to change the value outside of the thread-group.

I have done something similar in my own tests whereby I am changing the value of a property in the middle of the test, and the value is picked up immediately by all of the active thread-groups, resulting in each new thread created from that point forward getting the new value. I am doing this by using the Beanshell Server: https://jmeter.apache.org/usermanual/best-practices.html#beanshell_server

In my specific case I use jenkins job that calls a shell-script which connects to the beanshell-service running on the local-host:

java -jar ${jmeter_home}/apache-jmeter-5.0/lib/bshclient.jar localhost 9000 ${test_plan_home}/update_Prop.bsh "${property}" "${value}"

where my update_prop.bash file is simply:

import org.apache.jmeter.util.JMeterUtils;
JMeterUtils.getJMeterProperties().setProperty(args[0],args[1]);

You would not need to use Jenkins or anything like that, though - if you setup your JMeter Process to include the Beanshell-server (see the link above) then you can simply replace the code in your post-processor: ${__setProperty("url", "google")};

with the code to connect to the beanshell server and execute that command there instead: exec("./updateprop.bash url google");

0
votes
  1. JMeter properties are global therefore once you set the property it is available for all threads
  2. Each JMeter thread (virtual user) executes Samplers. Pre and Post processors are obeying JMeter Scoping Rules Looking into your test plan the execution order is following:

    1. Beanshell PreProcessor
    2. HTTP Request Sampler
    3. Beanshell PostProcessor

      therefore HTTP Request sampler will never hit youtube (unless you run into a race condition due to concurrency) because PreProcessor will set the URL back to google

  3. It is recommended to use JSR223 Test Elements and Groovy language for scripting since JMeter 3.1

  4. It is NOT recommended to inline JMeter Functions and/or variables into scripts, you need to either use "Parameters" section or go for code-based equivalents instead so you need to replace this line:

    ${__setProperty("url", "youtube")};
    

    with this one:

    props.put("url", "youtube");