Files
argo-cd/util/cache/redis_test.go
Papapetrou Patroklos b2df60414c chore: bumps go redis client 9.17.2 (#25643)
Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Patroklos Papapetrou <ppapapetrou76@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-17 09:25:04 +02:00

172 lines
4.9 KiB
Go

package cache
import (
"bytes"
"compress/gzip"
"io"
"strconv"
"testing"
"time"
"github.com/alicebob/miniredis/v2"
"github.com/prometheus/client_golang/prometheus"
promcm "github.com/prometheus/client_model/go"
"github.com/redis/go-redis/v9"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
var (
redisRequestCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "argocd_redis_request_total",
},
[]string{"initiator", "failed"},
)
redisRequestHistogram = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "argocd_redis_request_duration",
Buckets: []float64{0.1, 0.25, .5, 1, 2},
},
[]string{"initiator"},
)
)
type MockMetricsServer struct {
redisRequestCounter *prometheus.CounterVec
redisRequestHistogram *prometheus.HistogramVec
}
func NewMockMetricsServer() *MockMetricsServer {
registry := prometheus.NewRegistry()
registry.MustRegister(redisRequestCounter)
registry.MustRegister(redisRequestHistogram)
return &MockMetricsServer{
redisRequestCounter: redisRequestCounter,
redisRequestHistogram: redisRequestHistogram,
}
}
func (m *MockMetricsServer) IncRedisRequest(failed bool) {
m.redisRequestCounter.WithLabelValues("mock", strconv.FormatBool(failed)).Inc()
}
func (m *MockMetricsServer) ObserveRedisRequestDuration(duration time.Duration) {
m.redisRequestHistogram.WithLabelValues("mock").Observe(duration.Seconds())
}
func TestRedisSetCache(t *testing.T) {
mr, err := miniredis.Run()
if err != nil {
panic(err)
}
defer mr.Close()
assert.NotNil(t, mr)
t.Run("Successful set", func(t *testing.T) {
client := NewRedisCache(redis.NewClient(&redis.Options{Addr: mr.Addr()}), 60*time.Second, RedisCompressionNone)
err = client.Set(&Item{Key: "foo", Object: "bar"})
require.NoError(t, err)
})
t.Run("Successful get", func(t *testing.T) {
var res string
client := NewRedisCache(redis.NewClient(&redis.Options{Addr: mr.Addr()}), 10*time.Second, RedisCompressionNone)
err = client.Get("foo", &res)
require.NoError(t, err)
assert.Equal(t, "bar", res)
})
t.Run("Successful delete", func(t *testing.T) {
client := NewRedisCache(redis.NewClient(&redis.Options{Addr: mr.Addr()}), 10*time.Second, RedisCompressionNone)
err = client.Delete("foo")
require.NoError(t, err)
})
t.Run("Cache miss", func(t *testing.T) {
var res string
client := NewRedisCache(redis.NewClient(&redis.Options{Addr: mr.Addr()}), 10*time.Second, RedisCompressionNone)
err = client.Get("foo", &res)
assert.ErrorContains(t, err, "cache: key is missing")
})
}
func TestRedisSetCacheCompressed(t *testing.T) {
mr, err := miniredis.Run()
if err != nil {
panic(err)
}
defer mr.Close()
assert.NotNil(t, mr)
redisClient := redis.NewClient(&redis.Options{Addr: mr.Addr()})
client := NewRedisCache(redisClient, 10*time.Second, RedisCompressionGZip)
testValue := "my-value"
require.NoError(t, client.Set(&Item{Key: "my-key", Object: testValue}))
compressedData, err := redisClient.Get(t.Context(), "my-key.gz").Bytes()
require.NoError(t, err)
assert.Greater(t, len(compressedData), len([]byte(testValue)), "compressed data is bigger than uncompressed")
// trying to unzip compressed data
gzipReader, err := gzip.NewReader(bytes.NewBuffer(compressedData))
require.NoError(t, err)
_, err = io.ReadAll(gzipReader)
require.NoError(t, err)
var result string
require.NoError(t, client.Get("my-key", &result))
assert.Equal(t, testValue, result)
}
func TestRedisMetrics(t *testing.T) {
mr, err := miniredis.Run()
if err != nil {
panic(err)
}
defer mr.Close()
metric := &promcm.Metric{}
ms := NewMockMetricsServer()
redisClient := redis.NewClient(&redis.Options{Addr: mr.Addr()})
faultyRedisClient := redis.NewClient(&redis.Options{Addr: "invalidredishost.invalid:12345"})
CollectMetrics(redisClient, ms, nil)
CollectMetrics(faultyRedisClient, ms, nil)
client := NewRedisCache(redisClient, 60*time.Second, RedisCompressionNone)
faultyClient := NewRedisCache(faultyRedisClient, 60*time.Second, RedisCompressionNone)
var res string
// client successful request
err = client.Set(&Item{Key: "foo", Object: "bar"})
require.NoError(t, err)
err = client.Get("foo", &res)
require.NoError(t, err)
c, err := ms.redisRequestCounter.GetMetricWithLabelValues("mock", "false")
require.NoError(t, err)
err = c.Write(metric)
require.NoError(t, err)
assert.InEpsilon(t, float64(2), metric.Counter.GetValue(), 0.0001)
// faulty client failed request
err = faultyClient.Get("foo", &res)
require.Error(t, err)
c, err = ms.redisRequestCounter.GetMetricWithLabelValues("mock", "true")
require.NoError(t, err)
err = c.Write(metric)
require.NoError(t, err)
assert.InEpsilon(t, float64(1), metric.Counter.GetValue(), 0.0001)
// both clients histogram count
o, err := ms.redisRequestHistogram.GetMetricWithLabelValues("mock")
require.NoError(t, err)
err = o.(prometheus.Metric).Write(metric)
require.NoError(t, err)
assert.Equal(t, 3, int(metric.Histogram.GetSampleCount()))
}