mirror of
https://github.com/status-im/proxy-common.git
synced 2026-08-30 12:01:06 +00:00
* l1 biggache, l2 keydb * extracted from status-im/eth-rpc-proxy to reuse in another projects fixes status-im/eth-rpc-proxy#106
230 lines
5.9 KiB
Go
230 lines
5.9 KiB
Go
package multi
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"go.uber.org/mock/gomock"
|
|
|
|
"github.com/status-im/proxy-common/cache"
|
|
"github.com/status-im/proxy-common/cache/mock"
|
|
"github.com/status-im/proxy-common/models"
|
|
)
|
|
|
|
func TestNewMultiCache(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
cache1 := mock.NewMockCache(ctrl)
|
|
cache2 := mock.NewMockCache(ctrl)
|
|
caches := []cache.Cache{cache1, cache2}
|
|
|
|
multiCache := NewMultiCache(caches, true)
|
|
|
|
assert.NotNil(t, multiCache)
|
|
mc := multiCache.(*MultiCache)
|
|
assert.Equal(t, 2, len(mc.caches))
|
|
assert.Equal(t, cache1, mc.caches[0])
|
|
assert.Equal(t, cache2, mc.caches[1])
|
|
}
|
|
|
|
func TestMultiCache_Get_FirstCacheHit(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
cache1 := mock.NewMockCache(ctrl)
|
|
cache2 := mock.NewMockCache(ctrl)
|
|
caches := []cache.Cache{cache1, cache2}
|
|
|
|
multiCache := NewMultiCache(caches, true)
|
|
|
|
expectedEntry := &models.CacheEntry{
|
|
Data: []byte("test-value"),
|
|
CreatedAt: time.Now().Unix(),
|
|
StaleAt: time.Now().Unix() + 60,
|
|
ExpiresAt: time.Now().Unix() + 120,
|
|
}
|
|
cache1.EXPECT().Get("test-key").Return(expectedEntry, true).Times(1)
|
|
// cache2.Get should not be called since cache1 has the value
|
|
|
|
entry, found := multiCache.Get("test-key")
|
|
|
|
assert.True(t, found)
|
|
assert.Equal(t, expectedEntry, entry)
|
|
}
|
|
|
|
func TestMultiCache_Get_SecondCacheHit(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
cache1 := mock.NewMockCache(ctrl)
|
|
cache2 := mock.NewMockCache(ctrl)
|
|
caches := []cache.Cache{cache1, cache2}
|
|
|
|
multiCache := NewMultiCache(caches, true)
|
|
|
|
expectedEntry := &models.CacheEntry{
|
|
Data: []byte("test-value"),
|
|
CreatedAt: time.Now().Unix(),
|
|
StaleAt: time.Now().Unix() + 60,
|
|
ExpiresAt: time.Now().Unix() + 120,
|
|
}
|
|
|
|
cache1.EXPECT().Get("test-key").Return(nil, false).Times(1)
|
|
cache2.EXPECT().Get("test-key").Return(expectedEntry, true).Times(1)
|
|
// Expect propagation to cache1
|
|
cache1.EXPECT().Set("test-key", expectedEntry.Data, gomock.Any()).Times(1)
|
|
|
|
entry, found := multiCache.Get("test-key")
|
|
|
|
assert.True(t, found)
|
|
assert.Equal(t, expectedEntry, entry)
|
|
}
|
|
|
|
func TestMultiCache_Get_AllCachesMiss(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
cache1 := mock.NewMockCache(ctrl)
|
|
cache2 := mock.NewMockCache(ctrl)
|
|
caches := []cache.Cache{cache1, cache2}
|
|
|
|
multiCache := NewMultiCache(caches, true)
|
|
|
|
cache1.EXPECT().Get("test-key").Return(nil, false).Times(1)
|
|
cache2.EXPECT().Get("test-key").Return(nil, false).Times(1)
|
|
|
|
entry, found := multiCache.Get("test-key")
|
|
|
|
assert.False(t, found)
|
|
assert.Nil(t, entry)
|
|
}
|
|
|
|
func TestMultiCache_Get_NoCaches(t *testing.T) {
|
|
multiCache := NewMultiCache([]cache.Cache{}, true)
|
|
|
|
entry, found := multiCache.Get("test-key")
|
|
|
|
assert.False(t, found)
|
|
assert.Nil(t, entry)
|
|
}
|
|
|
|
func TestMultiCache_GetStale_FirstCacheHit(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
cache1 := mock.NewMockCache(ctrl)
|
|
cache2 := mock.NewMockCache(ctrl)
|
|
caches := []cache.Cache{cache1, cache2}
|
|
|
|
multiCache := NewMultiCache(caches, true)
|
|
|
|
expectedEntry := &models.CacheEntry{
|
|
Data: []byte("test-value"),
|
|
CreatedAt: time.Now().Unix(),
|
|
StaleAt: time.Now().Unix() - 30, // stale but not expired
|
|
ExpiresAt: time.Now().Unix() + 60,
|
|
}
|
|
cache1.EXPECT().GetStale("test-key").Return(expectedEntry, true).Times(1)
|
|
|
|
entry, found := multiCache.GetStale("test-key")
|
|
|
|
assert.True(t, found)
|
|
assert.Equal(t, expectedEntry, entry)
|
|
}
|
|
|
|
func TestMultiCache_GetStale_SecondCacheHit(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
cache1 := mock.NewMockCache(ctrl)
|
|
cache2 := mock.NewMockCache(ctrl)
|
|
caches := []cache.Cache{cache1, cache2}
|
|
|
|
multiCache := NewMultiCache(caches, true)
|
|
|
|
expectedEntry := &models.CacheEntry{
|
|
Data: []byte("test-value"),
|
|
CreatedAt: time.Now().Unix(),
|
|
StaleAt: time.Now().Unix() - 30, // stale but not expired
|
|
ExpiresAt: time.Now().Unix() + 60,
|
|
}
|
|
|
|
cache1.EXPECT().GetStale("test-key").Return(nil, false).Times(1)
|
|
cache2.EXPECT().GetStale("test-key").Return(expectedEntry, true).Times(1)
|
|
// Expect propagation to cache1
|
|
cache1.EXPECT().Set("test-key", expectedEntry.Data, gomock.Any()).Times(1)
|
|
|
|
entry, found := multiCache.GetStale("test-key")
|
|
|
|
assert.True(t, found)
|
|
assert.Equal(t, expectedEntry, entry)
|
|
}
|
|
|
|
func TestMultiCache_Set_AllCaches(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
cache1 := mock.NewMockCache(ctrl)
|
|
cache2 := mock.NewMockCache(ctrl)
|
|
caches := []cache.Cache{cache1, cache2}
|
|
|
|
multiCache := NewMultiCache(caches, true)
|
|
|
|
testVal := []byte("test-value")
|
|
testTTL := models.TTL{Fresh: 60 * time.Second, Stale: 30 * time.Second}
|
|
|
|
cache1.EXPECT().Set("test-key", testVal, testTTL).Times(1)
|
|
cache2.EXPECT().Set("test-key", testVal, testTTL).Times(1)
|
|
|
|
multiCache.Set("test-key", testVal, testTTL)
|
|
}
|
|
|
|
func TestMultiCache_Set_NoCaches(t *testing.T) {
|
|
multiCache := NewMultiCache([]cache.Cache{}, true)
|
|
|
|
testVal := []byte("test-value")
|
|
testTTL := models.TTL{Fresh: 60 * time.Second, Stale: 30 * time.Second}
|
|
|
|
// Should not panic
|
|
multiCache.Set("test-key", testVal, testTTL)
|
|
}
|
|
|
|
func TestMultiCache_Delete_AllCaches(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
cache1 := mock.NewMockCache(ctrl)
|
|
cache2 := mock.NewMockCache(ctrl)
|
|
caches := []cache.Cache{cache1, cache2}
|
|
|
|
multiCache := NewMultiCache(caches, true)
|
|
|
|
cache1.EXPECT().Delete("test-key").Times(1)
|
|
cache2.EXPECT().Delete("test-key").Times(1)
|
|
|
|
multiCache.Delete("test-key")
|
|
}
|
|
|
|
func TestMultiCache_Delete_NoCaches(t *testing.T) {
|
|
multiCache := NewMultiCache([]cache.Cache{}, true)
|
|
|
|
// Should not panic
|
|
multiCache.Delete("test-key")
|
|
}
|
|
|
|
func TestMultiCache_GetCacheCount(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
cache1 := mock.NewMockCache(ctrl)
|
|
cache2 := mock.NewMockCache(ctrl)
|
|
caches := []cache.Cache{cache1, cache2}
|
|
|
|
multiCache := NewMultiCache(caches, true)
|
|
mc := multiCache.(*MultiCache)
|
|
|
|
assert.Equal(t, 2, mc.GetCacheCount())
|
|
}
|