github.com/thanos-io/thanos@v0.32.5/pkg/cacheutil/redis_client_test.go (about) 1 // Copyright (c) The Thanos Authors. 2 // Licensed under the Apache License 2.0. 3 4 package cacheutil 5 6 import ( 7 "context" 8 "os" 9 "testing" 10 "time" 11 12 "github.com/alicebob/miniredis/v2" 13 "github.com/efficientgo/core/testutil" 14 "github.com/go-kit/log" 15 "github.com/prometheus/client_golang/prometheus" 16 ) 17 18 func TestRedisClient(t *testing.T) { 19 // Init some data to conveniently define test cases later one. 20 key1 := "key1" 21 key2 := "key2" 22 key3 := "key3" 23 value1 := []byte{1} 24 value2 := []byte{2} 25 value3 := []byte{3} 26 27 type args struct { 28 data map[string][]byte 29 fetchKeys []string 30 } 31 type want struct { 32 hits map[string][]byte 33 } 34 tests := []struct { 35 name string 36 args args 37 want want 38 }{ 39 { 40 name: "all hit", 41 args: args{ 42 data: map[string][]byte{ 43 key1: value1, 44 key2: value2, 45 key3: value3, 46 }, 47 fetchKeys: []string{key1, key2, key3}, 48 }, 49 want: want{ 50 hits: map[string][]byte{ 51 key1: value1, 52 key2: value2, 53 key3: value3, 54 }, 55 }, 56 }, 57 { 58 name: "partial hit", 59 args: args{ 60 data: map[string][]byte{ 61 key1: value1, 62 key2: value2, 63 }, 64 fetchKeys: []string{key1, key2, key3}, 65 }, 66 want: want{ 67 hits: map[string][]byte{ 68 key1: value1, 69 key2: value2, 70 }, 71 }, 72 }, 73 { 74 name: "not hit", 75 args: args{ 76 data: map[string][]byte{}, 77 fetchKeys: []string{key1, key2, key3}, 78 }, 79 want: want{ 80 hits: map[string][]byte{}, 81 }, 82 }, 83 } 84 s, err := miniredis.Run() 85 if err != nil { 86 testutil.Ok(t, err) 87 } 88 defer s.Close() 89 redisConfigs := []struct { 90 name string 91 redisConfig func() RedisClientConfig 92 }{ 93 { 94 name: "MaxConcurrency>0", 95 redisConfig: func() RedisClientConfig { 96 cfg := DefaultRedisClientConfig 97 cfg.Addr = s.Addr() 98 cfg.MaxGetMultiConcurrency = 2 99 cfg.GetMultiBatchSize = 2 100 cfg.MaxSetMultiConcurrency = 2 101 cfg.SetMultiBatchSize = 2 102 return cfg 103 }, 104 }, 105 { 106 name: "MaxConcurrency=0", 107 redisConfig: func() RedisClientConfig { 108 cfg := DefaultRedisClientConfig 109 cfg.Addr = s.Addr() 110 cfg.MaxGetMultiConcurrency = 0 111 cfg.GetMultiBatchSize = 0 112 cfg.MaxSetMultiConcurrency = 0 113 cfg.SetMultiBatchSize = 0 114 return cfg 115 }, 116 }, 117 } 118 for _, tt := range tests { 119 t.Run(tt.name, func(t *testing.T) { 120 for _, redisConfig := range redisConfigs { 121 t.Run(tt.name+redisConfig.name, func(t *testing.T) { 122 logger := log.NewLogfmtLogger(os.Stderr) 123 reg := prometheus.NewRegistry() 124 c, err := NewRedisClientWithConfig(logger, t.Name(), redisConfig.redisConfig(), reg) 125 if err != nil { 126 testutil.Ok(t, err) 127 } 128 defer c.Stop() 129 defer s.FlushAll() 130 ctx := context.Background() 131 c.SetMulti(tt.args.data, time.Hour) 132 hits := c.GetMulti(ctx, tt.args.fetchKeys) 133 testutil.Equals(t, tt.want.hits, hits) 134 }) 135 } 136 }) 137 } 138 } 139 140 func TestValidateRedisConfig(t *testing.T) { 141 tests := []struct { 142 name string 143 config func() RedisClientConfig 144 expect_err bool // func(*testing.T, interface{}, error) 145 }{ 146 { 147 name: "simpleConfig", 148 config: func() RedisClientConfig { 149 cfg := DefaultRedisClientConfig 150 cfg.Addr = "127.0.0.1:6789" 151 cfg.Username = "user" 152 cfg.Password = "1234" 153 return cfg 154 }, 155 expect_err: false, 156 }, 157 { 158 name: "tlsConfigDefaults", 159 config: func() RedisClientConfig { 160 cfg := DefaultRedisClientConfig 161 cfg.Addr = "127.0.0.1:6789" 162 cfg.Username = "user" 163 cfg.Password = "1234" 164 cfg.TLSEnabled = true 165 return cfg 166 }, 167 expect_err: false, 168 }, 169 { 170 name: "tlsClientCertConfig", 171 config: func() RedisClientConfig { 172 cfg := DefaultRedisClientConfig 173 cfg.Addr = "127.0.0.1:6789" 174 cfg.Username = "user" 175 cfg.Password = "1234" 176 cfg.TLSEnabled = true 177 cfg.TLSConfig = TLSConfig{ 178 CertFile: "cert/client.pem", 179 KeyFile: "cert/client.key", 180 } 181 return cfg 182 }, 183 expect_err: false, 184 }, 185 { 186 name: "tlsInvalidClientCertConfig", 187 config: func() RedisClientConfig { 188 cfg := DefaultRedisClientConfig 189 cfg.Addr = "127.0.0.1:6789" 190 cfg.Username = "user" 191 cfg.Password = "1234" 192 cfg.TLSEnabled = true 193 cfg.TLSConfig = TLSConfig{ 194 CertFile: "cert/client.pem", 195 } 196 return cfg 197 }, 198 expect_err: true, 199 }, 200 } 201 202 for _, tt := range tests { 203 t.Run(tt.name, func(t *testing.T) { 204 cfg := tt.config() 205 206 if tt.expect_err { 207 testutil.NotOk(t, cfg.validate()) 208 } else { 209 testutil.Ok(t, cfg.validate()) 210 } 211 }) 212 } 213 214 } 215 216 func TestMultipleRedisClient(t *testing.T) { 217 s, err := miniredis.Run() 218 if err != nil { 219 testutil.Ok(t, err) 220 } 221 defer s.Close() 222 cfg := DefaultRedisClientConfig 223 cfg.Addr = s.Addr() 224 logger := log.NewLogfmtLogger(os.Stderr) 225 reg := prometheus.NewRegistry() 226 cl, err := NewRedisClientWithConfig(logger, "test1", cfg, reg) 227 testutil.Ok(t, err) 228 t.Cleanup(cl.Stop) 229 cl, err = NewRedisClientWithConfig(logger, "test2", cfg, reg) 230 testutil.Ok(t, err) 231 t.Cleanup(cl.Stop) 232 }