@@ -2,8 +2,12 @@ package store
22
33import (
44 "context"
5+ "fmt"
56 "testing"
7+ "time"
68
9+ ds "github.com/ipfs/go-datastore"
10+ "github.com/rs/zerolog"
711 "github.com/stretchr/testify/assert"
812 "github.com/stretchr/testify/require"
913
@@ -270,3 +274,129 @@ func TestCachedStore_Close(t *testing.T) {
270274 err = cachedStore .Close ()
271275 require .NoError (t , err )
272276}
277+
278+ func TestCachedStore_AsyncSetMetadata (t * testing.T ) {
279+ t .Parallel ()
280+ ctx := context .Background ()
281+
282+ kv , err := NewTestInMemoryKVStore ()
283+ require .NoError (t , err )
284+
285+ base := New (kv )
286+ cs , err := NewCachedStore (base )
287+ require .NoError (t , err )
288+ t .Cleanup (func () { cs .Close () })
289+
290+ require .NoError (t , cs .SetMetadata (ctx , "key1" , []byte ("value1" )))
291+
292+ require .Eventually (t , func () bool {
293+ v , err := base .GetMetadata (ctx , "key1" )
294+ return err == nil && string (v ) == "value1"
295+ }, time .Second , 10 * time .Millisecond )
296+ }
297+
298+ func TestCachedStore_AsyncDeleteMetadata (t * testing.T ) {
299+ t .Parallel ()
300+ ctx := context .Background ()
301+
302+ kv , err := NewTestInMemoryKVStore ()
303+ require .NoError (t , err )
304+
305+ base := New (kv )
306+ require .NoError (t , base .SetMetadata (ctx , "key1" , []byte ("value1" )))
307+
308+ cs , err := NewCachedStore (base )
309+ require .NoError (t , err )
310+ t .Cleanup (func () { cs .Close () })
311+
312+ require .NoError (t , cs .DeleteMetadata (ctx , "key1" ))
313+
314+ require .Eventually (t , func () bool {
315+ _ , err := base .GetMetadata (ctx , "key1" )
316+ return err != nil
317+ }, time .Second , 10 * time .Millisecond )
318+ }
319+
320+ func TestCachedStore_Close_FlushesPendingWrites (t * testing.T ) {
321+ ctx := context .Background ()
322+
323+ dir := t .TempDir ()
324+ kv , err := NewDefaultKVStore (dir , "" , "test-db" )
325+ require .NoError (t , err )
326+
327+ base := New (kv )
328+ cs , err := NewCachedStore (base )
329+ require .NoError (t , err )
330+
331+ const n = 100
332+ for i := range n {
333+ k := fmt .Sprintf ("key-%d" , i )
334+ require .NoError (t , cs .SetMetadata (ctx , k , []byte (k )))
335+ }
336+
337+ require .NoError (t , cs .Close ())
338+
339+ kv2 , err := NewDefaultKVStore (dir , "" , "test-db" )
340+ require .NoError (t , err )
341+ t .Cleanup (func () { kv2 .Close () })
342+ reopened := New (kv2 )
343+
344+ for i := range n {
345+ k := fmt .Sprintf ("key-%d" , i )
346+ v , err := reopened .GetMetadata (ctx , k )
347+ require .NoError (t , err )
348+ require .Equal (t , []byte (k ), v )
349+ }
350+ }
351+
352+ func TestCachedStore_WriteAfterClose_FallsBack (t * testing.T ) {
353+ kv , err := NewTestInMemoryKVStore ()
354+ require .NoError (t , err )
355+
356+ base := New (kv )
357+ cs , err := NewCachedStore (base )
358+ require .NoError (t , err )
359+
360+ ctx := context .Background ()
361+ require .NoError (t , cs .SetMetadata (ctx , "before" , []byte ("ok" )))
362+
363+ require .NoError (t , cs .Close ())
364+
365+ err = cs .SetMetadata (ctx , "after" , []byte ("sync" ))
366+ require .Error (t , err )
367+ }
368+
369+ func TestCachedStore_CoalescesSameKeyOps (t * testing.T ) {
370+ ctx := context .Background ()
371+
372+ kv , err := NewTestInMemoryKVStore ()
373+ require .NoError (t , err )
374+
375+ require .NoError (t , kv .Put (ctx , ds .NewKey (GetMetaKey ("k" )), []byte ("original" )))
376+
377+ base := New (kv )
378+
379+ writeCh := make (chan asyncWriteOp , asyncWriteBufferSize )
380+ done := make (chan struct {})
381+ cs := & CachedStore {
382+ Store : base ,
383+ writeCh : writeCh ,
384+ done : done ,
385+ logger : zerolog .Nop (),
386+ }
387+ cs .startWriteLoop ()
388+
389+ require .NoError (t , cs .SetMetadata (ctx , "k" , []byte ("v1" )))
390+ require .NoError (t , cs .DeleteMetadata (ctx , "k" ))
391+ require .NoError (t , cs .SetMetadata (ctx , "k" , []byte ("v2" )))
392+
393+ cs .stopMu .Lock ()
394+ cs .stopped = true
395+ close (writeCh )
396+ cs .stopMu .Unlock ()
397+ <- done
398+
399+ v , err := base .GetMetadata (ctx , "k" )
400+ require .NoError (t , err )
401+ require .Equal (t , []byte ("v2" ), v , "last write (Set) should win over delete" )
402+ }
0 commit comments