Files
graphql-monitoring-proxy/cache/cache_test.go
T
lukaszraczylo d141fe3c04 Fix the introduced bug where RO endpoint could've been accidentally used. (#17)
* Fix the introduced bug where RO endpoint could've been accidentally used.
2024-06-28 21:48:39 +01:00

207 lines
4.6 KiB
Go

package libpack_cache
import (
"fmt"
"sync"
"time"
"github.com/alicebob/miniredis/v2"
libpack_cache_memory "github.com/lukaszraczylo/graphql-monitoring-proxy/cache/memory"
libpack_logger "github.com/lukaszraczylo/graphql-monitoring-proxy/logging"
)
func (suite *Tests) Test_cacheLookupInmemory() {
config = &CacheConfig{
Logger: libpack_logger.New(),
Client: libpack_cache_memory.New(5 * time.Minute),
TTL: 5,
}
type args struct {
hash string
}
tests := []struct {
name string
args args
want []byte
addCache struct {
data []byte
}
}{
{
name: "test_non_existent",
args: args{
hash: "00000000000000000000000000000000000000",
},
want: nil,
},
{
name: "test_existent",
args: args{
hash: "00000000000000000000000000000000001337",
},
want: []byte("it's fine."),
addCache: struct {
data []byte
}{
data: []byte("it's fine."),
},
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
if tt.addCache.data != nil {
CacheStore(tt.args.hash, tt.addCache.data)
}
got := CacheLookup(tt.args.hash)
assert.Equal(tt.want, got, "Unexpected cache lookup result")
})
}
}
func (suite *Tests) Test_cacheLookupRedis() {
config = &CacheConfig{
Logger: libpack_logger.New(),
TTL: 5,
}
config.Redis.DB = 0
config.Redis.URL = redisMockServer.Addr()
config.Redis.Enable = true
EnableCache(config)
type args struct {
hash string
}
tests := []struct {
name string
args args
want []byte
addCache struct {
data []byte
}
}{
{
name: "test_non_existent",
args: args{
hash: "00000000000000000000000000000000000000",
},
want: nil,
},
{
name: "test_existent",
args: args{
hash: "00000000000000000000000000000000001337",
},
want: []byte("it's fine."),
addCache: struct {
data []byte
}{
data: []byte("it's fine."),
},
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
if tt.addCache.data != nil {
CacheStore(tt.args.hash, tt.addCache.data)
}
got := CacheLookup(tt.args.hash)
assert.Equal(tt.want, got, "Unexpected cache lookup result")
})
}
}
func (suite *Tests) Test_cacheConcurrency() {
config = &CacheConfig{
Logger: libpack_logger.New(),
Client: libpack_cache_memory.New(5 * time.Second),
TTL: 5,
}
const numGoroutines = 10
const numOperations = 1000
var wg sync.WaitGroup
wg.Add(numGoroutines)
for i := 0; i < numGoroutines; i++ {
go func(id int) {
defer wg.Done()
for j := 0; j < numOperations; j++ {
key := fmt.Sprintf("key-%d-%d", id, j)
value := []byte(fmt.Sprintf("value-%d-%d", id, j))
CacheStore(key, value)
retrieved := CacheLookup(key)
assert.Equal(string(value), string(retrieved), "Concurrent cache operation failed")
}
}(i)
}
wg.Wait()
}
// func (suite *Tests) Test_cacheEviction() {
// config = &CacheConfig{
// Logger: libpack_logger.New(),
// Client: libpack_cache_memory.New(3 * time.Second), // 3 seconds TTL
// TTL: 3,
// }
// // Fill the cache
// for i := 0; i < 20; i++ {
// key := fmt.Sprintf("key-%d", i)
// value := []byte(fmt.Sprintf("value-%d", i))
// CacheStore(key, value)
// time.Sleep(100 * time.Millisecond) // Ensure different creation times
// }
// // Wait for the TTL to expire for the first half of the items
// time.Sleep(3100 * time.Millisecond)
// // Check that the oldest items have been evicted
// for i := 0; i < 10; i++ {
// key := fmt.Sprintf("key-%d", i)
// retrieved := CacheLookup(key)
// assert.Nil(retrieved, fmt.Sprintf("Old item %s should have been evicted", key))
// }
// // Check that the newer items are still in the cache
// for i := 10; i < 20; i++ {
// key := fmt.Sprintf("key-%d", i)
// expected := []byte(fmt.Sprintf("value-%d", i))
// retrieved := CacheLookup(key)
// assert.Equal(expected, retrieved, fmt.Sprintf("Recent item %s should be in cache", key))
// }
// }
func (suite *Tests) Test_cacheRedisFailure() {
mr, err := miniredis.Run()
if err != nil {
suite.T().Fatal(err)
}
defer mr.Close()
config = &CacheConfig{
Logger: libpack_logger.New(),
TTL: 5,
}
config.Redis.DB = 0
config.Redis.URL = mr.Addr()
config.Redis.Enable = true
EnableCache(config)
// Test normal operation
CacheStore("test-key", []byte("test-value"))
retrieved := CacheLookup("test-key")
assert.Equal([]byte("test-value"), retrieved)
// Simulate Redis failure
mr.Close()
// Operations should not panic, but should return errors or nil values
CacheStore("another-key", []byte("another-value"))
retrieved = CacheLookup("another-key")
assert.Nil(retrieved, "Lookup should return nil when Redis is down")
}