github.com/letsencrypt/boulder@v0.20251208.0/ratelimits/source_redis_test.go (about)

     1  package ratelimits
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/letsencrypt/boulder/cmd"
     9  	"github.com/letsencrypt/boulder/metrics"
    10  	"github.com/letsencrypt/boulder/test"
    11  
    12  	"github.com/jmhodges/clock"
    13  	"github.com/redis/go-redis/v9"
    14  )
    15  
    16  func newTestRedisSource(clk clock.FakeClock, addrs map[string]string) *RedisSource {
    17  	CACertFile := "../test/certs/ipki/minica.pem"
    18  	CertFile := "../test/certs/ipki/localhost/cert.pem"
    19  	KeyFile := "../test/certs/ipki/localhost/key.pem"
    20  	tlsConfig := cmd.TLSConfig{
    21  		CACertFile: CACertFile,
    22  		CertFile:   CertFile,
    23  		KeyFile:    KeyFile,
    24  	}
    25  	tlsConfig2, err := tlsConfig.Load(metrics.NoopRegisterer)
    26  	if err != nil {
    27  		panic(err)
    28  	}
    29  
    30  	client := redis.NewRing(&redis.RingOptions{
    31  		Addrs:     addrs,
    32  		Username:  "boulder",
    33  		Password:  "824968fa490f4ecec1e52d5e34916bdb60d45f8d",
    34  		TLSConfig: tlsConfig2,
    35  	})
    36  	return NewRedisSource(client, clk, metrics.NoopRegisterer)
    37  }
    38  
    39  func newRedisTestLimiter(t *testing.T, clk clock.FakeClock) *Limiter {
    40  	return newTestLimiter(t, newTestRedisSource(clk, map[string]string{
    41  		"shard1": "10.77.77.4:4218",
    42  		"shard2": "10.77.77.5:4218",
    43  	}), clk)
    44  }
    45  
    46  func TestRedisSource_Ping(t *testing.T) {
    47  	clk := clock.NewFake()
    48  	workingSource := newTestRedisSource(clk, map[string]string{
    49  		"shard1": "10.77.77.4:4218",
    50  		"shard2": "10.77.77.5:4218",
    51  	})
    52  
    53  	err := workingSource.Ping(context.Background())
    54  	test.AssertNotError(t, err, "Ping should not error")
    55  
    56  	missingFirstShardSource := newTestRedisSource(clk, map[string]string{
    57  		"shard1": "10.77.77.4:1337",
    58  		"shard2": "10.77.77.5:4218",
    59  	})
    60  
    61  	err = missingFirstShardSource.Ping(context.Background())
    62  	test.AssertError(t, err, "Ping should not error")
    63  
    64  	missingSecondShardSource := newTestRedisSource(clk, map[string]string{
    65  		"shard1": "10.77.77.4:4218",
    66  		"shard2": "10.77.77.5:1337",
    67  	})
    68  
    69  	err = missingSecondShardSource.Ping(context.Background())
    70  	test.AssertError(t, err, "Ping should not error")
    71  }
    72  
    73  func TestRedisSource_BatchSetAndGet(t *testing.T) {
    74  	clk := clock.NewFake()
    75  	s := newTestRedisSource(clk, map[string]string{
    76  		"shard1": "10.77.77.4:4218",
    77  		"shard2": "10.77.77.5:4218",
    78  	})
    79  
    80  	set := map[string]time.Time{
    81  		"test1": clk.Now().Add(time.Second),
    82  		"test2": clk.Now().Add(time.Second * 2),
    83  		"test3": clk.Now().Add(time.Second * 3),
    84  	}
    85  
    86  	incr := map[string]increment{
    87  		"test1": {time.Second, time.Minute},
    88  		"test2": {time.Second * 2, time.Minute},
    89  		"test3": {time.Second * 3, time.Minute},
    90  	}
    91  
    92  	err := s.BatchSet(context.Background(), set)
    93  	test.AssertNotError(t, err, "BatchSet() should not error")
    94  
    95  	got, err := s.BatchGet(context.Background(), []string{"test1", "test2", "test3"})
    96  	test.AssertNotError(t, err, "BatchGet() should not error")
    97  
    98  	for k, v := range set {
    99  		test.AssertEquals(t, got[k], v)
   100  	}
   101  
   102  	err = s.BatchIncrement(context.Background(), incr)
   103  	test.AssertNotError(t, err, "BatchIncrement() should not error")
   104  
   105  	got, err = s.BatchGet(context.Background(), []string{"test1", "test2", "test3"})
   106  	test.AssertNotError(t, err, "BatchGet() should not error")
   107  
   108  	for k := range set {
   109  		test.AssertEquals(t, got[k], set[k].Add(incr[k].cost))
   110  	}
   111  
   112  	// Test that BatchGet() returns a zero time for a key that does not exist.
   113  	got, err = s.BatchGet(context.Background(), []string{"test1", "test4", "test3"})
   114  	test.AssertNotError(t, err, "BatchGet() should not error when a key isn't found")
   115  	test.Assert(t, got["test4"].IsZero(), "BatchGet() should return a zero time for a key that does not exist")
   116  }