Skip to content
File

Blob: spec/chord/retry_test.go

go66 lines
1package chord
2 
3import (
4 "context"
5 "testing"
6 "time"
7 
8 "github.com/stretchr/testify/require"
9)
10 
11type retryTestNode struct {
12 VNode
13 get func(context.Context, []byte) ([]byte, error)
14}
15 
16func (n *retryTestNode) Get(ctx context.Context, key []byte) ([]byte, error) {
17 return n.get(ctx, key)
18}
19 
20func TestRetryKVPreservesAttemptsValuesAndErrors(t *testing.T) {
21 for _, tc := range []struct {
22 name string
23 results []error
24 wantErr error
25 }{
26 {name: "retry stale ownership", results: []error{ErrKVStaleOwnership, nil}},
27 {name: "stop on conflict", results: []error{ErrKVSimpleConflict}, wantErr: ErrKVSimpleConflict},
28 {name: "return final error", results: []error{ErrKVStaleOwnership, ErrKVPendingTransfer, ErrKVPendingTransfer}, wantErr: ErrKVPendingTransfer},
29 } {
30 t.Run(tc.name, func(t *testing.T) {
31 calls := 0
32 node := &retryTestNode{get: func(ctx context.Context, key []byte) ([]byte, error) {
33 require.Equal(t, []byte("key"), key)
34 require.NoError(t, ctx.Err())
35 if calls >= len(tc.results) {
36 t.Fatal("retried after the expected final attempt")
37 }
38 err := tc.results[calls]
39 calls++
40 return []byte{}, err
41 }}
42 value, err := WrapRetryKV(node, time.Nanosecond, 3).Get(t.Context(), []byte("key"))
43 require.Equal(t, tc.wantErr, err, "errors must remain directly comparable")
44 require.Equal(t, len(tc.results), calls)
45 if err == nil {
46 require.NotNil(t, value, "successful empty values must stay distinct from missing values")
47 require.Empty(t, value)
48 }
49 })
50 }
51}
52 
53func TestRetryKVCancellationStopsBackoff(t *testing.T) {
54 ctx, cancel := context.WithCancel(t.Context())
55 defer cancel()
56 calls := 0
57 node := &retryTestNode{get: func(context.Context, []byte) ([]byte, error) {
58 calls++
59 cancel()
60 return nil, ErrKVStaleOwnership
61 }}
62 _, err := WrapRetryKV(node, time.Hour, 3).Get(ctx, []byte("key"))
63 require.ErrorIs(t, err, context.Canceled)
64 require.Equal(t, 1, calls)
65}