I am looking to run a service mix of 3 APIs with different loads sequentially. Q1 - 20%, Q2 -10%, Q3 - 70%
However, Q1 in independent and Q2 is dependent on variable generated in Q3.
I have following setup. I cannot have multiple thread groups and need transaction controllers as I need to upload this to Storm Runner.
ThreadGroup - Threads 10, Loop 1
--- Q1ThroughPutController -20%
---Q1TransactionController
--- Q2ThroughPutController - 10%
---Q2TransactionController
--- Q3ThroughPutController - 70%
---Q3TransactionController
Current run looks like this:
Q3 - Fail
Q3 - Fail
Q3 - Fail
Q3 - Fail
Q1 - Fail
Q3 - Fail
Q1 - Pass
Q3 - Pass
Q2 - Pass
Q3 - Pass
According to JMeter Documentation:
Properties are not the same as variables. Variables are local to a thread; properties are common to all threads, and need to be referenced using the __P or __property function.
Your setup assumes that:
20% of users are executing Q1
10% of users are executing Q2
70% of users are executing Q3
so there is no way for user who ran Q3 to switch to Q1
You need to amend your correlation logic to use properties instead of variables, properties are global so they will be accessible to all threads, you will have to do some custom Groovy scripting using suitable JSR223 Test Elements
Alternative solution would be using Inter-Thread Communication Plugin to pass your variables between different threads and also implement some blocking logic so the virtual user will "wait" for the variable value before proceeding
Related
I'm working on an app which runs remote tasks (Task A and Task B) on a few (10) servers (s1 to s0) and once the parts are complete Task C is run on the local server. All these tasks could take a while to finish (from a minute to an hour) but task A takes between 4 to 20 times longer than task B (and this could change for each run).
I don't wish to run more than one task on any server at a time.I'm trying to be efficient with how this works so I think laravel8's Queue would serve my purpose. My thinking I have say 5 queues q1,q2,q3,q4,q5 I then add taskA for queues 1 to 3 for the first 3 servers and task B for s4 and s5 I would then repeat for all tasks. After this my Queues would look like this
q1 q2 q3 q4 q5
s1ta s2ta s3ta s4tb s5tb
s6ta s7ta s8ta s9tb s0tb
s1tb s2tb s3tb s4ta s4ta
s6tb s7tb s8tb s9ta s0ta
--tc
While this looks good what if q1 gets to task C but other queues are running? Is there a way I can trigger task C when all queues are empty? Is there a better way to do this? Should I use something else except Queues for this and if so what? Is an event triggered when a job in a queue finishes?
I await your thoughts and recommendations.
thanks
Craig
*** EDIT ***
Thinking more on this it would make sense to run task a and task b on the same queue after each other so:
q1 q2 q3 q4 q5
s1ta s2ta s3ta s4ta s5ta
s1tb s2tb s3tb s4tb s5tb
s6ta s7ta s8ta s9ta s0ta
s6tb s7tb s8tb s9tb s0tb
--tc
but the issue with Task C would still remain and it would be good if a task could move to an empty Queue if it hasn't started. Right now I've no idea where to begin...
I am using jMeter to do some performance testing.
All thread groups are almost identical - differs only in name and in http request inside (see structure below). Although all are defined the same, the run seems to ignore some of those. Only two out of 10 are running.
I have set the log level to debug and there is still no mention of the other TG (thread groups). It's not even first two that would work, but more like third and fifth or so.
Doesn't make any sense to me. Any ideas?
I have following definition:
Test Plan
- variables#1 - constants
- variables#2 - environment variables (user defined)
- variables#3 - another variables used to enable/disable certain tests
- CSV dataset config - data#1
- CSV dataset config - data#2
- HTTP Request defaults (hostname, protocol and port are defined) + implicit parameters (e.g. callingApp=jmeter - part of GET in url)
-view results tree
-log aggregate report
-thread group A (arrivals - extension)
--If Controller*1
---HTTP request with specific path
----some assertions
-thread group B - E (all are the same as A, only different urls are used)
Ran using:
$config="-DrampUpTime=1 ..."
mvn clean verify $config
Didn't find anything in related logs or any of the settings
Related pom.xml bits:
plugin:com.lazerycode.jmeter:jmeter-maven-plugin:2.9.0
plugin-<config>
<jmeterVersion>5.1.1</jmeterVersion>
<overrideRootLogLevel>DEBUG</overrideRootLogLevel>
<resultsFileFormat>jtl</resultsFileFormat>
<jmeterExtensions>
<artifact>kg.apc:jmeter-plugins-casutg:${jmeter.plugins.catsug.version}</artifact>
</jmeterExtensions>
Shoot me now. Just found it.
<com.blazemeter.jmeter.threads.arrivals.ArrivalsThreadGroup guiclass="com.blazemeter.jmeter.threads.arrivals.ArrivalsThreadGroupGui" testclass="com.blazemeter.jmeter.threads.arrivals.ArrivalsThreadGroup" testname="/something/something/something" enabled="false">
enabled="false"
Apparently there is a possibility to disable the test and for fun it only differs in slightly more gray font (in the dark theme) in GUI.
On my defense, I did not create the test suite, so at least it was not me, who disabled it.
wastedHoursCounter=5;
In my Jmeter 3.0 test plan, I have multiple thread groups. Now I want to
distribute users among them on the basis of percentage.
I have declared Variables in user defined variable and then used the following statement in thread group
${__BeanShell(${__evalVar(threads)}*${__evalVar(WeightOfGroup1)}/100)}
But I am getting the following exception while doing so
2017/09/20 19:25:39 ERROR - jmeter.util.BeanShellInterpreter: Error invoking bsh method: eval In file: inline evaluation of: ``**ERROR - see log file*****ERROR - see log file**/100;'' Encountered "*" at line 1, column 1.
2017/09/20 19:25:39 WARN - jmeter.functions.BeanShell: Error running BSH script org.apache.jorphan.util.JMeterException: Error invoking bsh method: eval In file: inline evaluation of: ``**ERROR - see log file*****ERROR - see log file**/100;'' Encountered "*" at line 1, column 1.
You cannot use variables in thread group definitions, since variables are local to a thread, and thus are initialized after thread group starts its threads.
You have 2 options:
Use properties, as described in this solution. Calculation you are trying to do will need to be modified too, for example like this:
${__javaScript(Math.max(1\,Math.round(props.get('threads')*props.get('WeightOfGroup1')/100)))}
Assuming here that you have both threads and WeightOfGroup1 properties defined. Also notice that you need to round the number to integer. To avoid ending up with 0 threads, I also take the maximum between 1 and formula calculation (so it will run at least one thread) - this is optional of course.
From your use case it actually looks like you don't need thread groups. Instead, you could use one thread group, have Throughput Controller for each fragment which previously was your thread group, and express your distribution goal in Throughput Controller parameter. In that case you don't need to calculate percentage, just specify what you need the percentage to be, e.g.:
I think this solution is more elegant, so unless there are any other reasons to use multiple thread groups, I'd go with that.
I configured my test in this way (in windows 7):
1 Virtual machine is master, that run all vm slaves with the command for a distribuited testing (from command line) and show in jmeter GUI some graphs (for example jp#gc Active thread over time , hits/sec, response time, etc..).
3 Virtual machine are slave, to execute the testing;
When master run the "start" to 3 slave, the test works (each slave run 6 thread), and in the GUI on master, there are only 6 thread in the graph (jp#gc - Active Threads Over Time), but in reality are 18 (6 thread for slaves, with 3 slaves).
So my question is: how can I see the total data for all slaves?
jp#gc - Active Threads Over Time = to see 18 thread (thread slave1 +thread slave2+thread slave3)
jp#gc - Hits per Second = Hits slave 1 +Hits slave 2+ Hits slave 3
and so on...
You need to add __machineName or __machineIP function so the listeners could distinguish results coming from different nodes.
Also be aware of mode property which is configured to send results from slave machines each 100 results or each minute (whatever comes the first) so you might want to amend it, i.e. add mode=Standard line to user.properties file on each slave node.
# Remote batching support
# Since JMeter 2.9, default is MODE_STRIPPED_BATCH, which returns samples in
# batch mode (every 100 samples or every minute by default)
# Note also that MODE_STRIPPED_BATCH strips response data from SampleResult, so if you need it change to
# another mode
# Hold retains samples until end of test (may need lots of memory)
# Batch returns samples in batches
# Statistical returns sample summary statistics
# hold_samples was originally defined as a separate property,
# but can now also be defined using mode=Hold
# mode can also be the class name of an implementation of org.apache.jmeter.samplers.SampleSender
#mode=Standard
#mode=Batch
#mode=Hold
#mode=Statistical
See Apache JMeter Properties Customization Guide for more information on working with JMeter properties.
Be aware that sending results in case of severe load may cause network IO overhead so it might be a good idea to consider Backend Listener instead
Add the Machine Info function to the thread group name area as shown below:
In JMeter, I have a requirement where I want to run a particular thread group after all the other thread groups complete their run, I know the tearDown thread group has the similar behavior but unfortunately, the logic has to be part of my regular thread.
Let's say there are 4 thread groups A,B,C & D in my test plan and I want the thread group D only to be executed after A, B & C will complete their run.
Can we achieve this without using "setup, teardown & Run groups one at a time" ??
Problem ScreenShot:
I can suggest 2 options:
Use Inter-Thread Communication Plugin. See example test plan for details.
If for some reason you are not in position to use JMeter Plugins you can achieve the same using JMeter Properties like:
When Thread Group A finishes set a JMeter Property, i.e. ThreadGroupADone=true using __setProperty() function like
${__setProperty(ThreadGroupADone,true,)}
In Thread Group D:
Add While Controller at the beginning of the Thread Group and use the following condition:
${__javaScript("${__P(ThreadGroupADone,)}"=="false",)}
Add Test Action sampler as a child of the While Controller and configure it to pause for a reasonable amount of seconds, i.e. 5 so each 5 seconds While Controller will check ThreadGroupADone property value and if it is still false - sleep for another 5 seconds. When property value will become true - Thread Group D will proceed.