github.com/ethersphere/bee/v2@v2.2.0/pkg/storage/storagetest/batch.go (about) 1 // Copyright 2022 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package storagetest 6 7 import ( 8 "context" 9 "errors" 10 "testing" 11 12 "github.com/ethersphere/bee/v2/pkg/storage" 13 "github.com/google/go-cmp/cmp" 14 ) 15 16 func TestBatchedStore(t *testing.T, bs storage.BatchStore) { 17 item := &obj1{Id: "id", SomeInt: 1, Buf: []byte("data")} 18 19 t.Run("duplicates are rejected", func(t *testing.T) { 20 batch := bs.Batch(context.Background()) 21 22 if err := batch.Put(item); err != nil { 23 t.Fatalf("Put(...): unexpected error: %v", err) 24 } 25 26 if err := batch.Put(item); err != nil { 27 t.Fatalf("Put(...): unexpected error: %v", err) 28 } 29 if err := batch.Commit(); err != nil { 30 t.Fatalf("Commit(): unexpected error: %v", err) 31 } 32 33 var cnt int 34 err := bs.Iterate(storage.Query{ 35 Factory: func() storage.Item { return new(obj1) }, 36 ItemProperty: storage.QueryItem, 37 }, func(r storage.Result) (bool, error) { 38 if cnt++; cnt > 1 { 39 t.Fatalf("Iterate(...): duplicate detected: %v", r.Entry) 40 } 41 42 want, have := item, r.Entry 43 if diff := cmp.Diff(want, have); diff != "" { 44 t.Errorf("Iterate(...): unexpected result: (-want +have):\n%s", diff) 45 } 46 return false, nil 47 }) 48 if err != nil { 49 t.Fatalf("Iterate(...): unexpected error: %v", err) 50 } 51 }) 52 53 t.Run("only last ops are of interest", func(t *testing.T) { 54 if err := bs.Put(item); err != nil { 55 t.Fatalf("Put(...): unexpected error: %v", err) 56 } 57 58 batch := bs.Batch(context.Background()) 59 60 if err := batch.Put(item); err != nil { 61 t.Fatalf("Put(...): unexpected error: %v", err) 62 } 63 if err := batch.Delete(item); err != nil { 64 t.Fatalf("Delete(...): unexpected error: %v", err) 65 } 66 67 if err := batch.Commit(); err != nil { 68 t.Fatalf("Commit(): unexpected error: %v", err) 69 } 70 71 err := bs.Iterate(storage.Query{ 72 Factory: func() storage.Item { return new(obj1) }, 73 ItemProperty: storage.QueryItem, 74 }, func(r storage.Result) (bool, error) { 75 t.Fatalf("expected empty store, got %v", r.Entry) 76 return true, nil 77 }) 78 if err != nil { 79 t.Fatal("iterate", err) 80 } 81 }) 82 83 t.Run("batch not reusable after commit", func(t *testing.T) { 84 batch := bs.Batch(context.Background()) 85 if err := batch.Commit(); err != nil { 86 t.Fatalf("Commit(): unexpected error: %v", err) 87 } 88 if err := batch.Commit(); err == nil { 89 t.Fatal("Commit(): expected error; have none") 90 } 91 }) 92 93 t.Run("batch not usable with expired context", func(t *testing.T) { 94 ctx, cancel := context.WithCancel(context.Background()) 95 96 batch := bs.Batch(ctx) 97 98 if err := batch.Put(item); err != nil { 99 t.Fatalf("Put(...): unexpected error: %v", err) 100 } 101 102 cancel() 103 have := batch.Commit() 104 want := context.Canceled 105 if !errors.Is(have, want) { 106 t.Fatalf("Commit(): want error: %v; have error: %v", want, have) 107 } 108 }) 109 110 t.Run("close", func(t *testing.T) { 111 err := bs.Close() 112 if err != nil { 113 t.Fatalf("failed closing: %v", err) 114 } 115 }) 116 }