github.com/koko1123/flow-go-1@v0.29.6/storage/badger/operation/modifiers_test.go (about) 1 // (c) 2019 Dapper Labs - ALL RIGHTS RESERVED 2 3 package operation 4 5 import ( 6 "errors" 7 "fmt" 8 "testing" 9 10 "github.com/dgraph-io/badger/v3" 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 "github.com/vmihailenco/msgpack/v4" 14 15 "github.com/koko1123/flow-go-1/storage" 16 "github.com/koko1123/flow-go-1/utils/unittest" 17 ) 18 19 func TestSkipDuplicates(t *testing.T) { 20 unittest.RunWithBadgerDB(t, func(db *badger.DB) { 21 e := Entity{ID: 1337} 22 key := []byte{0x01, 0x02, 0x03} 23 val, _ := msgpack.Marshal(e) 24 25 // persist first time 26 err := db.Update(insert(key, e)) 27 require.NoError(t, err) 28 29 e2 := Entity{ID: 1338} 30 31 // persist again 32 err = db.Update(SkipDuplicates(insert(key, e2))) 33 require.NoError(t, err) 34 35 // ensure old value is still used 36 var act []byte 37 _ = db.View(func(tx *badger.Txn) error { 38 item, err := tx.Get(key) 39 require.NoError(t, err) 40 act, err = item.ValueCopy(nil) 41 require.NoError(t, err) 42 return nil 43 }) 44 45 assert.Equal(t, val, act) 46 }) 47 } 48 49 func TestRetryOnConflict(t *testing.T) { 50 unittest.RunWithBadgerDB(t, func(db *badger.DB) { 51 t.Run("good op", func(t *testing.T) { 52 goodOp := func(*badger.Txn) error { 53 return nil 54 } 55 err := RetryOnConflict(db.Update, goodOp) 56 require.NoError(t, err) 57 }) 58 59 t.Run("conflict op should be retried", func(t *testing.T) { 60 n := 0 61 conflictOp := func(*badger.Txn) error { 62 n++ 63 if n > 3 { 64 return nil 65 } 66 return badger.ErrConflict 67 } 68 err := RetryOnConflict(db.Update, conflictOp) 69 require.NoError(t, err) 70 }) 71 72 t.Run("wrapped conflict op should be retried", func(t *testing.T) { 73 n := 0 74 conflictOp := func(*badger.Txn) error { 75 n++ 76 if n > 3 { 77 return nil 78 } 79 return fmt.Errorf("wrap error: %w", badger.ErrConflict) 80 } 81 err := RetryOnConflict(db.Update, conflictOp) 82 require.NoError(t, err) 83 }) 84 85 t.Run("other error should be returned", func(t *testing.T) { 86 otherError := errors.New("other error") 87 failOp := func(*badger.Txn) error { 88 return otherError 89 } 90 91 err := RetryOnConflict(db.Update, failOp) 92 require.Equal(t, otherError, err) 93 }) 94 }) 95 } 96 97 func TestSkipNonExists(t *testing.T) { 98 unittest.RunWithBadgerDB(t, func(db *badger.DB) { 99 t.Run("not found", func(t *testing.T) { 100 op := func(*badger.Txn) error { 101 return badger.ErrKeyNotFound 102 } 103 104 err := db.Update(SkipNonExist(op)) 105 require.NoError(t, err) 106 }) 107 108 t.Run("not exist", func(t *testing.T) { 109 op := func(*badger.Txn) error { 110 return storage.ErrNotFound 111 } 112 113 err := db.Update(SkipNonExist(op)) 114 require.NoError(t, err) 115 }) 116 117 t.Run("general error", func(t *testing.T) { 118 expectError := fmt.Errorf("random error") 119 op := func(*badger.Txn) error { 120 return expectError 121 } 122 123 err := db.Update(SkipNonExist(op)) 124 require.Equal(t, expectError, err) 125 }) 126 }) 127 }