1 package datastore
2
3 import (
4 "errors"
5 "sort"
6 "testing"
7 "time"
8
9 "github.com/launchdarkly/go-server-sdk/v6/internal/sharedtest/mocks"
10
11 "github.com/launchdarkly/go-server-sdk/v6/interfaces"
12 "github.com/launchdarkly/go-server-sdk/v6/internal"
13 s "github.com/launchdarkly/go-server-sdk/v6/internal/sharedtest"
14 "github.com/launchdarkly/go-server-sdk/v6/subsystems"
15 st "github.com/launchdarkly/go-server-sdk/v6/subsystems/ldstoretypes"
16
17 "github.com/stretchr/testify/assert"
18 "github.com/stretchr/testify/require"
19 )
20
21 type testCacheMode string
22
23 const (
24 testUncached testCacheMode = "uncached"
25 testCached testCacheMode = "cached"
26 testCachedIndefinitely testCacheMode = "cached indefinitely"
27 )
28
29 func (m testCacheMode) isCached() bool {
30 return m != testUncached
31 }
32
33 func (m testCacheMode) ttl() time.Duration {
34 switch m {
35 case testCached:
36 return 30 * time.Second
37 case testCachedIndefinitely:
38 return -1
39 default:
40 return 0
41 }
42 }
43
44 func (m testCacheMode) isInfiniteTTL() bool {
45 return m.ttl() < 0
46 }
47
48 func makePersistentDataStoreWrapper(
49 t *testing.T,
50 mode testCacheMode,
51 core *mocks.MockPersistentDataStore,
52 ) subsystems.DataStore {
53 broadcaster := internal.NewBroadcaster[interfaces.DataStoreStatus]()
54 dataStoreUpdates := NewDataStoreUpdateSinkImpl(broadcaster)
55 return NewPersistentDataStoreWrapper(core, dataStoreUpdates, mode.ttl(), s.NewTestLoggers())
56 }
57
58 func TestPersistentDataStoreWrapper(t *testing.T) {
59 allCacheModes := []testCacheMode{testUncached, testCached, testCachedIndefinitely}
60 cachedOnly := []testCacheMode{testCached, testCachedIndefinitely}
61
62 runTests := func(
63 name string,
64 test func(t *testing.T, mode testCacheMode),
65 forModes ...testCacheMode,
66 ) {
67 if len(forModes) == 0 {
68 require.Fail(t, "didn't specify any testCacheModes")
69 }
70 t.Run(name, func(t *testing.T) {
71 for _, mode := range forModes {
72 t.Run(string(mode), func(t *testing.T) {
73 test(t, mode)
74 })
75 }
76 })
77 }
78
79 runTests("Get", testPersistentDataStoreWrapperGet, allCacheModes...)
80 runTests("GetAll", testPersistentDataStoreWrapperGetAll, allCacheModes...)
81 runTests("Upsert", testPersistentDataStoreWrapperUpsert, allCacheModes...)
82 runTests("Delete", testPersistentDataStoreWrapperDelete, allCacheModes...)
83 runTests("IsInitialized", testPersistentDataStoreWrapperIsInitialized, allCacheModes...)
84 runTests("update failures with cache", testPersistentDataStoreWrapperUpdateFailuresWithCache, cachedOnly...)
85
86 runTests("IsStatusMonitoringEnabled", func(t *testing.T, mode testCacheMode) {
87 testWithMockPersistentDataStore(t, "is always true", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
88 assert.True(t, w.IsStatusMonitoringEnabled())
89 })
90 }, allCacheModes...)
91 }
92
93 func testWithMockPersistentDataStore(
94 t *testing.T,
95 name string,
96 mode testCacheMode,
97 action func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore),
98 ) {
99 t.Run(name, func(t *testing.T) {
100 core := mocks.NewMockPersistentDataStore()
101 w := makePersistentDataStoreWrapper(t, mode, core)
102 defer w.Close()
103 action(t, core, w)
104 })
105 }
106
107 func testPersistentDataStoreWrapperGet(t *testing.T, mode testCacheMode) {
108 testWithMockPersistentDataStore(t, "existing item", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
109 itemv1 := mocks.MockDataItem{Key: "item", Version: 1}
110 itemv2 := mocks.MockDataItem{Key: itemv1.Key, Version: 2}
111
112 core.ForceSet(mocks.MockData, itemv1.Key, itemv1.ToSerializedItemDescriptor())
113 item, err := w.Get(mocks.MockData, itemv1.Key)
114 require.NoError(t, err)
115 require.Equal(t, itemv1.ToItemDescriptor(), item)
116
117 core.ForceSet(mocks.MockData, itemv1.Key, itemv2.ToSerializedItemDescriptor())
118 item, err = w.Get(mocks.MockData, itemv1.Key)
119 require.NoError(t, err)
120 if mode.isCached() {
121 require.Equal(t, itemv1.ToItemDescriptor(), item)
122 } else {
123 require.Equal(t, itemv2.ToItemDescriptor(), item)
124 }
125 })
126
127 testWithMockPersistentDataStore(t, "unknown item", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
128 itemv1 := mocks.MockDataItem{Key: "key", Version: 1}
129
130 item, err := w.Get(mocks.MockData, itemv1.Key)
131 require.NoError(t, err)
132 require.Equal(t, st.ItemDescriptor{}.NotFound(), item)
133
134 core.ForceSet(mocks.MockData, itemv1.Key, itemv1.ToSerializedItemDescriptor())
135 item, err = w.Get(mocks.MockData, itemv1.Key)
136 require.NoError(t, err)
137 if mode.isCached() {
138 require.Equal(t, st.ItemDescriptor{}.NotFound(), item)
139 } else {
140 require.Equal(t, itemv1.ToItemDescriptor(), item)
141 }
142 })
143
144 testWithMockPersistentDataStore(t, "deleted item", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
145 key := "item"
146 deletedItemDesc := st.ItemDescriptor{Version: 1}
147 serializedDeletedItemDesc := st.SerializedItemDescriptor{Version: 1}
148 itemv2 := mocks.MockDataItem{Key: key, Version: 2}
149
150 core.ForceSet(mocks.MockData, key, serializedDeletedItemDesc)
151 item, err := w.Get(mocks.MockData, key)
152 require.NoError(t, err)
153 assert.Equal(t, deletedItemDesc, item)
154
155 core.ForceSet(mocks.MockData, key, itemv2.ToSerializedItemDescriptor())
156 item, err = w.Get(mocks.MockData, key)
157 require.NoError(t, err)
158 if mode.isCached() {
159 require.Equal(t, deletedItemDesc, item)
160 } else {
161 require.Equal(t, itemv2.ToItemDescriptor(), item)
162 }
163 })
164
165 testWithMockPersistentDataStore(t, "item that fails to deserialize", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
166 key := "item"
167 core.ForceSet(mocks.MockData, key, st.SerializedItemDescriptor{Version: 1, SerializedItem: []byte("BAD!")})
168
169 _, err := w.Get(mocks.MockData, key)
170 require.Error(t, err)
171 assert.Contains(t, err.Error(), "not a valid MockDataItem")
172 })
173
174 if mode.isCached() {
175 t.Run("cached", func(t *testing.T) {
176 testWithMockPersistentDataStore(t, "uses values from Init", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
177 itemv1 := mocks.MockDataItem{Key: "item", Version: 1}
178 itemv2 := mocks.MockDataItem{Key: itemv1.Key, Version: 2}
179
180 require.NoError(t, w.Init(mocks.MakeMockDataSet(itemv1)))
181
182 core.ForceSet(mocks.MockData, itemv1.Key, itemv2.ToSerializedItemDescriptor())
183 result, err := w.Get(mocks.MockData, itemv1.Key)
184 require.NoError(t, err)
185 require.Equal(t, itemv1.ToItemDescriptor(), result)
186 })
187
188 testWithMockPersistentDataStore(t, "coalesces requests for same key", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
189 queryStartedCh := core.EnableInstrumentedQueries(200 * time.Millisecond)
190
191 item := mocks.MockDataItem{Key: "key", Version: 9}
192 core.ForceSet(mocks.MockData, item.Key, item.ToSerializedItemDescriptor())
193
194 resultCh := make(chan int, 2)
195 go func() {
196 result, _ := w.Get(mocks.MockData, item.Key)
197 resultCh <- result.Version
198 }()
199
200
201
202 <-queryStartedCh
203 go func() {
204 result, _ := w.Get(mocks.MockData, item.Key)
205 resultCh <- result.Version
206 }()
207
208 result1 := <-resultCh
209 result2 := <-resultCh
210 assert.Equal(t, item.Version, result1)
211 assert.Equal(t, item.Version, result2)
212
213 assert.Len(t, queryStartedCh, 0)
214 })
215 })
216 }
217
218 testWithMockPersistentDataStore(t, "item whose version number doesn't come from the serialized data",
219 mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
220
221
222
223 item := mocks.MockDataItem{Key: "key", Version: 1}
224
225 sid := item.ToSerializedItemDescriptor()
226 sid.Version = 2
227
228 core.ForceSet(mocks.MockData, item.Key, sid)
229
230 id := item.ToItemDescriptor()
231 id.Version = 2
232
233 result, err := w.Get(mocks.MockData, item.Key)
234 assert.NoError(t, err)
235 assert.Equal(t, id, result)
236 })
237 }
238
239 func testPersistentDataStoreWrapperGetAll(t *testing.T, mode testCacheMode) {
240 testWithMockPersistentDataStore(t, "gets only items of one kind", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
241 item1 := mocks.MockDataItem{Key: "item1", Version: 1}
242 item2 := mocks.MockDataItem{Key: "item2", Version: 1}
243 otherItem1 := mocks.MockDataItem{Key: "item1", Version: 3, IsOtherKind: true}
244
245 core.ForceSet(mocks.MockData, item1.Key, item1.ToSerializedItemDescriptor())
246 core.ForceSet(mocks.MockData, item2.Key, item2.ToSerializedItemDescriptor())
247 core.ForceSet(mocks.MockOtherData, otherItem1.Key, otherItem1.ToSerializedItemDescriptor())
248
249 items, err := w.GetAll(mocks.MockData)
250 require.NoError(t, err)
251 require.Equal(t, 2, len(items))
252 sort.Slice(items, func(i, j int) bool { return items[i].Key < items[j].Key })
253 assert.Equal(t, []st.KeyedItemDescriptor{item1.ToKeyedItemDescriptor(), item2.ToKeyedItemDescriptor()}, items)
254
255 items, err = w.GetAll(mocks.MockOtherData)
256 require.NoError(t, err)
257 require.Equal(t, 1, len(items))
258 assert.Equal(t, []st.KeyedItemDescriptor{otherItem1.ToKeyedItemDescriptor()}, items)
259 })
260
261 testWithMockPersistentDataStore(t, "item that fails to deserialize", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
262 item1 := mocks.MockDataItem{Key: "item1", Version: 1}
263 core.ForceSet(mocks.MockData, item1.Key, item1.ToSerializedItemDescriptor())
264 core.ForceSet(mocks.MockData, "item2", st.SerializedItemDescriptor{Version: 1, SerializedItem: []byte("BAD!")})
265
266 _, err := w.GetAll(mocks.MockData)
267 require.Error(t, err)
268 assert.Contains(t, err.Error(), "not a valid MockDataItem")
269 })
270
271 if mode.isCached() {
272 t.Run("cached", func(t *testing.T) {
273 testWithMockPersistentDataStore(t, "uses values from Init", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
274 item1 := mocks.MockDataItem{Key: "item1", Version: 1}
275 item2 := mocks.MockDataItem{Key: "item2", Version: 1}
276
277 require.NoError(t, w.Init(mocks.MakeMockDataSet(item1, item2)))
278
279 core.ForceRemove(mocks.MockData, item2.Key)
280
281 items, err := w.GetAll(mocks.MockData)
282 require.NoError(t, err)
283 assert.Len(t, items, 2)
284 })
285
286 t.Run("uses fresh values if there has been an update", func(t *testing.T) {
287 core := mocks.NewMockPersistentDataStore()
288 w := makePersistentDataStoreWrapper(t, mode, core)
289 defer w.Close()
290
291 item1v1 := mocks.MockDataItem{Key: "item1", Version: 1}
292 item1v2 := mocks.MockDataItem{Key: "item1", Version: 2}
293 item2v1 := mocks.MockDataItem{Key: "item2", Version: 1}
294 item2v2 := mocks.MockDataItem{Key: "item2", Version: 2}
295
296 require.NoError(t, w.Init(mocks.MakeMockDataSet(item1v1, item2v2)))
297
298
299 _, err := w.Upsert(mocks.MockData, item1v1.Key, item1v2.ToItemDescriptor())
300 require.NoError(t, err)
301
302
303 core.ForceSet(mocks.MockData, item2v1.Key, item2v2.ToSerializedItemDescriptor())
304
305
306 items, err := w.GetAll(mocks.MockData)
307 require.NoError(t, err)
308 sort.Slice(items, func(i, j int) bool { return items[i].Key < items[j].Key })
309 require.Equal(t, 2, items[1].Item.Version)
310 })
311
312 testWithMockPersistentDataStore(t, "uses values from Init", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
313 queryStartedCh := core.EnableInstrumentedQueries(200 * time.Millisecond)
314
315 item := mocks.MockDataItem{Key: "key", Version: 9}
316 core.ForceSet(mocks.MockData, item.Key, item.ToSerializedItemDescriptor())
317
318 resultCh := make(chan int, 2)
319 go func() {
320 result, _ := w.GetAll(mocks.MockData)
321 resultCh <- len(result)
322 }()
323
324
325
326 <-queryStartedCh
327 go func() {
328 result, _ := w.GetAll(mocks.MockData)
329 resultCh <- len(result)
330 }()
331
332 result1 := <-resultCh
333 result2 := <-resultCh
334 assert.Equal(t, 1, result1)
335 assert.Equal(t, 1, result2)
336
337 assert.Len(t, queryStartedCh, 0)
338 })
339 })
340 }
341 }
342
343 func testPersistentDataStoreWrapperUpsert(t *testing.T, mode testCacheMode) {
344 testWithMockPersistentDataStore(t, "successful", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
345 key := "item"
346 itemv1 := mocks.MockDataItem{Key: key, Version: 1}
347 itemv2 := mocks.MockDataItem{Key: key, Version: 2}
348
349 updated, err := w.Upsert(mocks.MockData, key, itemv1.ToItemDescriptor())
350 require.NoError(t, err)
351 assert.True(t, updated)
352 require.Equal(t, itemv1.ToSerializedItemDescriptor(), core.ForceGet(mocks.MockData, key))
353
354 updated, err = w.Upsert(mocks.MockData, key, itemv2.ToItemDescriptor())
355 require.NoError(t, err)
356 assert.True(t, updated)
357 require.Equal(t, itemv2.ToSerializedItemDescriptor(), core.ForceGet(mocks.MockData, key))
358
359
360
361 if mode.isCached() {
362 itemv3 := mocks.MockDataItem{Key: key, Version: 3}
363 core.ForceSet(mocks.MockData, key, itemv3.ToSerializedItemDescriptor())
364 }
365
366 result, err := w.Get(mocks.MockData, key)
367 require.NoError(t, err)
368 assert.Equal(t, itemv2.ToItemDescriptor(), result)
369 })
370
371 testWithMockPersistentDataStore(t, "unsuccessful - lower version", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
372 key := "item"
373 itemv1 := mocks.MockDataItem{Key: key, Version: 1}
374 itemv2 := mocks.MockDataItem{Key: key, Version: 2}
375
376 updated, err := w.Upsert(mocks.MockData, key, itemv2.ToItemDescriptor())
377 require.NoError(t, err)
378 assert.True(t, updated)
379 require.Equal(t, itemv2.ToSerializedItemDescriptor(), core.ForceGet(mocks.MockData, key))
380
381
382
383
384 itemv3 := mocks.MockDataItem{Key: key, Version: 3}
385 core.ForceSet(mocks.MockData, key, itemv3.ToSerializedItemDescriptor())
386
387 updated, err = w.Upsert(mocks.MockData, key, itemv1.ToItemDescriptor())
388 require.NoError(t, err)
389 assert.False(t, updated)
390
391 result, err := w.Get(mocks.MockData, key)
392 require.NoError(t, err)
393 assert.Equal(t, itemv3.ToItemDescriptor(), result)
394 })
395 }
396
397 func testPersistentDataStoreWrapperDelete(t *testing.T, mode testCacheMode) {
398 testWithMockPersistentDataStore(t, "successful", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
399 key := "item"
400 itemv1 := mocks.MockDataItem{Key: key, Version: 1}
401 deletedv2 := st.ItemDescriptor{Version: 2}
402
403 updated, err := w.Upsert(mocks.MockData, key, itemv1.ToItemDescriptor())
404 require.NoError(t, err)
405 assert.True(t, updated)
406 require.Equal(t, itemv1.ToSerializedItemDescriptor(), core.ForceGet(mocks.MockData, key))
407
408 updated, err = w.Upsert(mocks.MockData, key, deletedv2)
409 require.NoError(t, err)
410 assert.True(t, updated)
411
412
413
414 if mode.isCached() {
415 itemv3 := mocks.MockDataItem{Key: key, Version: 3}
416 core.ForceSet(mocks.MockData, key, itemv3.ToSerializedItemDescriptor())
417 }
418
419 result, err := w.Get(mocks.MockData, itemv1.Key)
420 require.NoError(t, err)
421 assert.Equal(t, deletedv2, result)
422 })
423
424 testWithMockPersistentDataStore(t, "unsuccessful - lower version", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
425 key := "item"
426 itemv2 := mocks.MockDataItem{Key: key, Version: 2}
427 deletedv1 := st.ItemDescriptor{Version: 1}
428
429 updated, err := w.Upsert(mocks.MockData, key, itemv2.ToItemDescriptor())
430 require.NoError(t, err)
431 assert.True(t, updated)
432 require.Equal(t, itemv2.ToSerializedItemDescriptor(), core.ForceGet(mocks.MockData, key))
433
434 updated, err = w.Upsert(mocks.MockData, key, deletedv1)
435 require.NoError(t, err)
436 assert.False(t, updated)
437
438 result, err := w.Get(mocks.MockData, itemv2.Key)
439 require.NoError(t, err)
440 assert.Equal(t, itemv2.ToItemDescriptor(), result)
441 })
442 }
443
444 func testPersistentDataStoreWrapperIsInitialized(t *testing.T, mode testCacheMode) {
445 testWithMockPersistentDataStore(t, "won't call underlying IsInitialized if Init has been called", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
446 assert.False(t, w.IsInitialized())
447 assert.Equal(t, 1, core.InitQueriedCount)
448
449 require.NoError(t, w.Init(mocks.MakeMockDataSet()))
450
451 assert.True(t, w.IsInitialized())
452 assert.Equal(t, 1, core.InitQueriedCount)
453 })
454
455 if mode.isCached() {
456 testWithMockPersistentDataStore(t, "can cache true result", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
457 assert.Equal(t, 0, core.InitQueriedCount)
458
459 core.ForceSetInited(true)
460
461 assert.True(t, w.IsInitialized())
462 assert.Equal(t, 1, core.InitQueriedCount)
463
464 core.ForceSetInited(false)
465
466 assert.True(t, w.IsInitialized())
467 assert.Equal(t, 1, core.InitQueriedCount)
468 })
469
470 testWithMockPersistentDataStore(t, "can cache false result", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
471 assert.False(t, w.IsInitialized())
472 assert.Equal(t, 1, core.InitQueriedCount)
473
474 core.ForceSetInited(true)
475
476 assert.False(t, w.IsInitialized())
477 assert.Equal(t, 1, core.InitQueriedCount)
478 })
479 }
480 }
481
482 func testPersistentDataStoreWrapperUpdateFailuresWithCache(t *testing.T, mode testCacheMode) {
483 if mode.isInfiniteTTL() {
484 t.Run("infinite TTL", func(t *testing.T) {
485 testWithMockPersistentDataStore(t, "will update cache even if core Upsert fails", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
486 key := "key"
487 itemv1 := mocks.MockDataItem{Key: key, Version: 1}
488 itemv2 := mocks.MockDataItem{Key: key, Version: 2}
489
490 require.NoError(t, w.Init(mocks.MakeMockDataSet(itemv1)))
491 assert.Equal(t, itemv1.ToSerializedItemDescriptor(), core.ForceGet(mocks.MockData, key))
492
493 myError := errors.New("sorry")
494 core.SetFakeError(myError)
495 _, err := w.Upsert(mocks.MockData, key, itemv2.ToItemDescriptor())
496 assert.Equal(t, myError, err)
497 assert.Equal(t, itemv1.ToSerializedItemDescriptor(), core.ForceGet(mocks.MockData, key))
498
499 core.SetFakeError(nil)
500 item, err := w.Get(mocks.MockData, key)
501 require.NoError(t, err)
502 require.Equal(t, itemv2.ToItemDescriptor(), item)
503 })
504
505 testWithMockPersistentDataStore(t, "will update cache even if core Init fails", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
506 key := "key"
507 itemv1 := mocks.MockDataItem{Key: key, Version: 1}
508
509 myError := errors.New("sorry")
510 core.SetFakeError(myError)
511 err := w.Init(mocks.MakeMockDataSet(itemv1))
512 assert.Equal(t, myError, err)
513 assert.Equal(t, st.SerializedItemDescriptor{}.NotFound(), core.ForceGet(mocks.MockData, key))
514
515 core.SetFakeError(nil)
516 result, err := w.GetAll(mocks.MockData)
517 require.NoError(t, err)
518 require.Len(t, result, 1)
519 })
520 })
521 } else {
522 t.Run("finite TTL", func(t *testing.T) {
523 testWithMockPersistentDataStore(t, "won't update cache if core Upsert fails", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
524 key := "key"
525 itemv1 := mocks.MockDataItem{Key: key, Version: 1}
526 itemv2 := mocks.MockDataItem{Key: key, Version: 2}
527
528 require.NoError(t, w.Init(mocks.MakeMockDataSet(itemv1)))
529 assert.Equal(t, itemv1.ToSerializedItemDescriptor(), core.ForceGet(mocks.MockData, key))
530
531 myError := errors.New("sorry")
532 core.SetFakeError(myError)
533 _, err := w.Upsert(mocks.MockData, key, itemv2.ToItemDescriptor())
534 assert.Equal(t, myError, err)
535 assert.Equal(t, itemv1.ToSerializedItemDescriptor(), core.ForceGet(mocks.MockData, key))
536
537 core.SetFakeError(nil)
538 item, err := w.Get(mocks.MockData, key)
539 require.NoError(t, err)
540 require.Equal(t, itemv1.ToItemDescriptor(), item)
541 })
542
543 testWithMockPersistentDataStore(t, "won't update cache if core Init fails", mode, func(t *testing.T, core *mocks.MockPersistentDataStore, w subsystems.DataStore) {
544 key := "key"
545 itemv1 := mocks.MockDataItem{Key: key, Version: 1}
546
547 myError := errors.New("sorry")
548 core.SetFakeError(myError)
549 err := w.Init(mocks.MakeMockDataSet(itemv1))
550 assert.Equal(t, myError, err)
551 assert.Equal(t, st.SerializedItemDescriptor{}.NotFound(), core.ForceGet(mocks.MockData, key))
552
553 core.SetFakeError(nil)
554 result, err := w.GetAll(mocks.MockData)
555 require.NoError(t, err)
556 require.Len(t, result, 0)
557 })
558 })
559 }
560 }
561
View as plain text