github.com/grafana/synthetic-monitoring-agent@v0.64.2/internal/cache/noop_test.go (about) 1 package cache 2 3 import ( 4 "context" 5 "io" 6 "testing" 7 "time" 8 9 "github.com/rs/zerolog" 10 "github.com/stretchr/testify/require" 11 ) 12 13 func TestNoopCache(t *testing.T) { 14 logger := zerolog.New(io.Discard) 15 cache := NewNoop(logger) 16 17 ctx := t.Context() 18 19 t.Run("implements Cache interface", func(t *testing.T) { 20 require.NotNil(t, cache) 21 require.Implements(t, (*Cache)(nil), cache) 22 }) 23 24 t.Run("get always returns ErrCacheMiss", func(t *testing.T) { 25 var result string 26 27 err := cache.Get(ctx, "any-key", &result) 28 require.ErrorIs(t, err, ErrCacheMiss) 29 require.Empty(t, result) 30 }) 31 32 t.Run("set succeeds but discards value", func(t *testing.T) { 33 err := cache.Set(ctx, "test-key", "test-value", 1*time.Minute) 34 require.NoError(t, err) 35 36 // Verify it wasn't actually cached 37 var result string 38 39 err = cache.Get(ctx, "test-key", &result) 40 require.ErrorIs(t, err, ErrCacheMiss) 41 require.Empty(t, result) 42 }) 43 44 t.Run("delete succeeds", func(t *testing.T) { 45 err := cache.Delete(ctx, "any-key") 46 require.NoError(t, err) 47 }) 48 49 t.Run("flush succeeds", func(t *testing.T) { 50 err := cache.Flush(ctx) 51 require.NoError(t, err) 52 }) 53 } 54 55 func TestNoopCacheSetGetDelete(t *testing.T) { 56 logger := zerolog.New(io.Discard) 57 cache := NewNoop(logger) 58 ctx := context.Background() 59 60 // Set multiple values 61 require.NoError(t, cache.Set(ctx, "key1", "value1", 1*time.Minute)) 62 require.NoError(t, cache.Set(ctx, "key2", 123, 1*time.Minute)) 63 require.NoError(t, cache.Set(ctx, "key3", TestStruct{ID: 1, Name: "test"}, 1*time.Minute)) 64 65 // All gets should return ErrCacheMiss 66 var s string 67 require.ErrorIs(t, cache.Get(ctx, "key1", &s), ErrCacheMiss) 68 require.Empty(t, s) 69 70 var i int 71 require.ErrorIs(t, cache.Get(ctx, "key2", &i), ErrCacheMiss) 72 require.Zero(t, i) 73 74 var ts TestStruct 75 require.ErrorIs(t, cache.Get(ctx, "key3", &ts), ErrCacheMiss) 76 require.Zero(t, ts) 77 78 // Delete should succeed 79 require.NoError(t, cache.Delete(ctx, "key1")) 80 81 // Flush should succeed 82 require.NoError(t, cache.Flush(ctx)) 83 } 84 85 func TestNoopCacheWithVariousTypes(t *testing.T) { 86 logger := zerolog.New(io.Discard) 87 cache := NewNoop(logger) 88 ctx := context.Background() 89 90 testCases := map[string]struct { 91 key string 92 value any 93 }{ 94 "string": { 95 key: "test:string", 96 value: "hello", 97 }, 98 "int": { 99 key: "test:int", 100 value: 42, 101 }, 102 "struct": { 103 key: "test:struct", 104 value: TestStruct{ 105 ID: 100, 106 Name: "noop test", 107 Tags: []string{"a", "b"}, 108 }, 109 }, 110 "slice": { 111 key: "test:slice", 112 value: []string{"x", "y", "z"}, 113 }, 114 "map": { 115 key: "test:map", 116 value: map[string]int{"a": 1, "b": 2}, 117 }, 118 } 119 120 for name, tc := range testCases { 121 t.Run(name, func(t *testing.T) { 122 // Set should succeed 123 err := cache.Set(ctx, tc.key, tc.value, 5*time.Minute) 124 require.NoError(t, err) 125 126 // Get should always return ErrCacheMiss 127 var result any 128 129 err = cache.Get(ctx, tc.key, &result) 130 require.ErrorIs(t, err, ErrCacheMiss) 131 }) 132 } 133 } 134 135 func TestNoopCacheZeroExpiration(t *testing.T) { 136 logger := zerolog.New(io.Discard) 137 cache := NewNoop(logger) 138 ctx := context.Background() 139 140 // Set with zero expiration should succeed 141 err := cache.Set(ctx, "key", "value", 0) 142 require.NoError(t, err) 143 144 // But Get should still return ErrCacheMiss 145 var result string 146 147 err = cache.Get(ctx, "key", &result) 148 require.ErrorIs(t, err, ErrCacheMiss) 149 }