Jmeter pass number of threads as dynamic value - multithreading

I have a main thread where I am getting a list of categories from there I am passing each category from inside the ForEach Controller to next thread. In this thread I get a number of categories inside the variable
In the second thread I am going through each category and using ForEach Controller to pass each product into the 3rd Thread. In this thread I get a number of products inside the variable.
Now I want to use the above number of categories and products into the second and third threads as a dynamic variable i.e if:
categories are 10 then the second thread numbers should be 10
products are 100 then I would like 100/10 = 10 threads for 3 thread group.
I am using the interthread communication processors successfully which works fine withe static number of threads but not when I pass as a variable via interthread communication processors
Please help me

In first Thread Group define the desired number of threads using __setProperty() function like:
${__setProperty(threads,10, )}
In second Thread Group read the value using __P() function like:
${__P(threads,)}
That's it, 2nd Thread Group will kick off as many threads as you define in the first one
More information: Knit One Pearl Two: How to Use Variables in Different Thread Groups
Also be aware that since JMeter 3.1 you should be using JSR223 Test Elements and Groovy language for any form of scripting so convert your Beanshell test elements into JSR223 and make sure to use Groovy

Related

How to synchronise a code block in JSR223 Post Processor component in the global scope

I want to ensure a code block within a JSR223 Post Processor is executed by only one thread at a time. The JSR223 Post Processor is placed just below the Test Plan component to ensure it is shared with all the samplers.
I have tried with following to check if synchronization works as expected
synchronized (this){
def count=props.get("count").toInteger()
count+=1
props.put("count",count.toString())
log.info(" ==== Current count is ${count} ${__threadNum} ${vars.get('__jm__TG__idx')}=== ")
//different code to be used within this block
}
I have noted duplicates (i.e. duplicate count values)
props is a global object so when multiple threads are writing into it the previous value is getting overwritten
When you're inlining JMeter Functions or Variables like ${__threadNum} into Groovy scripts only first value is getting cached and used in the subsequent iterations
Each thread is executing JSR223 test elements separately, sychronized keyword doesn't act as you expect
So the options are in:
Either convert your JSR223 PreProcessor into JSR223 Sampler and put it under Critical Section Controller (however it will mean "no concurrency"
Or go for Inter-Thread Communication Plugin
You may include JSR Sampler in Critical Section Controller to ensure it's synchronized on JVM level
ensures that its children elements (samplers/controllers, etc.) will be executed by only one thread as a named lock will be taken before executing children of controller.
Critical Section Controller takes locks only within one JVM, so if using Distributed testing ensure your use case does not rely on all threads of all JVMs blocking.

JMeter slows down when using external file for groovy script

I have a threadgroup with JSR223 pre-processor that loops through unique IDs of the objects and makes a request for that object resource. I am attempting to address all the objects, which could be in millions. To overcome maximum thread limitations, each thread addresses specific set of objects and loops through this set. The entire threadgroup runs for a specific time period. This is the pre-processor groovy script.
// get unique object Id for the thread request
int numThreads = Integer.parseInt(args[0]);
int totalObjects = Integer.parseInt(args[1]);
int objectsPerThread = totalObjects/numThreads;
int initialObjectsCount = (ctx.getThreadNum()) * objectsPerThread;
int objectId = initialObjectsCount + (ctx.getVariables().getIteration()) % objectsPerThread;
vars.put("uniqueId", Integer.toString(objectId));
All is well when this script is pasted right in the GUI. The JMeter client is able to saturate the server easily. I would like to use this script in multiple places and extracted this into a file to be shared across JMX files. When I do that and specify the file name for the script in JSR223, JMeter client is unable to perform at the same efficiency as when this script was pasted in the GUI. The Cache compiled script if available option is checked in both cases.
Is this expected?
Is there a better way to share the scripts, such as, using test fragments, assuming pre-processors can be used as test fragments.
This is kind of expected as file IO is slower than memory operation.
If this is critical you can use a Test Fragment and a Module Controller to avoid code duplication.
Just be aware that a PreProcessor is being executed only with conjunction with the Sampler so you will have to switch to the JSR223 Sampler
If you don't want to see the JSR223 Sampler in your test results just add the next line somewhere in your script:
SampleResult.setIgnore()
and it will suppress the output so the sampler won't be caught by Listeners and you won't see it in the .jtl results file

How to increment variables in JMeter and how to override values of user defined variables?

I need to increment a variable for each thread.
Example:
Thread 1: $(Test_Var) should be 1001
Thread 2: $(Test_Var) should be 1002
Thread 3: $(Test_Var)) should be 1003
and so on ..
In the test plan I defined some user defined variables. Here I set up one $(Start_Test_Var) with the value of 1000.
Now I am starting my test and it will always count until 1001 because the start value is set on 1000.
How can I increment the variable for each thread? I never pass the value of 1001 and I have no idea what to do.
JMeter always “remember” the start variable and starts to count from 1000 up but I want Jmeter to count up from the last value of the variable (1000, 1001, 1002).
I tried to set up a “SetUp”-Thread group with all settings and with all user defined variables. Then I added a BeanShell Assertion in my “real” thread group but it didn’t worked either.
Although my calculation works:
Calculation of the variable
Is there a way to override the value of the user defined variable?
Thanks!
JMeter Variables are local to current Thread Group only, if you want to pass variables between Thread Groups you need to use JMeter Properties instead, i.e.
__setProperty() function in the setUp Thread Group to set the value
__P() function in "real" thread group to read the value
See Knit One Pearl Two: How to Use Variables in Different Thread Groups article for more details.
Also be aware of __counter() function which can produce "global" number which will increment by 1 each time this function is called.

