Quantcast

Sharing arrays between threads.

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Sharing arrays between threads.

Eric Olson
Hi,

I'm having a terrible time figuring out how to share an array of strings
between different parts of my test plan.  The problem I'm trying to solve
is that i want to "log in" all of my users up front to get a big list of
tokens (using OAuth 2.0), and then when I move on to the actual load
testing section of my test plan, I can just have it randomly pick a token
from my array.

The way I've been trying to do it is:

-Define an array using a BSF preprocessor (via javascript) and add it to
vars (vars.putObject("myArray",
myArray);)
-In the auth thread group, parse the response using regular expressions
putting it into a temporary variable
-In the auth thread group, use a BSF postprocessor retrieve my previously
created array and add the temporary variable from the step above to the
array, and put it back in vars
-In my test thread group, which does not start running until my auth step
is completed, each thread randomly picks from the array defined at the test
plan level.

The problem I'm running into seems to be that there is some sort of scope
issue where the data added during the auth step is not available to the
test step - only what was predefined in the top-level preprocessor.  Am I
doing this completely wrong, or what?  Can Arrays not be shared?  If so,
how do you use data gathered from one step in the next step?

Thanks,

Eric
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Sharing arrays between threads.

shettyd
Hi
variables are scoped to the thread.
a. Use properties (but you'd have to represent the array as a delimited
string (also described in same link s step c)
b. Do you need randomness (or will sequential work) - if sequential works
then in a setup threadgroup write these values to a CSV , which is then
picked up by the next thread group using CSV data set config
c. use BSH shared namespace --
http://jmeter.apache.org/usermanual/best-practices - sharing variables

regards
deepak

On Thu, Feb 9, 2012 at 7:07 PM, Eric Olson <[hidden email]> wrote:

> Hi,
>
> I'm having a terrible time figuring out how to share an array of strings
> between different parts of my test plan.  The problem I'm trying to solve
> is that i want to "log in" all of my users up front to get a big list of
> tokens (using OAuth 2.0), and then when I move on to the actual load
> testing section of my test plan, I can just have it randomly pick a token
> from my array.
>
> The way I've been trying to do it is:
>
> -Define an array using a BSF preprocessor (via javascript) and add it to
> vars (vars.putObject("myArray",
> myArray);)
> -In the auth thread group, parse the response using regular expressions
> putting it into a temporary variable
> -In the auth thread group, use a BSF postprocessor retrieve my previously
> created array and add the temporary variable from the step above to the
> array, and put it back in vars
> -In my test thread group, which does not start running until my auth step
> is completed, each thread randomly picks from the array defined at the test
> plan level.
>
> The problem I'm running into seems to be that there is some sort of scope
> issue where the data added during the auth step is not available to the
> test step - only what was predefined in the top-level preprocessor.  Am I
> doing this completely wrong, or what?  Can Arrays not be shared?  If so,
> how do you use data gathered from one step in the next step?
>
> Thanks,
>
> Eric
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Sharing arrays between threads.

Eric Olson
Thanks for the swift reply, Deepak.

I had a similar thought about the CSV thing, but I'm still running into the
issue of not being able to store the tokens long enough to even put them in
a CSV.  I hadn't considered serializing the array into a string - that may
work for me as well.

As for the CSV thing, how would I store the values long enough to get them
into a CSV in the first place?  It seems like solving that problem is the
same as solving my first problem, which is that I can't write multiple
values to the same shared place.  Is there some sort of streaming CSV
writer that can append the values as I go?  I think I may just be having a
hard time grasping the scopes here.

-Eric

On Thu, Feb 9, 2012 at 7:13 PM, Deepak Shetty <[hidden email]> wrote:

> Hi
> variables are scoped to the thread.
> a. Use properties (but you'd have to represent the array as a delimited
> string (also described in same link s step c)
> b. Do you need randomness (or will sequential work) - if sequential works
> then in a setup threadgroup write these values to a CSV , which is then
> picked up by the next thread group using CSV data set config
> c. use BSH shared namespace --
> http://jmeter.apache.org/usermanual/best-practices - sharing variables
>
> regards
> deepak
>
> On Thu, Feb 9, 2012 at 7:07 PM, Eric Olson <[hidden email]> wrote:
>
> > Hi,
> >
> > I'm having a terrible time figuring out how to share an array of strings
> > between different parts of my test plan.  The problem I'm trying to solve
> > is that i want to "log in" all of my users up front to get a big list of
> > tokens (using OAuth 2.0), and then when I move on to the actual load
> > testing section of my test plan, I can just have it randomly pick a token
> > from my array.
> >
> > The way I've been trying to do it is:
> >
> > -Define an array using a BSF preprocessor (via javascript) and add it to
> > vars (vars.putObject("myArray",
> > myArray);)
> > -In the auth thread group, parse the response using regular expressions
> > putting it into a temporary variable
> > -In the auth thread group, use a BSF postprocessor retrieve my previously
> > created array and add the temporary variable from the step above to the
> > array, and put it back in vars
> > -In my test thread group, which does not start running until my auth step
> > is completed, each thread randomly picks from the array defined at the
> test
> > plan level.
> >
> > The problem I'm running into seems to be that there is some sort of scope
> > issue where the data added during the auth step is not available to the
> > test step - only what was predefined in the top-level preprocessor.  Am I
> > doing this completely wrong, or what?  Can Arrays not be shared?  If so,
> > how do you use data gathered from one step in the next step?
> >
> > Thanks,
> >
> > Eric
> >
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Sharing arrays between threads.

Flavio Cysne
Eric,

Write a customized function to JMeter and manipulate a map of values inside
it.
Store it in JMeter properties scope.

Regards.
Flavio Cysne

2012/2/10 Eric Olson <[hidden email]>

> Thanks for the swift reply, Deepak.
>
> I had a similar thought about the CSV thing, but I'm still running into the
> issue of not being able to store the tokens long enough to even put them in
> a CSV.  I hadn't considered serializing the array into a string - that may
> work for me as well.
>
> As for the CSV thing, how would I store the values long enough to get them
> into a CSV in the first place?  It seems like solving that problem is the
> same as solving my first problem, which is that I can't write multiple
> values to the same shared place.  Is there some sort of streaming CSV
> writer that can append the values as I go?  I think I may just be having a
> hard time grasping the scopes here.
>
> -Eric
>
> On Thu, Feb 9, 2012 at 7:13 PM, Deepak Shetty <[hidden email]> wrote:
>
> > Hi
> > variables are scoped to the thread.
> > a. Use properties (but you'd have to represent the array as a delimited
> > string (also described in same link s step c)
> > b. Do you need randomness (or will sequential work) - if sequential works
> > then in a setup threadgroup write these values to a CSV , which is then
> > picked up by the next thread group using CSV data set config
> > c. use BSH shared namespace --
> > http://jmeter.apache.org/usermanual/best-practices - sharing variables
> >
> > regards
> > deepak
> >
> > On Thu, Feb 9, 2012 at 7:07 PM, Eric Olson <[hidden email]> wrote:
> >
> > > Hi,
> > >
> > > I'm having a terrible time figuring out how to share an array of
> strings
> > > between different parts of my test plan.  The problem I'm trying to
> solve
> > > is that i want to "log in" all of my users up front to get a big list
> of
> > > tokens (using OAuth 2.0), and then when I move on to the actual load
> > > testing section of my test plan, I can just have it randomly pick a
> token
> > > from my array.
> > >
> > > The way I've been trying to do it is:
> > >
> > > -Define an array using a BSF preprocessor (via javascript) and add it
> to
> > > vars (vars.putObject("myArray",
> > > myArray);)
> > > -In the auth thread group, parse the response using regular expressions
> > > putting it into a temporary variable
> > > -In the auth thread group, use a BSF postprocessor retrieve my
> previously
> > > created array and add the temporary variable from the step above to the
> > > array, and put it back in vars
> > > -In my test thread group, which does not start running until my auth
> step
> > > is completed, each thread randomly picks from the array defined at the
> > test
> > > plan level.
> > >
> > > The problem I'm running into seems to be that there is some sort of
> scope
> > > issue where the data added during the auth step is not available to the
> > > test step - only what was predefined in the top-level preprocessor.
>  Am I
> > > doing this completely wrong, or what?  Can Arrays not be shared?  If
> so,
> > > how do you use data gathered from one step in the next step?
> > >
> > > Thanks,
> > >
> > > Eric
> > >
> >
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Sharing arrays between threads.

Bruce Ide
In the same thread you can use vars.putObject in a bsf or beanshell sampler
to store an array in a variable. Or you can just iteratively create a
jmeter array.

I wrote an addon to allow sharing across threads, see
https://github.com/FlyingRhenquest/JmeterThreadGlobal. It's a pretty simple
addon and isn't currently set up to share arbitrary objects, but it should
be easy to modify to do that.

If you used the new setup things you shouldn't have to synchronize between
the threads. If it turns out you need to, you can use a synchronizing timer
or my thread synchronization sampler (Which is also on github.)

All this does add quite a bit of complexity to the test though, so if
you're ever going to need to explain it to another tester you might want to
simplify your test design.

--
Bruce Ide
[hidden email]
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Sharing arrays between threads.

sebb-2-2
On 10 February 2012 16:26, Bruce Ide <[hidden email]> wrote:

> In the same thread you can use vars.putObject in a bsf or beanshell sampler
> to store an array in a variable. Or you can just iteratively create a
> jmeter array.
>
> I wrote an addon to allow sharing across threads, see
> https://github.com/FlyingRhenquest/JmeterThreadGlobal. It's a pretty simple
> addon and isn't currently set up to share arbitrary objects, but it should
> be easy to modify to do that.
>
> If you used the new setup things you shouldn't have to synchronize between
> the threads. If it turns out you need to, you can use a synchronizing timer
> or my thread synchronization sampler (Which is also on github.)
>
> All this does add quite a bit of complexity to the test though, so if
> you're ever going to need to explain it to another tester you might want to
> simplify your test design.

Very good point.

Why not create CSV data files containing the tokens in a separate test phase?
You can then randomise the data file if you want.

By the way, you say each thread picks a random token.
If you have multiple threads, a simple random choice will sometimes
result in two threads having the same token.
Is that allowed? If not, the token entries will have to be marked as
used; this will necessarily entail synchronising across threads.

The CSV data file can be set to only be used once; threads cannot then
get the same token (unless it is duplicated in the file).

If you have hundreds or thousands of tokens, using a data file is the way to go.

> --
> Bruce Ide
> [hidden email]

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Sharing arrays between threads.

Eric Olson
It's alright if two threads share a token, in fact it's probably preferable
for that to be part of my test since I'd expect to see that from real users.

I still don't see how I can write to a CSV, however.  I was able to get it
to write 1 CSV file per token, but I'm not really interested in having my
folder get filled up with numbered csv files.  I was hoping to have it all
in one CSV.

As for sharing within a thread, this still isn't working for me, so I guess
that's what I need help with.  Here's how my setup looks.

ThreadGroup
-BSF PreProcessor or Sampler (javascript) -> var myArray = new Array();
vars.putObject("myArray",myArray);
-Loop Controller -> 5 loops
--HTTP Sampler
---Regex postprocessor -> Reference Name = myToken
---BSF postprocessor - > var myArray = vars.getOject("myArray");
myArray.push(myToken);  vars.putObject("myArray",myArray);
-BSF Sampler -> var myArray = vars.getObject("myArray");  //At this point,
I expect myArray.length to be 5.  Instead it is 0.

Right now I'm taking the approach of serializing into a comma
delimitted string and storing it in props, but that just feels wrong to me.

Sebb, when you say "iteratively create a jmeter array", what do you mean?
Is there some other data structure that I'm completely missing?  I thought
the only way you could get a jmeter array was if your single regular
expression returned multiple matching groups... rather than having multiple
runs of a thread or a loop add on to an existing array.  If there's some
way to do that, I would love to know.

-Eric
On Fri, Feb 10, 2012 at 8:50 AM, sebb <[hidden email]> wrote:

> On 10 February 2012 16:26, Bruce Ide <[hidden email]> wrote:
> > In the same thread you can use vars.putObject in a bsf or beanshell
> sampler
> > to store an array in a variable. Or you can just iteratively create a
> > jmeter array.
> >
> > I wrote an addon to allow sharing across threads, see
> > https://github.com/FlyingRhenquest/JmeterThreadGlobal. It's a pretty
> simple
> > addon and isn't currently set up to share arbitrary objects, but it
> should
> > be easy to modify to do that.
> >
> > If you used the new setup things you shouldn't have to synchronize
> between
> > the threads. If it turns out you need to, you can use a synchronizing
> timer
> > or my thread synchronization sampler (Which is also on github.)
> >
> > All this does add quite a bit of complexity to the test though, so if
> > you're ever going to need to explain it to another tester you might want
> to
> > simplify your test design.
>
> Very good point.
>
> Why not create CSV data files containing the tokens in a separate test
> phase?
> You can then randomise the data file if you want.
>
> By the way, you say each thread picks a random token.
> If you have multiple threads, a simple random choice will sometimes
> result in two threads having the same token.
> Is that allowed? If not, the token entries will have to be marked as
> used; this will necessarily entail synchronising across threads.
>
> The CSV data file can be set to only be used once; threads cannot then
> get the same token (unless it is duplicated in the file).
>
> If you have hundreds or thousands of tokens, using a data file is the way
> to go.
>
> > --
> > Bruce Ide
> > [hidden email]
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Sharing arrays between threads.

Bruce Ide
Jmeter variables are essentially just key/value pairs stored in a big hash
table. There's nothing magical about arrays in jmeter, they just get a
_number extension on them. You can very easily write one of these with a
BSF sampler You just need to keep in mind that they start at one.

int i;
for(i = 1; i < 42; ++i) {
 vars.put("myarray_" + Integer.toString(i), Integer.toString(i));
}
vars.put("myArray_#", Integer.toString(i));

That's off the top of my head so please forgive me if it has syntax errors.
You can read them in the same way.

Since Jmeter variables are this way, the Object you stored in the Jmeter
variable is a reference. Therefore, you should not ever need to put it
again after you store it the first time. Just get the object in your BSF
sampler and push values into it and the array in vars will change.

That being said, I honestly don't see why your test doesn't work. It looks
to me like it should. There' s no harm in re-putting the array reference.

You can also open a File and write a comma delimited file from within the
BSF sampler. I prefer to use groovy in my BSF samplers, but I write my
files like a Java programmer because I'm not entirely comfortable with
everything that Groovy does. It's atrocious (my code, not groovy.) Just
google on opening and writing files with whatever language you're using. It
should put the file in your current test directory, if I recall correctly.

--
Bruce Ide
[hidden email]
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Sharing arrays between threads.

sebb-2-2
In reply to this post by Eric Olson
On 10 February 2012 17:09, Eric Olson <[hidden email]> wrote:
> It's alright if two threads share a token, in fact it's probably preferable
> for that to be part of my test since I'd expect to see that from real users.

If you say so - seems odd to me.
How can you tell the sessions apart?

Would a real user login to the service through two separate browsers at once?

> I still don't see how I can write to a CSV, however.  I was able to get it
> to write 1 CSV file per token, but I'm not really interested in having my
> folder get filled up with numbered csv files.  I was hoping to have it all
> in one CSV.

Use RE extractor (or similar) to put the token in a fixed named
variable, and save it to the CSV file:

http://jakarta.apache.org/jmeter/usermanual/listeners.html#sample_variables

You can configure the listener to skip just about everything else in
the sample result.

You may need to run this as a separate test in order to ensure that
the file is closed.

> As for sharing within a thread, this still isn't working for me, so I guess
> that's what I need help with.  Here's how my setup looks.
>
> ThreadGroup
> -BSF PreProcessor or Sampler (javascript) -> var myArray = new Array();
> vars.putObject("myArray",myArray);
> -Loop Controller -> 5 loops
> --HTTP Sampler
> ---Regex postprocessor -> Reference Name = myToken
> ---BSF postprocessor - > var myArray = vars.getOject("myArray");
> myArray.push(myToken);  vars.putObject("myArray",myArray);
> -BSF Sampler -> var myArray = vars.getObject("myArray");  //At this point,
> I expect myArray.length to be 5.  Instead it is 0.

BSF interpreters are not shared between samplers (or threads), but
they should be able to see a variable created earlier in the same
thread.

> Right now I'm taking the approach of serializing into a comma
> delimitted string and storing it in props, but that just feels wrong to me.

OK to use properties if you want to share read-only information across
threads; props are not really suitable for frequently updated values.

> Sebb, when you say "iteratively create a jmeter array", what do you mean?

Not guilty.

> Is there some other data structure that I'm completely missing?  I thought
> the only way you could get a jmeter array was if your single regular
> expression returned multiple matching groups...

That does not generate an array; just lots of variables with numeric suffixes.

> rather than having multiple
> runs of a thread or a loop add on to an existing array.  If there's some
> way to do that, I would love to know.

Use a pre-populated CSV data set.

> -Eric
> On Fri, Feb 10, 2012 at 8:50 AM, sebb <[hidden email]> wrote:
>
>> On 10 February 2012 16:26, Bruce Ide <[hidden email]> wrote:
>> > In the same thread you can use vars.putObject in a bsf or beanshell
>> sampler
>> > to store an array in a variable. Or you can just iteratively create a
>> > jmeter array.
>> >
>> > I wrote an addon to allow sharing across threads, see
>> > https://github.com/FlyingRhenquest/JmeterThreadGlobal. It's a pretty
>> simple
>> > addon and isn't currently set up to share arbitrary objects, but it
>> should
>> > be easy to modify to do that.
>> >
>> > If you used the new setup things you shouldn't have to synchronize
>> between
>> > the threads. If it turns out you need to, you can use a synchronizing
>> timer
>> > or my thread synchronization sampler (Which is also on github.)
>> >
>> > All this does add quite a bit of complexity to the test though, so if
>> > you're ever going to need to explain it to another tester you might want
>> to
>> > simplify your test design.
>>
>> Very good point.
>>
>> Why not create CSV data files containing the tokens in a separate test
>> phase?
>> You can then randomise the data file if you want.
>>
>> By the way, you say each thread picks a random token.
>> If you have multiple threads, a simple random choice will sometimes
>> result in two threads having the same token.
>> Is that allowed? If not, the token entries will have to be marked as
>> used; this will necessarily entail synchronising across threads.
>>
>> The CSV data file can be set to only be used once; threads cannot then
>> get the same token (unless it is duplicated in the file).
>>
>> If you have hundreds or thousands of tokens, using a data file is the way
>> to go.
>>
>> > --
>> > Bruce Ide
>> > [hidden email]
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [hidden email]
>> For additional commands, e-mail: [hidden email]
>>
>>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Loading...