 
Senior Member
Combobox permutations I am attempting to write a suite that will execute all possible permutations of a set of comboboxes on a webpage.
I have already written a function that will parse the page and create a comma delimited file including all combobxes and their selections. The file format is as follows:
column 1: combobox name
column 2: # of selections
columns 3  n: selection1, selection2, .., selectionN
For example:
The function that will parse the file and cycle through all possible permutations is below. It works when executing with 1 vuser. However, when I run the same suite using 2+ vusers, it breaks horribly. Any ideas?
 
Senior Member
Re: Combobox permutations Not exactly sure exactly what you need here  eg do you need all users to exercise all options? If so then the Global vars will be a problem. However you could use the following to have all users exercise all options:
function fncFoo(fForm:form)
var
i,j:number;
nNumberOfComboboxes:number;
sCombobox:string;
nSelections:number;
sSelection:string;
begin
nNumberOfComboboxes := FileGetNumRows(hBuildPage);
for i := 1 to nNumberOfComboboxes do
FileGetRow(hBuildPage, i);
sCombobox := FileGetCol(hBuildPage, 1, 100);
Write("sCombobox is: " + sCombobox);
nSelections := number(FileGetCol(hBuildPage, 2, 10));
Writeln("\t\tnSelections is: " + string(nSelections));
for j := 3 to nSelections+2 do //start from the third column
sSelection := FileGetCol(hBuildPage, j, 100);
writeln("WebFormValueSet [" + sCombobox + "] [" + sSelection + "] (" + string(j2) + ")");
end;
Writeln("***********************************");Wri teln;
end;
end fncFoo;
One last thing, this used a csv as follows, which is a little different to yours:
ddlMachName,5,AKRON,AMEX01,AMEX02,APOC,ASSETAPP1
ddlCategory,8,Cluster,EventLog,Heartbeat,HouseKeep ing,Legacy,LogMonitor,LogMonitoring,Network
ddlSource2,5,System,Application,Network,C:,D:
ddlSource3,3,Error,Warning,Info
 
Senior Member
Re: Combobox permutations Stronzo,
Thanks for your reply.
I don't think I accurately described my problem.
I am testing the front end (web interface) of an app that tracks system events. The app has search capabilites. These searches are performed by selecting the desired search criteria from a set of comboboxes on a webpage.
For instance, a real world example:
One search page (Events) has the following comboboxes: MachineName, Category, Detail, Type. If I wanted to search for any MachineName in the heartbeat Category, with any Detail, and warning type, I would select <Null>, "heartbeat", <Null>, "warning" from the comboboxes, respectively.
This particular webpage (Events) has 4 combobxes, each with multiple selections. MachineName has 213, Category has 13, Detail has 6 and Type has 4. This equals 66,456 possible permutations.
I was attempting to write a function that would exercise each and every possible permutation in the shortest amount of time.
I began by writing functions that would parse raw HTML data and return: 1) The total number of comboboxes on a webpage, 2) The Name of each combobox, 3) The number of selections in a given combobox, and 4) A specific selection from a specific combobox.
With those functions done, I wrote a simple Iterative function (below) that cycled through each combobox and each selection, sequentially. It worked well, but the # of comboboxes was hardcoded. The function was not reusable for webpages with +/ 4 comboboxes. The function processed about 29,478 permutations/minute.
Next, I began writing the same function using recursion (below). This enabled me to use the function for any webpage. However, it also slowed down the processing time to about 12,074 permutations/minute.
I realized that much of the processing time was due to the fact that the raw HTML data was being parsed again and again (and again!). So, I wrote a similar function (below) that would parse the raw HTML data ONCE and write the results to a comma delimited file. (Note  Due to some malformed HTML data, I wrote StrStrip, which simply searches string <X> for all occurences of char <Y> and replaces them with char <Z>.)
So, now I had a CSV file that represented the webpage. I could read the file into memory and run a similar recursive function (below) to exercise all possible permutations. This function processed about 5,298,740 permutations/minute!!
This was great...for the search page with 66,456 permutations. However, another of the search pages had 7 comboboxes with over 402 million permutations.
Back at the drawing board, I decided that the best solution was to divide and conquer via multiple vusers. However, none of the functions I had written could utilize multiple vusers!
So, I wrote the function (below) that, while it works well with 1 vuser, it seems to bomb with >1. That was the question I posed in my original post. It is also very slow, running at about 13,909 permutations/minute.
To tell the truth, besides comboboxes, many of these search pages have radio buttons, as well. If I were to factor in the radio buttons when calculating the # of possible permutations, you get into the trillions.
So, although I don't think there is any solution that will allow multiple users to exercise several trillion permutations in a reasonable amount of time, it was a fun exercise.
FYI, I have decided to tackle the problem by devising a subset of "most probable permutations" and go from there.
Sorry so long...hope it helped!

