@@ -296,56 +296,60 @@ func keyValueRevision(key, value string, rev int64) model.KeyValue {
296296
297297func BenchmarkValidateLinearizableOperations (b * testing.B ) {
298298 lg := zap .NewNop ()
299- b .Run ("Successes " , func (b * testing.B ) {
300- history := allPutSuccesses ( 1000 )
299+ b .Run ("SequentialSuccessPuts " , func (b * testing.B ) {
300+ history := sequentialSuccessPuts ( 7000 , 2 )
301301 shuffles := shuffleHistory (history , b .N )
302302 b .ResetTimer ()
303303 validateShuffles (b , lg , shuffles , time .Second )
304304 })
305- b .Run ("AllFailures " , func (b * testing.B ) {
306- history := allPutFailures ( 10 )
305+ b .Run ("SequentialFailedPuts " , func (b * testing.B ) {
306+ history := sequentialFailedPuts ( 14 , 1 )
307307 shuffles := shuffleHistory (history , b .N )
308308 b .ResetTimer ()
309309 validateShuffles (b , lg , shuffles , time .Second )
310310 })
311- b .Run ("PutFailuresWithRead " , func (b * testing.B ) {
312- history := putFailuresWithRead (b , 8 )
311+ b .Run ("ConcurrentFailedPutsWithRead " , func (b * testing.B ) {
312+ history := concurrentFailedPutsWithRead (b , 13 )
313313 shuffles := shuffleHistory (history , b .N )
314314 b .ResetTimer ()
315315 validateShuffles (b , lg , shuffles , time .Second )
316316 })
317+ b .Run ("BacktrackingHeavy" , func (b * testing.B ) {
318+ history := backtrackingHeavy (b )
319+ shuffles := shuffleHistory (history , b .N )
320+ b .ResetTimer ()
321+ for i := 0 ; i < len (shuffles ); i ++ {
322+ validateLinearizableOperationsAndVisualize (lg , shuffles [i ], time .Second )
323+ }
324+ })
317325}
318326
319- func allPutSuccesses ( concurrencyCount int ) []porcupine.Operation {
327+ func sequentialSuccessPuts ( count int , startRevision int64 ) []porcupine.Operation {
320328 ops := []porcupine.Operation {}
321- for i := 0 ; i < concurrencyCount ; i ++ {
329+ for i := 0 ; i < count ; i ++ {
322330 ops = append (ops , porcupine.Operation {
323331 ClientId : i ,
324332 Input : putRequest ("key" , "value" ),
325- Output : txnResponse (int64 (i )+ 2 , model.EtcdOperationResult {}),
326- Call : int64 (i ),
327- Return : int64 (i ) + int64 ( concurrencyCount ),
333+ Output : txnResponse (startRevision + int64 (i ), model.EtcdOperationResult {}),
334+ Call : int64 (i * 2 ),
335+ Return : int64 (i * 2 + 1 ),
328336 })
329337 }
330338 return ops
331339}
332340
333- func putFailuresWithRead (b * testing.B , concurrencyCount int ) []porcupine.Operation {
341+ func concurrentFailedPutsWithRead (b * testing.B , concurrencyCount int ) []porcupine.Operation {
334342 ops := []porcupine.Operation {}
335343 for i := 0 ; i < concurrencyCount ; i ++ {
336344 ops = append (ops , porcupine.Operation {
337345 ClientId : i ,
338- Input : putRequest (fmt . Sprintf ( "key%d" , i ) , "value" ),
346+ Input : putRequest ("key" , "value" ),
339347 Output : errorResponse (fmt .Errorf ("timeout" )),
340348 Call : int64 (i ),
341349 Return : int64 (i ) + int64 (concurrencyCount ),
342350 })
343351 }
344- requests := []model.EtcdRequest {}
345- for _ , op := range ops {
346- requests = append (requests , op .Input .(model.EtcdRequest ))
347- }
348- replay := model .NewReplay (requests )
352+ replay := model .NewReplayFromOperations (ops )
349353 state , err := replay .StateForRevision (int64 (concurrencyCount ) + 1 )
350354 if err != nil {
351355 b .Fatal (err )
@@ -362,17 +366,72 @@ func putFailuresWithRead(b *testing.B, concurrencyCount int) []porcupine.Operati
362366 return ops
363367}
364368
365- func allPutFailures ( concurrencyCount int ) []porcupine.Operation {
369+ func sequentialFailedPuts ( count int , keyCount int ) []porcupine.Operation {
366370 ops := []porcupine.Operation {}
367- for i := 0 ; i < concurrencyCount ; i ++ {
371+ for i := 0 ; i < count ; i ++ {
372+ key := "key0"
373+ if keyCount > 1 {
374+ key = fmt .Sprintf ("key%d" , i % keyCount )
375+ }
368376 ops = append (ops , porcupine.Operation {
369377 ClientId : i ,
370- Input : putRequest (" key" , "value" ),
378+ Input : putRequest (key , "value" ),
371379 Output : errorResponse (fmt .Errorf ("timeout" )),
380+ Call : int64 (i * 2 ),
381+ Return : int64 (i * 2 + 1 ),
382+ })
383+ }
384+ return ops
385+ }
386+
387+ func backtrackingHeavy (b * testing.B ) (ops []porcupine.Operation ) {
388+ for i := 0 ; i < 30 ; i ++ {
389+ ops = append (ops , porcupine.Operation {
390+ ClientId : - 1 ,
391+ Input : putRequest (fmt .Sprintf ("key%d" , i + 1000 ), "value" ),
392+ Output : txnResponse (int64 (i + 2 ), model.EtcdOperationResult {}),
372393 Call : int64 (i ),
373- Return : int64 (i ) + int64 (concurrencyCount ),
394+ Return : int64 (i ) + 1 ,
395+ })
396+ }
397+ startTime := int64 (1000 )
398+
399+ failedPuts := 4
400+ for i := 0 ; i < failedPuts ; i ++ {
401+ ops = append (ops , porcupine.Operation {
402+ ClientId : i ,
403+ Input : putRequest (fmt .Sprintf ("key%d" , i ), "value" ),
404+ Output : errorResponse (fmt .Errorf ("timeout" )),
405+ Call : startTime + int64 (i ),
406+ Return : startTime + 1000 + int64 (i ),
407+ })
408+ }
409+ replay := model .NewReplayFromOperations (ops )
410+ state , err := replay .StateForRevision (int64 (30 + 1 ))
411+ if err != nil {
412+ b .Fatal (err )
413+ }
414+
415+ concurrentReads := 3
416+ for i := 0 ; i < concurrentReads ; i ++ {
417+ request := rangeRequest (fmt .Sprintf ("key%d" , i ), "" , 0 , 0 )
418+ _ , resp := state .Step (request )
419+ ops = append (ops , porcupine.Operation {
420+ ClientId : failedPuts + i ,
421+ Input : request ,
422+ Output : resp ,
423+ Call : startTime + 1100 ,
424+ Return : startTime + 2100 ,
374425 })
375426 }
427+
428+ ops = append (ops , porcupine.Operation {
429+ ClientId : 99 ,
430+ Input : rangeRequest ("key0" , "" , 0 , 0 ),
431+ Output : rangeResponse (0 , keyValueRevision ("key0" , "wrong" , 9999 )),
432+ Call : startTime + 3000 ,
433+ Return : startTime + 4000 ,
434+ })
376435 return ops
377436}
378437
0 commit comments