Skip to content

Commit d85e88d

Browse files
authored
Merge pull request #21488 from serathius/robustness-benmarks
Improve robustness benchmarks
2 parents 50f4ea2 + c6a5c57 commit d85e88d

File tree

2 files changed

+91
-22
lines changed

2 files changed

+91
-22
lines changed

tests/robustness/model/replay.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,18 @@ import (
1818
"fmt"
1919
"sort"
2020
"strings"
21+
22+
"github.com/anishathalye/porcupine"
2123
)
2224

25+
func NewReplayFromOperations(ops []porcupine.Operation) *EtcdReplay {
26+
requests := []EtcdRequest{}
27+
for _, op := range ops {
28+
requests = append(requests, op.Input.(EtcdRequest))
29+
}
30+
return NewReplay(requests)
31+
}
32+
2333
func NewReplay(persistedRequests []EtcdRequest) *EtcdReplay {
2434
state := freshEtcdState()
2535
// Padding for index 0 and 1, so the index matches the revision.

tests/robustness/validate/operations_test.go

Lines changed: 81 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -296,56 +296,60 @@ func keyValueRevision(key, value string, rev int64) model.KeyValue {
296296

297297
func 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

Comments
 (0)