[This message has been edited by Damian Synadinos (edited 12302002).]
[This message has been edited by Damian Synadinos (edited 12302002).]
[This message has been edited by Damian Synadinos (edited 12302002).] 
Senior Member
Re: Combobox permutations Wow!
One thing you might look at is explicitly dividing up the comboboxes by virtual user. At it's simplest you could have vu 1 exercise combobox 1, vu 2 exercise combobox 2 etc. You'd need to remove the loop
for nCombobox := 1 to nNumberOfComboboxes do
and set
nCombobox := GetUserID();
You'd need to have at least as many vus as you have comboboxes and you need to make sure that those vus where GetUserID() > nNumberOfComboboxes don't do anything.
To break it down further you could also explicitly divide nSelections by virtual user. For example, say that vus 1 to 20 handle ComboBox 1 and vu 1 handles nselection 1, vu 2 handles nselection 2 etc. vus 21 to 40 handle combobox 2 with vu 21 exercising nSelection 1 etc. That is:
vu 1 Combobox 1, Selection 1
vu 2 Combobox 1, Selection 2
vu 3 Combobox 1, Selection 3
...
vu 21 Combobox 2, Selection 1
vu 22 Combobox 2, Selection 2
..
vu 41 Combobox 3, Selection 1
vu 42 Combobox 3, Selection 2
etc
Of course it starts to get a bit complicated with handling exceptions etc but it looks like you're not afraid of a bit of coding...

[This message has been edited by Stronzo (edited 01062003).] 
Senior Member
Re: Combobox permutations Stronzo,
Thanks again!
I'm a little confused by your suggestions. I think that dividing up the task by vu is an excellent approach, however, I don't quite understand how you propose to do it.
Picture 3 comboboxes and their selections (below):
Combobox1  A, B, C
Combobox2  W, X, Y, Z
Combobox3  1, 2, 3
Using your method (each vu exercises a single combobox), it seems that I would submit forms containing the following permutations (3+4+3=10):
vu1 (exercises all Combobox1 selections)  AW1, BW1, CW1
vu2 (exercises all Combobox2 selections)  AW1, AX1, AY1, AZ1
vu3 (exercises all Combobox3 selections)  AW1, AW2, AW3
However, what I am actually looking for is each and every permutation (3*4*3=36):
AW1, AW2, AW3
AX1, AX2, AX3
AY1, AY2, AY3
AZ1, AZ2, AZ3
BW1, BW2, BW3
BX1, BX2, BX3
BY1, BY2, BY3
BZ1, BZ2, BZ3
CW1, CW2, CW3
CX1, CX2, CX3
CY1, CY2, CY3
CZ1, CZ2, CZ3
I hope this makes sense.
Although I'm pretty sure that I will be resigned to approach this by using a select sample of the entire set, I am still interesting in seeing if this method can be done.
Thanks again!
 
Senior Member
Re: Combobox permutations Right, sorry, that logic was wrong, but I think that the general approach may still be useful.
You could for example identify the Combobox with the largest number of selections and use it as the item set per vu. In the example above this is ComboBox 2 so you would have the following:
vu1  W + all combinations of ComboBox1 & ComboBox3
vu2  X + all combinations of ComboBox1 & ComboBox3
vu3  Y + all combinations of ComboBox1 & ComboBox3
vu4  Z + all combinations of ComboBox1 & ComboBox3
vu5  does nothing
vu6  does nothing
To take it one step further, you could use the top 2 comboboxes (2 then 1 in the example) giving you:
vu1  W + A + all combinations of ComboBox3
vu2  W + B + all combinations of ComboBox3
vu3  W + C + all combinations of ComboBox3
vu4  X + A + all combinations of ComboBox3
vu5  X + B + all combinations of ComboBox3
vu6  X + C + all combinations of ComboBox3
vu7  Y + A + all combinations of ComboBox3
vu8  Y + B + all combinations of ComboBox3
vu9  Y + C + all combinations of ComboBox3
vu10  Z + A + all combinations of ComboBox3
vu11  Z + B + all combinations of ComboBox3
vu12  Z + C + all combinations of ComboBox3
vu13 does nothing
There is probably some nice matrix model or algorithm which describes just this somewhere...
Anyway, coding to use the top 2 should be relatively easy.
If you assume that
nFirstSelections = the number of selections for the combobox with the largest number of selections
and
nSecondselections = the number of selections for the combobox with the second largest number of selections
then your basic control to divide up the combinations by vu would be:
I didn't fully check the code, but it is not far off being right. With a bit of error handling this should be fairly extendible.

[This message has been edited by Stronzo (edited 01092003).]
Posting Permissions
 You may not post new threads
 You may not post replies
 You may not post attachments
 You may not edit your posts

Forum Rules 