Jmeter: how to modify properties on the fly while distributed test is running? - jmeter

WHAT I HAVE:
Huge Jmeter agents network, 1 master + many slaves.
Master sends tasks to Slaves, they start test execution and report data to Master.
WHAT I WANT:
Be able to modify inputs (passed as global properties to Master, -G) on the fly, while test is executed, without necessity to stop/restart test.
WHAT I KNOW:
I can use BeanShell server to modify Jmeter properties while running the test. It works fine. But BeanShell server starts only on Master, not on Slaves.
Master sends -G properties to Slaves only once, before test execution. Even if Master properties are updated, slaves never get this information until test is restarted.
QUESTION:
How can I modify properties on Slaves as well? Is there any proper solution?
WHAT I THOUGHT ABOUT:
Well, I can do the same trick with BeanShell server for every Slave node too. But this solution doesn't look really ideal for me as I have a lot of agents and have to update all of them. It takes time.
I can change my test logic to update properties from file periodically, and then modify files on Slaves on the fly. Looks even easier for me than #1 as it's cheaper to modify a file over ssh remotely then to launch a separate server on every node.
Actually, all I need in fact is to write a proper method/function for BeanShell server that not only changes properties locally but informs Slaves about it. I'm not so familiar with Jmeter source code yet (just started) but know that it's already implemented inside the code as a part of remote launching procedure. So, if you can point me to the right class to take a look into - it can help me a lot.
Any ideas appreciated. Thanks in advance.

You can add to your Test Plan Property File Reader which will read and update properties in Slaves, you can add properties on runtime in Master using Beanshell/JSR233 element.

Related

Saving the jmeter result .jtl files in the Slaves machine

I have configured Jmeter distributed testing, and I'm successfully able to trigger the test from Master to Slave machine. But the results files are not being generated on Slave machine even if I explicitly added a Listener into the test plan.
Can anybody help on this.
Thanks in advance
Question answered in JMeter group by #glinius:
in user.properties, add: mode=StrippedBatch
This will:
remove some data from the SampleResults as the response body, but do you need response body during a High Load Test, NO, DEFINITELY NO !
will send Sample Results as Batches and not for every sample reducing CPU, IO and network roundtrips
Adding the listener itself is not sufficient, you need to specify the location for the .jtl file in the listener, i.e. Simple Data Writer is a good choice
The user which is running the JMeter slave process must have write permissions to the folder specified. See How to Save Response Data in JMeter article for more details if needed. If you want to save the response data - make sure to provide mode=Standard property
Also make sure to provide the valid resultcollector.action_if_file_exists property, i.e. APPEND if you want to add new results to the existing file or DELETE if you want to overwrite the old results with the new ones.
The property can be passed via -G command-line argument from the master or via -J command-line argument from the slave. More information: Full list of command-line options

Jmeter in distributed mode: JVM doesn't stop because of BeanShell server

