github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/store/batch_test.go (about) 1 // Copyright (c) 2023 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package store 19 20 import ( 21 "errors" 22 "sync" 23 "testing" 24 ) 25 26 func TestBatch(t *testing.T) { 27 var limit uint32 = 100 28 batch := NewBatch[int, int](limit) 29 for i := 0; i < int(limit); i++ { 30 if err := batch.Add(i, i); err != nil { 31 t.Fatalf("failed to add %v; %v", i, err) 32 } 33 if _, ok := batch.GetByKey(i); !ok { 34 t.Fatalf("failed to get the item by key %v after adding", i) 35 } 36 } 37 err := batch.Add(101, 101) 38 if err == nil || !errors.Is(err, ErrBatchFull) { 39 t.Fatalf("Expected err %v but got %v", ErrBatchFull, err) 40 } 41 if !batch.IsFull() { 42 t.Fatal("Expected batch.IsFull to be true but got false") 43 } 44 batchLen := batch.Len() 45 if batchLen != int(limit) { 46 t.Fatalf("expected batch length to be %v but got %v", limit, batchLen) 47 } 48 keys, items, err := batch.GetAll() 49 if err != nil { 50 t.Fatalf("unable to get the items from the batch; %v", err) 51 } 52 if len(items) != int(limit) { 53 t.Fatalf("Expected length of the batch items to be %v but got %v", limit, len(items)) 54 } 55 if len(keys) != int(limit) { 56 t.Fatalf("Expected length of the batch keys to be %v but got %v", limit, len(items)) 57 } 58 batchLen = batch.Len() 59 if batchLen != 0 { 60 t.Fatalf("expected batch to be empty but still left with %d items", batchLen) 61 } 62 // Add duplicate entries 63 for i := 0; i < 10; i++ { 64 if err := batch.Add(99, 99); err != nil { 65 t.Fatalf("failed to add duplicate item %v to batch after Get; %v", i, err) 66 } 67 } 68 if _, ok := batch.GetByKey(99); !ok { 69 t.Fatal("failed to get the duplicxate item by key '99' after adding") 70 } 71 keys, items, err = batch.GetAll() 72 if err != nil { 73 t.Fatalf("unable to get the items from the batch; %v", err) 74 } 75 if len(items) != 1 { 76 t.Fatalf("Expected length of the batch items to be 1 but got %v", len(items)) 77 } 78 if len(keys) != 1 { 79 t.Fatalf("Expected length of the batch keys to be 1 but got %v", len(items)) 80 } 81 // try adding again after Get. 82 for i := 0; i < int(limit); i++ { 83 if err := batch.Add(i, i); err != nil { 84 t.Fatalf("failed to add item %v to batch after Get; %v", i, err) 85 } 86 if _, ok := batch.GetByKey(i); !ok { 87 t.Fatalf("failed to get the item by key %v after adding", i) 88 } 89 } 90 } 91 92 func TestBatchWithConcurrency(t *testing.T) { 93 var limit uint32 = 100 94 batch := NewBatch[int, int](limit) 95 96 var wg sync.WaitGroup 97 for i := 0; i < int(limit); i++ { 98 wg.Add(1) 99 go func(item int) { 100 defer wg.Done() 101 if err := batch.Add(item, item); err != nil { 102 t.Errorf("failed to add item %v; %v", item, err) 103 return 104 } 105 if _, ok := batch.GetByKey(item); !ok { 106 t.Errorf("failed to get the item by key %v after adding", item) 107 } 108 }(i) 109 } 110 wg.Wait() 111 112 keys, items, err := batch.GetAll() 113 if err != nil { 114 t.Fatalf("unable to get the items from the batch; %v", err) 115 } 116 if len(items) != int(limit) { 117 t.Fatalf("expected batch length %v but got %v", limit, len(items)) 118 } 119 if len(keys) != int(limit) { 120 t.Fatalf("Expected length of the batch keys to be %v but got %v", limit, len(items)) 121 } 122 batchLen := batch.Len() 123 if batchLen != 0 { 124 t.Fatalf("expected batch to be empty but still left with %d items", batchLen) 125 } 126 }