Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#include <iostream>
#include <cassert>
using namespace std;
#include "pictapi.h"
#define PAIRWISE 2
#define checkNull( x ) \
if( NULL == x ) \
{ \
wcout << L"Error: Out of memory" << endl; \
goto cleanup; \
}
#define checkRetCode( x ) \
switch( x ) \
{ \
case PICT_SUCCESS: \
break; \
case PICT_OUT_OF_MEMORY: \
wcout << L"Error: Out of memory" << endl; \
goto cleanup; \
case PICT_GENERATION_ERROR: \
wcout << L"Error: Internal engine error" << endl; \
goto cleanup; \
default: \
assert( ! L"Unexpected error code" ); \
goto cleanup; \
}
void __cdecl wmain()
{
PICT_RET_CODE ret = PICT_SUCCESS;
PICT_HANDLE task = PictCreateTask();
checkNull( task );
//
// In a general case, models might form a tree-like hierarchy
// Let's try with only one model for now, pairwise is default
//
PICT_HANDLE model = PictCreateModel();
checkNull( model );
//
// The root of the model tree should be attached to the task
// In this simple case, we will attach the only model we have
//
PictSetRootModel( task, model );
//
// We will add five parameters with different number of values
// to the model. Let's store pointers to our parameters since
// we will use them to define exclusions.
//
// The order of combinations for each parameter must be greater
// than 0 and less or equal the number of parameters defined
// in the model, we will use order = 2, i.e. pairwise.
//
// An array of weights determines which values are more likely
// to be picked.
//
// The order of calls here determines the order of values in
// the resulting test cases.
//
unsigned int weights[] = {1, 2, 1, 1};
PICT_HANDLE p1 = PictAddParameter( model, 4, PAIRWISE, weights );
checkNull( p1 );
PICT_HANDLE p2 = PictAddParameter( model, 3, PAIRWISE );
checkNull( p2 );
PICT_HANDLE p3 = PictAddParameter( model, 5, PAIRWISE );
checkNull( p3 );
PICT_HANDLE p4 = PictAddParameter( model, 2, PAIRWISE );
checkNull( p4 );
PICT_HANDLE p5 = PictAddParameter( model, 4, PAIRWISE );
checkNull( p5 );
//
// Exclusions determine which combinations should not show up
// in the output. An exclusion is a list of param-value pairs.
// Make sure you're not exceeding a value count for each param
// when using 0-based value indices.
//
//
// Exclude a combination of
// (1st value of 1st param) and
// (1st value of 2nd param)
//
const size_t EXCLUSION_1_SIZE = 2;
PICT_EXCLUSION_ITEM excl1[ EXCLUSION_1_SIZE ];
excl1[ 0 ].Parameter = p1;
excl1[ 0 ].ValueIndex = 0;
excl1[ 1 ].Parameter = p2;
excl1[ 1 ].ValueIndex = 0;
ret = PictAddExclusion( task, excl1, EXCLUSION_1_SIZE );
checkRetCode( ret );
//
// Exclude a combination of
// (2nd value of 4th param) and
// (3rd value of 5th param)
//
const size_t EXCLUSION_2_SIZE = 2;
PICT_EXCLUSION_ITEM excl2[ EXCLUSION_2_SIZE ];
excl2[ 0 ].Parameter = p4;
excl2[ 0 ].ValueIndex = 1;
excl2[ 1 ].Parameter = p5;
excl2[ 1 ].ValueIndex = 2;
ret = PictAddExclusion( task, excl2, EXCLUSION_2_SIZE );
checkRetCode( ret );
//
// Seeding rows tell the engine which combinations must appear
// in the output. If they don't violate exclusions, of course.
// Let's add one of those; it is similar to adding exclusions.
//
//
// Make sure that a test case where all parameters are set to
// their 2nd values is present in the generated output. Again
// the 0-based indices cannot go beyond the number of possible
// values for any of the parameters.
//
const size_t SEED_1_SIZE = 5;
PICT_SEED_ITEM seed1[ SEED_1_SIZE ];
seed1[ 0 ].Parameter = p1;
seed1[ 0 ].ValueIndex = 1;
seed1[ 1 ].Parameter = p2;
seed1[ 1 ].ValueIndex = 1;
seed1[ 2 ].Parameter = p3;
seed1[ 2 ].ValueIndex = 1;
seed1[ 3 ].Parameter = p4;
seed1[ 3 ].ValueIndex = 1;
seed1[ 4 ].Parameter = p5;
seed1[ 4 ].ValueIndex = 1;
ret = PictAddSeed( task, seed1, SEED_1_SIZE );
checkRetCode( ret );
//
// The main event: generation.
//
ret = PictGenerate( task );
checkRetCode( ret );
//
// The result is a collection of rows.Each row is a collection
// of values: one value for every parameter in the order they
// were added to the models; i.e. in the order of AddParameter
// calls. We can only get one row at a time.
//
// Per exclusion 1, we should not see "0 0" as first two items
// in any row. Per exclusion 2, "1 2" will not appear as last
// two items in any of the rows. Also, per seed 1 we must see
// a test "1 1 1 1 1".
//
//
// First let's allocate a piece of memory big enough to hold a
// row. Every row of the result is of the same size because it
// contains the same number of values. Each value corresponds
// to one parameter we defined earlier.
//
// We could allocate the memory by hand since we know how many
// parameters we have in all models of the task (moreover, we
// have a handy PictGetTotalParameterCount function available)
// but PictAllocateResultBuffer can do it for us.
//
PICT_RESULT_ROW row = PictAllocateResultBuffer( task );
checkNull( row );
//
// We will get rows by repeatedly calling PictGetNextResultRow
// until it returns false. Before we do that however a call to
// PictResetResultFetching will reset the retrieval procedure.
//
// If the result fetching ever needs to be repeated for this
// task, a call to PictResetResultFetching will let us start
// over.
//
size_t paramCount = PictGetTotalParameterCount( task );
PictResetResultFetching( task );
while( PictGetNextResultRow( task, row ))
{
for( size_t index = 0; index < paramCount; ++index )
{
wcout << static_cast<unsigned int>( row[ index ] )<< L" ";
}
wcout << endl;
}
//
// Memory allocated for the buffer needs to be freed.
//
PictFreeResultBuffer( row );
cleanup:
if( model != NULL )
{
PictDeleteModel( model );
}
if( task != NULL )
{
PictDeleteTask( task );
}
};