github.com/ethersphere/bee/v2@v2.2.0/pkg/storer/mock/mockstorer_test.go (about) 1 // Copyright 2023 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 mockstorer_test 6 7 import ( 8 "context" 9 "errors" 10 "fmt" 11 "os" 12 "testing" 13 "time" 14 15 storage "github.com/ethersphere/bee/v2/pkg/storage" 16 chunktesting "github.com/ethersphere/bee/v2/pkg/storage/testing" 17 storer "github.com/ethersphere/bee/v2/pkg/storer" 18 mockstorer "github.com/ethersphere/bee/v2/pkg/storer/mock" 19 "github.com/ethersphere/bee/v2/pkg/swarm" 20 "github.com/google/go-cmp/cmp" 21 ) 22 23 var now = func() time.Time { return time.Unix(1234567890, 0) } 24 25 // TestMain exists to adjust the time.Now function to a fixed value. 26 func TestMain(m *testing.M) { 27 mockstorer.ReplaceTimeNow(now) 28 code := m.Run() 29 mockstorer.ReplaceTimeNow(time.Now) 30 os.Exit(code) 31 } 32 33 func TestMockStorer(t *testing.T) { 34 t.Parallel() 35 36 mockStorer := mockstorer.New() 37 38 t.Run("new session", func(t *testing.T) { 39 have, err := mockStorer.NewSession() 40 if err != nil { 41 t.Fatalf("NewSession(): unexpected error: %v", err) 42 } 43 44 want := storer.SessionInfo{TagID: 1, StartedAt: now().UnixNano()} 45 46 if diff := cmp.Diff(want, have); diff != "" { 47 t.Fatalf("unexpected session info: (-want +have):\n%s", diff) 48 } 49 }) 50 51 t.Run("get session", func(t *testing.T) { 52 have, err := mockStorer.Session(1) 53 if err != nil { 54 t.Fatalf("Session(): unexpected error: %v", err) 55 } 56 57 want := storer.SessionInfo{TagID: 1, StartedAt: now().UnixNano()} 58 59 if diff := cmp.Diff(want, have); diff != "" { 60 t.Fatalf("unexpected session info: (-want +have):\n%s", diff) 61 } 62 }) 63 64 t.Run("list sessions", func(t *testing.T) { 65 have, err := mockStorer.ListSessions(0, 1) 66 if err != nil { 67 t.Fatalf("ListSessions(): unexpected error: %v", err) 68 } 69 70 want := []storer.SessionInfo{ 71 {TagID: 1, StartedAt: now().UnixNano()}, 72 } 73 74 if diff := cmp.Diff(want, have); diff != "" { 75 t.Fatalf("unexpected session info: (-want +have):\n%s", diff) 76 } 77 }) 78 79 t.Run("delete session", func(t *testing.T) { 80 if err := mockStorer.DeleteSession(1); err != nil { 81 t.Fatalf("DeleteSession(): unexpected error: %v", err) 82 } 83 84 want := storage.ErrNotFound 85 _, have := mockStorer.Session(1) 86 if !errors.Is(want, have) { 87 t.Fatalf("Session(): unexpected error: want %v have %v", want, have) 88 } 89 }) 90 91 verifyChunksAndPin := func(t *testing.T, chunks []swarm.Chunk, root swarm.Address) { 92 t.Helper() 93 94 for _, ch := range chunks { 95 has, err := mockStorer.ChunkStore().Has(context.Background(), ch.Address()) 96 if err != nil { 97 t.Fatalf("Has(...): unexpected error: %v", err) 98 } 99 100 if !has { 101 t.Fatalf("expected chunk to be found %s", ch.Address()) 102 } 103 } 104 105 has, err := mockStorer.HasPin(root) 106 if err != nil { 107 t.Fatalf("HasPin(...): unexpected error: %v", err) 108 } 109 110 if !has { 111 t.Fatalf("expected to find root pin %s", root) 112 } 113 114 pins, err := mockStorer.Pins() 115 if err != nil { 116 t.Fatalf("Pins(): unexpected error: %v", err) 117 } 118 119 found := false 120 for _, p := range pins { 121 if p.Equal(root) { 122 found = true 123 break 124 } 125 } 126 127 if !found { 128 t.Fatalf("expected to find pin in list %s", root) 129 } 130 } 131 132 t.Run("upload", func(t *testing.T) { 133 session, err := mockStorer.NewSession() 134 if err != nil { 135 t.Fatalf("NewSession(): unexpected error: %v", err) 136 } 137 138 chunks := chunktesting.GenerateTestRandomChunks(5) 139 putter, err := mockStorer.Upload(context.Background(), true, session.TagID) 140 if err != nil { 141 t.Fatalf("Upload(...): unexpected error: %v", err) 142 } 143 144 for _, ch := range chunks { 145 err = putter.Put(context.Background(), ch) 146 if err != nil { 147 t.Fatalf("Put(...): unexpected error: %v", err) 148 } 149 } 150 151 err = putter.Done(chunks[0].Address()) 152 if err != nil { 153 t.Fatalf("Done(...): unexpected error: %v", err) 154 } 155 156 have, err := mockStorer.Session(session.TagID) 157 if err != nil { 158 t.Fatalf("Session(...): unexpected error: %v", err) 159 } 160 161 want := storer.SessionInfo{ 162 TagID: session.TagID, 163 StartedAt: session.StartedAt, 164 Address: chunks[0].Address(), 165 } 166 167 if diff := cmp.Diff(want, have); diff != "" { 168 t.Fatalf("unexpected session info: (-want +have):\n%s", diff) 169 } 170 171 verifyChunksAndPin(t, chunks, chunks[0].Address()) 172 }) 173 174 t.Run("pin", func(t *testing.T) { 175 putter, err := mockStorer.NewCollection(context.Background()) 176 if err != nil { 177 t.Fatalf("NewCollection(): unexpected error: %v", err) 178 } 179 180 chunks := chunktesting.GenerateTestRandomChunks(5) 181 for _, ch := range chunks { 182 err = putter.Put(context.Background(), ch) 183 if err != nil { 184 t.Fatalf("Put(...): unexpected error: %v", err) 185 } 186 } 187 188 err = putter.Done(chunks[0].Address()) 189 if err != nil { 190 t.Fatalf("Done(...): unexpected error: %v", err) 191 } 192 193 verifyChunksAndPin(t, chunks, chunks[0].Address()) 194 }) 195 196 t.Run("direct upload", func(t *testing.T) { 197 putter := mockStorer.DirectUpload() 198 199 chunks := chunktesting.GenerateTestRandomChunks(5) 200 done := make(chan struct{}) 201 go func() { 202 defer close(done) 203 204 i := 0 205 for op := range mockStorer.PusherFeed() { 206 if !op.Chunk.Equal(chunks[i]) { 207 op.Err <- fmt.Errorf("invalid chunk %s", op.Chunk.Address()) 208 break 209 } 210 op.Err <- nil 211 i++ 212 if i == len(chunks) { 213 break 214 } 215 } 216 }() 217 218 for _, ch := range chunks { 219 err := putter.Put(context.Background(), ch) 220 if err != nil { 221 t.Fatalf("Put(...): unexpected error: %v", err) 222 } 223 } 224 225 err := putter.Done(swarm.ZeroAddress) 226 if err != nil { 227 t.Fatalf("Done(...): unexpected error: %v", err) 228 } 229 230 select { 231 case <-done: 232 case <-time.After(3 * time.Second): 233 t.Fatalf("expected to be done by now") 234 } 235 }) 236 237 t.Run("delete pin", func(t *testing.T) { 238 pins, err := mockStorer.Pins() 239 if err != nil { 240 t.Fatalf("Pins(): unexpected error: %v", err) 241 } 242 243 for _, p := range pins { 244 err := mockStorer.DeletePin(context.Background(), p) 245 if err != nil { 246 t.Fatalf("DeletePin(...): unexpected error: %v", err) 247 } 248 } 249 250 for _, p := range pins { 251 has, err := mockStorer.HasPin(p) 252 if err != nil { 253 t.Fatalf("HasPin(...): unexpected error: %v", err) 254 } 255 256 if has { 257 t.Fatalf("expected pin to be deleted %s", p) 258 } 259 } 260 261 pins, err = mockStorer.Pins() 262 if err != nil { 263 t.Fatalf("Pins(): unexpected error: %v", err) 264 } 265 if len(pins) != 0 { 266 t.Fatalf("expected all pins to be deleted, found %d", len(pins)) 267 } 268 }) 269 }