mirror of
https://github.com/argoproj/argo-cd.git
synced 2026-02-20 01:28:45 +01:00
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>
172 lines
4.9 KiB
Go
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()))
|
|
}
|