WHAT I HAVE:
Jmeter network created for tests in distributed mode: one Jmeter master plus few Jmeter slaves. BeanShell Server disabled. Everything works fine.
WHAT I WANT TO DO:
I want to enable BeanShell server to be able to modify properties on the fly.
ACTUAL RESULT:
BeanShell server starts and works successfully.
Once the test is done, the following message appears in the log:
The JVM should have exited but did not.
The following non-daemon threads are still running (DestroyJavaVM is OK):
Thread[Thread-7,5,main], stackTrace:java.net.PlainSocketImpl#socketAccept
java.net.AbstractPlainSocketImpl#accept at line:409
java.net.ServerSocket#implAccept at line:545
java.net.ServerSocket#accept at line:513
bsh.util.Sessiond#run at line:65
java.lang.Thread#run at line:748
Thread[Thread-5,5,main], stackTrace:java.net.PlainSocketImpl#socketAccept
java.net.AbstractPlainSocketImpl#accept at line:409
java.net.ServerSocket#implAccept at line:545
java.net.ServerSocket#accept at line:513
bsh.util.Httpd#run at line:64
java.lang.Thread#run at line:748
It's clear that it happens because of BeanShell server that is running and doesn't exit for some reason.
As a result, java process will never exit and will hang.
QUESTION:
Any ideas why it happens? How to avoid it? I don't connect to beanshell server, neither by http nor by telnet.
MORE DETAILS:
All the nodes are running as Docker containers.
All nodes are deployed in AWS.
Can't reproduce the same issue locally on my machine. Even with BeanShell server enabled, all works smooth, and java exists as it should.
WHAT I TRIED:
Tried to set up the following properties:
jmeterengine.remote.system.exit=true
jmeterengine.stopfail.system.exit=true
jmeterengine.force.system.exit=true
Doesn't help, java process still hangs.
The same for
bsh.system.shutdownOnExit = true;
Any ideas are very much appreciated.
I don't think there is a way of stopping the Beanshell Server along with the test as it runs in an endless-loop Thread
I would recommend stopping your test and the Beanshell server using a .bsh file like:
stopEngine();
Thread.sleep(5000L); // just in case wait for 5 seconds for graceful shutdown
System.exit(0);
where:
stopEngine() is a shorthand for StandardJMeterEngine.stopEngine(), it's defined in startup.bsh
System.exit(0); - basically shuts down the whole JVM with 0 exit status code
So you will be able to turn everything off the same way you amend the properties in the runtime.
You can also achieve the same by executing the System.exit(0); command automatically from i.e. tearDown Thread Group using OS Process Sampler, however in this case make sure to set the following property:
jmeter.save.saveservice.autoflush=true
otherwise you can loose some results which have not been written to disk yet
Finally, I found a workaround, so posting it as an answer here.
Actually, it doesn't answer the original question in fact, but don't want to waste time trying to find an original root cause as it seems to be related to AWS structure (just because I can't reproduce it locally inside the same container I launch remotely).
So, the final schema is:
To update properties on the fly, I don't have to launch BeanShell on slave and master both. Real property change happens on slave, so master is not required. It solves my specific case.
To stop test, you can use existent shutdown.sh and stoptest.sh scripts. No need to do it over beanshell server.
If the test was properly stopped, then -X option (server.exitaftertest=true) also works fine, so force shutdown for JVM is not required, and you don't have to add tearDown thread group that does System.exit. But the idea is nice.
It's worth to have a shutdown.bsh script to force kill it anyway as a tool.

JMeter - Bandwidth control not working

I'm attempting to run a testplan using different qualities of network.
To accomplish this I set a "HTTP Request Default" so they all use HTTP 3.1 or 4.
Then I passed the properties as follows:
-Jhttpclient.socket.http.cps=21888 -Jhttpclient.socket.https.cps=21888
However it doesn't seem like it's doing much, do I need to enable the setting in the user.properties as well (to maybe 0) which I can then overwrite with the property?
I am doing this with a distributed test plan (multiple load generators in non-gui mode) but since they are all started through the one "master" node I would think they would all take the property.
You need to start all the slaves using these -J command-line arguments or modify user.properties file on each slave in order to make it work.
Properties are not being automatically passed to slaves from the master node. You can also try out -G key, as per Full list of command-line options
-G, --globalproperty <argument>=<value>
Define Global properties (sent to servers)
e.g. -Gport=123
or -Gglobal.properties
Also remember that all slaves are quite independent so each of them will have 21888 characters per second throttling so cumulative bandwidth will be sum of all slaves.
See How to Simulate Different Network Speeds in Your JMeter Load Test article for more information on simulating different networks during JMeter test.

Fetch response times in JMeter running remotely

Ok so I set up my JMeter to run remotely using one slave computer (possibly more to come), and it's working out for the most part EXCEPT that I can't fetch the response time over time-graphs function using the JMeter plugin. I'm still able to use the "PerfMon Metrics" tool to get the CPU/Memory values from the slave computer, so I don't understand how I'm not able to get the response time results.
Does anyone have any experience using that function?
I would check the master- slave configuration: be sure that
the same Jmeter release is used
same directory tree structure is used
Jmeter-plugins are installed on both systems
...
If you use a standard "Summary report" listener, and save data to a file in the master, then you can reload and analyse the data off line with any listener.
HTH

Distributed JMeter tests with per-slave CSV datasets

I'd like to run a distrubuted JMeter test on our site, following the
manual. My tests are parametrized via a CSV DataSet configuration element to simulate diffent users. The question is now: Will JMeter use the same DataSet for each slave, or can I somehow configure each slave with its own dataset? If the first is the case, slaves will steal each other's session which is of course undesired.
Jmeter use local CSV fiels in distributed mode. So you just place different files on each slave and it works. Nothing special to do.
You can choose the CSV Data behaviour with the Sharing mode option. Description of each option detailed in:
http://jmeter.apache.org/usermanual/component_reference.html#CSV_Data_Set_Config

Resources