Reputation: 319
I have a case where a particular API needs to be called only once to initialize. Thereafter threads can call the other methods. In vuser_init.c, I have this:
static volatile int initOnlyOnce = 0;
static volatile int initComplete = 0;
int iStatus;
if (1!=initOnlyOnce ) {
initOnlyOnce =1;
lr_output_message("Before, initComplete = %d", initComplete );
iStatus = Initialize(); // product API call
initComplete = 1;
lr_output_message("After, initComplete = %d", initComplete );
if (1 != iStatus ) {
lr_error_message("Initialize returns %d on %s.",iStatus,szLoadGenerator);
srand(time(NULL));
}
}
When I run the scenario, the first thread prints both, i.e.
Before, initComplete = 0
followed by
After, initComplete = 1
and the rest of the test is done in that thread, correctly. However, the next thread fails with "Error -- memory violation : Exception ACCESS_VIOLATION received" because it has executed a subsequent method without the Initialize being completed or initComplete was 0. The logs for each of the other threads have "Before, initComplete = 0" as the last line. Since I have defined these variables as static volatile, I expected that
initOnlyOnce = 1
right after the first thread called it and subsequently this block of code would not be entered again. However, it seems that Vugen is not the same as a thread. Each vuser_init.c is independent of the other Vugens running and so the state is not shared although variables are declared static volatile.
Is there a workaround? I essentially want a singleton precursor to the vuser_init.
Upvotes: 0
Views: 1704
Reputation: 1394
The way LoadRunner executes virtual users is not so easy to understand, and much less something you should depend upon.
In most cases the vu's are running as threads, under a special MMDRV process. The MMDRV process runs some 50 threads, and then the LR engine starts another MMDRV process that again runs 50 threads. (You can also run VUsers as a process each, have a look in run-time settings).
Also if you have LoadGenerators in your test, these are executing on different computers and have no way of knowing how many vusers are running on other machines.
As James stated, using the VUserID as the "check" is the best option here if you want to do it in code. To get the VUserID as a new parameter called "VUserID" and select the type as VUserID. You can then use this with lr_eval_string("{VUserID}")
as you would any other param.
Another option is running the scenario in a mode where one script is first executed, and then the others.
Upvotes: 1
Reputation: 5682
I would just use a virtual user number variable and check to see if the number was 1.
PCODE (in the init)
If (Value of Virtual User variable == 1) { Run intialization code; }
So, you would need to create the variable and then perhaps assign a single virtual user to only handle the intialization and then exit. Place this user in a group by itself and then perhaps even exit before the other users start.
You can add other functions scheduled to start before the VUSER_INIT() if you wish. Add the functions in the function list on the right then go into the run time setting and schedule your function to run once, before the vuser_init().
Upvotes: 1