boulder/ratelimits/source_redis_test.go

117 lines
3.4 KiB
Go

package ratelimits
import (
"context"
"testing"
"time"
"github.com/letsencrypt/boulder/cmd"
"github.com/letsencrypt/boulder/metrics"
"github.com/letsencrypt/boulder/test"
"github.com/jmhodges/clock"
"github.com/redis/go-redis/v9"
)
func newTestRedisSource(clk clock.FakeClock, addrs map[string]string) *RedisSource {
CACertFile := "../test/certs/ipki/minica.pem"
CertFile := "../test/certs/ipki/localhost/cert.pem"
KeyFile := "../test/certs/ipki/localhost/key.pem"
tlsConfig := cmd.TLSConfig{
CACertFile: CACertFile,
CertFile: CertFile,
KeyFile: KeyFile,
}
tlsConfig2, err := tlsConfig.Load(metrics.NoopRegisterer)
if err != nil {
panic(err)
}
client := redis.NewRing(&redis.RingOptions{
Addrs: addrs,
Username: "unittest-rw",
Password: "824968fa490f4ecec1e52d5e34916bdb60d45f8d",
TLSConfig: tlsConfig2,
})
return NewRedisSource(client, clk, metrics.NoopRegisterer)
}
func newRedisTestLimiter(t *testing.T, clk clock.FakeClock) *Limiter {
return newTestLimiter(t, newTestRedisSource(clk, map[string]string{
"shard1": "10.33.33.4:4218",
"shard2": "10.33.33.5:4218",
}), clk)
}
func TestRedisSource_Ping(t *testing.T) {
clk := clock.NewFake()
workingSource := newTestRedisSource(clk, map[string]string{
"shard1": "10.33.33.4:4218",
"shard2": "10.33.33.5:4218",
})
err := workingSource.Ping(context.Background())
test.AssertNotError(t, err, "Ping should not error")
missingFirstShardSource := newTestRedisSource(clk, map[string]string{
"shard1": "10.33.33.4:1337",
"shard2": "10.33.33.5:4218",
})
err = missingFirstShardSource.Ping(context.Background())
test.AssertError(t, err, "Ping should not error")
missingSecondShardSource := newTestRedisSource(clk, map[string]string{
"shard1": "10.33.33.4:4218",
"shard2": "10.33.33.5:1337",
})
err = missingSecondShardSource.Ping(context.Background())
test.AssertError(t, err, "Ping should not error")
}
func TestRedisSource_BatchSetAndGet(t *testing.T) {
clk := clock.NewFake()
s := newTestRedisSource(clk, map[string]string{
"shard1": "10.33.33.4:4218",
"shard2": "10.33.33.5:4218",
})
set := map[string]time.Time{
"test1": clk.Now().Add(time.Second),
"test2": clk.Now().Add(time.Second * 2),
"test3": clk.Now().Add(time.Second * 3),
}
incr := map[string]increment{
"test1": {time.Second, time.Minute},
"test2": {time.Second * 2, time.Minute},
"test3": {time.Second * 3, time.Minute},
}
err := s.BatchSet(context.Background(), set)
test.AssertNotError(t, err, "BatchSet() should not error")
got, err := s.BatchGet(context.Background(), []string{"test1", "test2", "test3"})
test.AssertNotError(t, err, "BatchGet() should not error")
for k, v := range set {
test.AssertEquals(t, got[k], v)
}
err = s.BatchIncrement(context.Background(), incr)
test.AssertNotError(t, err, "BatchIncrement() should not error")
got, err = s.BatchGet(context.Background(), []string{"test1", "test2", "test3"})
test.AssertNotError(t, err, "BatchGet() should not error")
for k := range set {
test.AssertEquals(t, got[k], set[k].Add(incr[k].cost))
}
// Test that BatchGet() returns a zero time for a key that does not exist.
got, err = s.BatchGet(context.Background(), []string{"test1", "test4", "test3"})
test.AssertNotError(t, err, "BatchGet() should not error when a key isn't found")
test.Assert(t, got["test4"].IsZero(), "BatchGet() should return a zero time for a key that does not exist")
}