@@ -32,7 +32,7 @@ import (
32
32
//ShadowCCIntf interfaces to be implemented by shadow chaincodes
33
33
type ShadowCCIntf interface {
34
34
//InitShadowCC initializes the shadow chaincode (will be called once for each chaincode)
35
- InitShadowCC ()
35
+ InitShadowCC (initArgs [] string )
36
36
37
37
//GetInvokeArgs gets invoke arguments from shadow
38
38
GetInvokeArgs (ccnum int , iter int ) [][]byte
@@ -45,22 +45,31 @@ type ShadowCCIntf interface {
45
45
46
46
//Validate the results against the query arguments
47
47
Validate (args [][]byte , value []byte ) error
48
+
49
+ //GetNumQueries returns number of queries to perform
50
+ GetNumQueries (numSuccessfulInvokes int ) int
51
+
52
+ //OverrideNumInvokes overrides the users number of invoke request
53
+ OverrideNumInvokes (numInvokesPlanned int ) int
48
54
}
49
55
50
- //CC chaincode properties, config and runtime
51
- type CC struct {
56
+ //CCClient chaincode properties, config and runtime
57
+ type CCClient struct {
52
58
//-------------config properties ------------
53
59
//Name of the chaincode
54
60
Name string
55
61
62
+ //InitArgs used for deploying the chaincode
63
+ InitArgs []string
64
+
56
65
//Path to the chaincode
57
66
Path string
58
67
59
68
//NumFinalQueryAttempts number of times to try final query before giving up
60
69
NumFinalQueryAttempts int
61
70
62
- //NumberOfInvokeIterations number of iterations to do invoke on
63
- NumberOfIterations int
71
+ //NumberOfInvokes number of iterations to do invoke on
72
+ NumberOfInvokes int
64
73
65
74
//DelayBetweenInvokeMs delay between each invoke
66
75
DelayBetweenInvokeMs int
@@ -87,14 +96,22 @@ type CC struct {
87
96
//shadow CC where the chaincode stats is maintained
88
97
shadowCC ShadowCCIntf
89
98
99
+ //number of iterations a shadow cc actually wants
100
+ //this could be different from NumberOfInvokes
101
+ overriddenNumInvokes int
102
+
103
+ //numer of queries to perform
104
+ //retrieved from the shadow CC
105
+ numQueries int
106
+
90
107
//current iteration of invoke
91
108
currentInvokeIter int
92
109
93
110
//start of invokes in epoch seconds
94
- invokeStartTime int
111
+ invokeStartTime int64
95
112
96
113
//end of invokes in epoch seconds
97
- invokeEndTime int
114
+ invokeEndTime int64
98
115
99
116
//error that stopped invoke iterations
100
117
invokeErr error
@@ -109,7 +126,7 @@ type CC struct {
109
126
queryErrs []error
110
127
}
111
128
112
- func (cc * CC ) getChaincodeSpec (args [][]byte ) * pb.ChaincodeSpec {
129
+ func (cc * CCClient ) getChaincodeSpec (args [][]byte ) * pb.ChaincodeSpec {
113
130
return & pb.ChaincodeSpec {
114
131
Type : pb .ChaincodeSpec_Type (pb .ChaincodeSpec_Type_value [cc .Lang ]),
115
132
ChaincodeID : & pb.ChaincodeID {Path : cc .Path , Name : cc .Name },
@@ -120,12 +137,15 @@ func (cc *CC) getChaincodeSpec(args [][]byte) *pb.ChaincodeSpec {
120
137
//doInvokes calls invoke for each iteration for the chaincode
121
138
//Stops at the first invoke with error
122
139
//currentInvokeIter contains the number of successful iterations
123
- func (cc * CC ) doInvokes (ctxt context.Context , chainID string ,
140
+ func (cc * CCClient ) doInvokes (ctxt context.Context , chainID string ,
124
141
bc common.BroadcastClient , ec pb.EndorserClient , signer msp.SigningIdentity ,
125
142
wg * sync.WaitGroup , quit func () bool ) error {
126
143
144
+ //perhaps the shadow CC wants to override the number of iterations
145
+ cc .overriddenNumInvokes = cc .shadowCC .OverrideNumInvokes (cc .NumberOfInvokes )
146
+
127
147
var err error
128
- for cc .currentInvokeIter = 0 ; cc .currentInvokeIter < cc .NumberOfIterations ; cc .currentInvokeIter ++ {
148
+ for cc .currentInvokeIter = 0 ; cc .currentInvokeIter < cc .overriddenNumInvokes ; cc .currentInvokeIter ++ {
129
149
if quit () {
130
150
break
131
151
}
@@ -154,7 +174,7 @@ func (cc *CC) doInvokes(ctxt context.Context, chainID string,
154
174
}
155
175
156
176
//don't sleep for the last iter
157
- if cc .DelayBetweenInvokeMs > 0 && cc .currentInvokeIter < (cc .NumberOfIterations - 1 ) {
177
+ if cc .DelayBetweenInvokeMs > 0 && cc .currentInvokeIter < (cc .overriddenNumInvokes - 1 ) {
158
178
time .Sleep (time .Duration (cc .DelayBetweenInvokeMs ) * time .Millisecond )
159
179
}
160
180
}
@@ -165,7 +185,7 @@ func (cc *CC) doInvokes(ctxt context.Context, chainID string,
165
185
//Run test over given number of iterations
166
186
// i will be unique across chaincodes and can be used as a key
167
187
// this is useful if chaincode occurs multiple times in the array of chaincodes
168
- func (cc * CC ) Run (ctxt context.Context , chainID string , bc common.BroadcastClient , ec pb.EndorserClient , signer msp.SigningIdentity , wg * sync.WaitGroup ) error {
188
+ func (cc * CCClient ) Run (ctxt context.Context , chainID string , bc common.BroadcastClient , ec pb.EndorserClient , signer msp.SigningIdentity , wg * sync.WaitGroup ) error {
169
189
defer wg .Done ()
170
190
171
191
var (
@@ -181,12 +201,12 @@ func (cc *CC) Run(ctxt context.Context, chainID string, bc common.BroadcastClien
181
201
quitF := func () bool { return quit }
182
202
183
203
//start of invokes
184
- cc .invokeStartTime = time .Now ().Second ()
204
+ cc .invokeStartTime = time .Now ().UnixNano () / 1000000
185
205
186
206
err = cc .doInvokes (ctxt , chainID , bc , ec , signer , wg , quitF )
187
207
188
208
//end of invokes
189
- cc .invokeEndTime = time .Now ().Second ()
209
+ cc .invokeEndTime = time .Now ().UnixNano () / 1000000
190
210
}()
191
211
192
212
//we could be done or cancelled or timedout
@@ -203,7 +223,7 @@ func (cc *CC) Run(ctxt context.Context, chainID string, bc common.BroadcastClien
203
223
}
204
224
205
225
//validates the invoke iteration for this chaincode
206
- func (cc * CC ) validateIter (ctxt context.Context , iter int , chainID string , bc common.BroadcastClient , ec pb.EndorserClient , signer msp.SigningIdentity , wg * sync.WaitGroup , quit func () bool ) {
226
+ func (cc * CCClient ) validateIter (ctxt context.Context , iter int , chainID string , bc common.BroadcastClient , ec pb.EndorserClient , signer msp.SigningIdentity , wg * sync.WaitGroup , quit func () bool ) {
207
227
defer wg .Done ()
208
228
args := cc .shadowCC .GetQueryArgs (cc .ID , iter )
209
229
@@ -253,7 +273,7 @@ func (cc *CC) validateIter(ctxt context.Context, iter int, chainID string, bc co
253
273
}
254
274
255
275
//Validate test that was Run. Each successful iteration in the run is validated against
256
- func (cc * CC ) Validate (ctxt context.Context , chainID string , bc common.BroadcastClient , ec pb.EndorserClient , signer msp.SigningIdentity , wg * sync.WaitGroup ) error {
276
+ func (cc * CCClient ) Validate (ctxt context.Context , chainID string , bc common.BroadcastClient , ec pb.EndorserClient , signer msp.SigningIdentity , wg * sync.WaitGroup ) error {
257
277
defer wg .Done ()
258
278
259
279
//this will signal inner validators to get out via
@@ -280,8 +300,10 @@ func (cc *CC) Validate(ctxt context.Context, chainID string, bc common.Broadcast
280
300
//return the quit closure for validation within validateIter
281
301
quitF := func () bool { return quit }
282
302
303
+ cc .numQueries = cc .shadowCC .GetNumQueries (cc .currentInvokeIter )
304
+
283
305
//try only till successful invoke iterations
284
- for i := 0 ; i < cc .currentInvokeIter ; i ++ {
306
+ for i := 0 ; i < cc .numQueries ; i ++ {
285
307
go func (iter int ) {
286
308
cc .validateIter (ctxt , iter , chainID , bc , ec , signer , & innerwg , quitF )
287
309
}(i )
@@ -317,22 +339,22 @@ func (cc *CC) Validate(ctxt context.Context, chainID string, bc common.Broadcast
317
339
}
318
340
319
341
//Report reports chaincode test execution, iter by iter
320
- func (cc * CC ) Report (verbose bool , chainID string ) {
342
+ func (cc * CCClient ) Report (verbose bool , chainID string ) {
321
343
fmt .Printf ("%s/%s(%d)\n " , cc .Name , chainID , cc .ID )
322
- fmt .Printf ("\t Num successful invokes: %d(%d)\n " , cc .currentInvokeIter , cc .NumberOfIterations )
344
+ fmt .Printf ("\t Num successful invokes: %d(%d,%d )\n " , cc .currentInvokeIter , cc .NumberOfInvokes , cc . overriddenNumInvokes )
323
345
if cc .invokeErr != nil {
324
346
fmt .Printf ("\t Error on invoke: %s\n " , cc .invokeErr )
325
347
}
326
348
//test to see if validate was called (validate alloc the arrays, one of which is queryWorked)
327
349
if cc .queryWorked != nil {
328
- for i := 0 ; i < cc .currentInvokeIter ; i ++ {
350
+ for i := 0 ; i < cc .numQueries ; i ++ {
329
351
fmt .Printf ("\t Query(%d) : succeeded-%t, num trials-%d(%d), error if any(%s)\n " , i , cc .queryWorked [i ], cc .currQueryIter [i ], cc .NumFinalQueryAttempts , cc .queryErrs [i ])
330
352
}
331
353
} else {
332
354
fmt .Printf ("\t Query validation appears not have been performed(#invokes-%d). timed out ?\n " , cc .currentInvokeIter )
333
355
}
334
356
//total actual time for cc.currentInvokeIter
335
- invokeTime := ( cc .invokeEndTime - cc .invokeStartTime ) * 1000 - (cc .DelayBetweenInvokeMs * (cc .currentInvokeIter - 1 ))
357
+ invokeTime := cc .invokeEndTime - cc .invokeStartTime - int64 (cc .DelayBetweenInvokeMs * (cc .currentInvokeIter - 1 ))
336
358
fmt .Printf ("\t Time for invokes(ms): %d\n " , invokeTime )
337
359
338
360
fmt .Printf ("\t Final query worked ? %t\n " , cc .queryWorked )
0 commit comments