175
store/cache/cache_test.go
vendored
175
store/cache/cache_test.go
vendored
@@ -1,99 +1,102 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/micro/go-micro/v2/store"
|
||||
"github.com/micro/go-micro/v2/store/memory"
|
||||
"github.com/micro/go-micro/v2/store/file"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCache(t *testing.T) {
|
||||
l0, l1, l2 := memory.NewStore(store.Database("l0")), memory.NewStore(store.Table("l1")), memory.NewStore()
|
||||
_, _, _ = l0.Init(), l1.Init(), l2.Init()
|
||||
func cleanup(db string, s store.Store) {
|
||||
s.Close()
|
||||
dir := filepath.Join(file.DefaultDir, db+"/")
|
||||
os.RemoveAll(dir)
|
||||
}
|
||||
|
||||
assert := assert.New(t)
|
||||
func TestRead(t *testing.T) {
|
||||
cf := NewStore(file.NewStore())
|
||||
cf.Init()
|
||||
cfInt := cf.(*cache)
|
||||
defer cleanup(file.DefaultDatabase, cf)
|
||||
|
||||
nonCache := NewCache(nil)
|
||||
assert.Equal(len(nonCache.(*cache).stores), 1, "Expected a cache initialised with just 1 store to fail")
|
||||
|
||||
// Basic functionality
|
||||
cachedStore := NewCache(l0, l1, l2)
|
||||
assert.Equal(cachedStore.Options(), l0.Options(), "Options on store/cache are nonsensical")
|
||||
expectedString := "cache [memory memory memory]"
|
||||
assert.Equal(cachedStore.String(), expectedString, "Cache couldn't describe itself as expected")
|
||||
|
||||
// Read/Write tests
|
||||
_, err := cachedStore.Read("test")
|
||||
assert.Equal(store.ErrNotFound, err, "Read non existant key")
|
||||
r1 := &store.Record{
|
||||
Key: "aaa",
|
||||
Value: []byte("bbb"),
|
||||
Metadata: map[string]interface{}{},
|
||||
}
|
||||
r2 := &store.Record{
|
||||
Key: "aaaa",
|
||||
Value: []byte("bbbb"),
|
||||
Metadata: map[string]interface{}{},
|
||||
}
|
||||
r3 := &store.Record{
|
||||
Key: "aaaaa",
|
||||
Value: []byte("bbbbb"),
|
||||
Metadata: map[string]interface{}{},
|
||||
}
|
||||
// Write 3 records directly to l2
|
||||
l2.Write(r1)
|
||||
l2.Write(r2)
|
||||
l2.Write(r3)
|
||||
// Ensure it's not in l0
|
||||
assert.Equal(store.ErrNotFound, func() error { _, err := l0.Read(r1.Key); return err }())
|
||||
// Read from cache, ensure it's in all 3 stores
|
||||
results, err := cachedStore.Read(r1.Key)
|
||||
assert.Nil(err, "cachedStore.Read() returned error")
|
||||
assert.Len(results, 1, "cachedStore.Read() should only return 1 result")
|
||||
assert.Equal(r1, results[0], "Cached read didn't return the record that was put in")
|
||||
results, err = l0.Read(r1.Key)
|
||||
assert.Nil(err)
|
||||
assert.Equal(r1, results[0], "l0 not coherent")
|
||||
results, err = l1.Read(r1.Key)
|
||||
assert.Nil(err)
|
||||
assert.Equal(r1, results[0], "l1 not coherent")
|
||||
results, err = l2.Read(r1.Key)
|
||||
assert.Nil(err)
|
||||
assert.Equal(r1, results[0], "l2 not coherent")
|
||||
// Multiple read
|
||||
results, err = cachedStore.Read("aa", store.ReadPrefix())
|
||||
assert.Nil(err, "Cachedstore multiple read errored")
|
||||
assert.Len(results, 3, "ReadPrefix should have read all records")
|
||||
// l1 should now have all 3 records
|
||||
l1results, err := l1.Read("aa", store.ReadPrefix())
|
||||
assert.Nil(err, "l1.Read failed")
|
||||
assert.Len(l1results, 3, "l1 didn't contain a full cache")
|
||||
sort.Slice(results, func(i, j int) bool { return results[i].Key < results[j].Key })
|
||||
sort.Slice(l1results, func(i, j int) bool { return l1results[i].Key < l1results[j].Key })
|
||||
assert.Equal(results[0], l1results[0], "l1 cache not coherent")
|
||||
assert.Equal(results[1], l1results[1], "l1 cache not coherent")
|
||||
assert.Equal(results[2], l1results[2], "l1 cache not coherent")
|
||||
|
||||
// Test List and Delete
|
||||
keys, err := cachedStore.List(store.ListPrefix("a"))
|
||||
assert.Nil(err, "List should not error")
|
||||
assert.Len(keys, 3, "List should return 3 keys")
|
||||
for _, k := range keys {
|
||||
err := cachedStore.Delete(k)
|
||||
assert.Nil(err, "Delete should not error")
|
||||
_, err = cachedStore.Read(k)
|
||||
// N.B. - this may not pass on stores that are eventually consistent
|
||||
assert.Equal(store.ErrNotFound, err, "record should be gone")
|
||||
}
|
||||
|
||||
// Test Write
|
||||
err = cachedStore.Write(r1)
|
||||
assert.Nil(err, "Write shouldn't fail")
|
||||
l2result, err := l2.Read(r1.Key)
|
||||
assert.Nil(err)
|
||||
assert.Len(l2result, 1)
|
||||
assert.Equal(r1, l2result[0], "Write didn't make it all the way through to l2")
|
||||
_, err := cf.Read("key1")
|
||||
assert.Error(t, err, "Unexpected record")
|
||||
cfInt.b.Write(&store.Record{
|
||||
Key: "key1",
|
||||
Value: []byte("foo"),
|
||||
})
|
||||
recs, err := cf.Read("key1")
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, recs, 1, "Expected a record to be pulled from file store")
|
||||
recs, err = cfInt.m.Read("key1")
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, recs, 1, "Expected a memory store to be populatedfrom file store")
|
||||
|
||||
}
|
||||
|
||||
func TestWrite(t *testing.T) {
|
||||
cf := NewStore(file.NewStore())
|
||||
cf.Init()
|
||||
cfInt := cf.(*cache)
|
||||
defer cleanup(file.DefaultDatabase, cf)
|
||||
|
||||
cf.Write(&store.Record{
|
||||
Key: "key1",
|
||||
Value: []byte("foo"),
|
||||
})
|
||||
recs, _ := cfInt.m.Read("key1")
|
||||
assert.Len(t, recs, 1, "Expected a record in the memory store")
|
||||
recs, _ = cfInt.b.Read("key1")
|
||||
assert.Len(t, recs, 1, "Expected a record in the file store")
|
||||
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
cf := NewStore(file.NewStore())
|
||||
cf.Init()
|
||||
cfInt := cf.(*cache)
|
||||
defer cleanup(file.DefaultDatabase, cf)
|
||||
|
||||
cf.Write(&store.Record{
|
||||
Key: "key1",
|
||||
Value: []byte("foo"),
|
||||
})
|
||||
recs, _ := cfInt.m.Read("key1")
|
||||
assert.Len(t, recs, 1, "Expected a record in the memory store")
|
||||
recs, _ = cfInt.b.Read("key1")
|
||||
assert.Len(t, recs, 1, "Expected a record in the file store")
|
||||
cf.Delete("key1")
|
||||
|
||||
_, err := cfInt.m.Read("key1")
|
||||
assert.Error(t, err, "Expected no records in memory store")
|
||||
_, err = cfInt.b.Read("key1")
|
||||
assert.Error(t, err, "Expected no records in file store")
|
||||
|
||||
}
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
cf := NewStore(file.NewStore())
|
||||
cf.Init()
|
||||
cfInt := cf.(*cache)
|
||||
defer cleanup(file.DefaultDatabase, cf)
|
||||
|
||||
keys, err := cf.List()
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, keys, 0)
|
||||
cfInt.b.Write(&store.Record{
|
||||
Key: "key1",
|
||||
Value: []byte("foo"),
|
||||
})
|
||||
|
||||
cfInt.b.Write(&store.Record{
|
||||
Key: "key2",
|
||||
Value: []byte("foo"),
|
||||
})
|
||||
keys, err = cf.List()
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, keys, 2)
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user