how to access a worker thread from UI thread?

I have a working thread running all along the runtime, who generates events.
I can handle those events inside the UI thread by using disp = Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher.
more precisely, I do the modifications to the UI by using disp->RunAsync(...) anywhere inside the working thread.
but I don't know how to do the inverted operation. I want to have some Async function inside the UI thread to perform operation (on some std::unique_ptr) in the working thread when I click on some button.
If I understand correctly you want to be able to run an async operation when a button is clicked, but on a specific thread to which you refer as your worker thread.
First - Since you want to use a resource in 2 threads you should not use unique_ptr and use shared_ptr since you share this resource between the two threads.
Second - if you don't necessarily have to run the action on a specific thread then you can simply use Windows::System::Threading::ThreadPool::RunAsync and capture the shared_ptr by value.
e.g:
namespace WST = Windows::System::Threading;
WST::ThreadPool::RunAsync(
ref new WST::WorkItemHandler(
[mySharedPtr](Windows::Foundation::IAsyncAction^ operation)
{
mySharedPtr->Foo();
}));
In case you have to run the operation on a specific thread then I assume you want to be able to append operations to an already running thread, otherwise you are creating a thread and you can use the above example.
So in order to append operations to an already running thread, that thread must have the functionality of getting a new operations and then running those operations in a synchronous order. This functionality is basically what the Dispatcher provides. This is what an Event Loop is, also called: message dispatcher, message loop, message pump, or run loop. Also you can find information by reading on the Recator\Proactor design pattern.
This CodeProject page shows one way of implementing the pattern, and you can use Winrt component to make it better \ more conveniant \ more familiar

Why pass parameters through thread function?

When I create a new thread in a program... in it's thread handle function, why do I pass variables that I want that thread to use through the thread function prototype as parameters (as a void pointer)? Since threads share the same memory segments (except for stack) as the main program, shouldn't I be able to just use the variables directly instead of passing parameters from main program to new thread?
Well, yes, you could use the variables directly. Maybe. Assuming that they aren't changed by some other thread before your thread starts running.
Also, a big part of passing parameters to functions (including thread functions) is to limit the amount of information the called function has to know about the outside world. If you pass the thread function everything it needs in order to do its work, then you can change the rest of the program with relative impunity and the thread will still continue to work. If, however, you force the thread to know that there is a global list of strings called MyStringList, then you can't change that global list without also affecting the thread.
Information hiding. Encapsulation. Separation of concerns. Etc.
You cannot pass parameters to a thread function in any kind of normal register/stack manner because thread functions are not called by the creating thread - they are given execution directly by the underlying OS and the API's that do this copy a fixed number of parameters, (usually only one void pointer), to the new and different stack of the new thread.
As Jim says, failure to understand this mechanism often results in disaster. There are numnerous questions on SO where the vars that devs. hope would be used by a new thread are RAII'd away before the new thread even starts.

Resources