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  }