github.com/letsencrypt/boulder@v0.20251208.0/redis/metrics_test.go (about) 1 package redis 2 3 import ( 4 "strings" 5 "testing" 6 7 "github.com/prometheus/client_golang/prometheus" 8 "github.com/redis/go-redis/v9" 9 10 "github.com/letsencrypt/boulder/metrics" 11 ) 12 13 type mockPoolStatGetter struct{} 14 15 var _ poolStatGetter = mockPoolStatGetter{} 16 17 func (mockPoolStatGetter) PoolStats() *redis.PoolStats { 18 return &redis.PoolStats{ 19 Hits: 13, 20 Misses: 7, 21 Timeouts: 4, 22 TotalConns: 1000, 23 IdleConns: 500, 24 StaleConns: 10, 25 } 26 } 27 28 func TestMetrics(t *testing.T) { 29 mets := newClientMetricsCollector(mockPoolStatGetter{}, 30 prometheus.Labels{ 31 "foo": "bar", 32 }) 33 // Check that it has the correct type to satisfy MustRegister 34 metrics.NoopRegisterer.MustRegister(mets) 35 36 expectedMetrics := 6 37 outChan := make(chan prometheus.Metric, expectedMetrics) 38 mets.Collect(outChan) 39 40 results := make(map[string]bool) 41 for range expectedMetrics { 42 metric := <-outChan 43 t.Log(metric.Desc().String()) 44 results[metric.Desc().String()] = true 45 } 46 47 expected := strings.Split( 48 `Desc{fqName: "redis_connection_pool_lookups", help: "Number of lookups for a connection in the pool, labeled by hit/miss", constLabels: {foo="bar"}, variableLabels: {result}} 49 Desc{fqName: "redis_connection_pool_lookups", help: "Number of lookups for a connection in the pool, labeled by hit/miss", constLabels: {foo="bar"}, variableLabels: {result}} 50 Desc{fqName: "redis_connection_pool_lookups", help: "Number of lookups for a connection in the pool, labeled by hit/miss", constLabels: {foo="bar"}, variableLabels: {result}} 51 Desc{fqName: "redis_connection_pool_total_conns", help: "Number of total connections in the pool.", constLabels: {foo="bar"}, variableLabels: {}} 52 Desc{fqName: "redis_connection_pool_idle_conns", help: "Number of idle connections in the pool.", constLabels: {foo="bar"}, variableLabels: {}} 53 Desc{fqName: "redis_connection_pool_stale_conns", help: "Number of stale connections removed from the pool.", constLabels: {foo="bar"}, variableLabels: {}}`, 54 "\n") 55 56 for _, e := range expected { 57 if !results[e] { 58 t.Errorf("expected metrics to contain %q, but they didn't", e) 59 } 60 } 61 62 if len(results) > len(expected) { 63 t.Errorf("expected metrics to contain %d entries, but they contained %d", 64 len(expected), len(results)) 65 } 66 } 67 68 func TestMustRegisterClientMetricsCollector(t *testing.T) { 69 client := mockPoolStatGetter{} 70 stats := prometheus.NewRegistry() 71 // First registration should succeed. 72 MustRegisterClientMetricsCollector(client, stats, map[string]string{"foo": "bar"}, "baz") 73 // Duplicate registration should succeed. 74 MustRegisterClientMetricsCollector(client, stats, map[string]string{"foo": "bar"}, "baz") 75 // Registration with different label values should succeed. 76 MustRegisterClientMetricsCollector(client, stats, map[string]string{"f00": "b4r"}, "b4z") 77 }