gitlab.com/gitlab-org/labkit@v1.21.0/metrics/handler_test.go (about)

     1  package metrics
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"net/http/httptest"
     7  	"testing"
     8  
     9  	"github.com/prometheus/client_golang/prometheus"
    10  	dto "github.com/prometheus/client_model/go"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestNewHandlerFactory(t *testing.T) {
    15  	tests := []struct {
    16  		name        string
    17  		opts        []HandlerFactoryOption
    18  		handlerOpts []HandlerOption
    19  	}{
    20  		{
    21  			name: "basic",
    22  			opts: []HandlerFactoryOption{
    23  				WithNamespace("basic"),
    24  			},
    25  		},
    26  		{
    27  			name: "labels",
    28  			opts: []HandlerFactoryOption{
    29  				WithNamespace("labels"),
    30  				WithLabels("label1", "label2"),
    31  			},
    32  			handlerOpts: []HandlerOption{
    33  				WithLabelValues(map[string]string{"label1": "1", "label2": "1"}),
    34  			},
    35  		},
    36  		{
    37  			name: "request_duration_buckets",
    38  			opts: []HandlerFactoryOption{
    39  				WithNamespace("request_duration_buckets"),
    40  				WithRequestDurationBuckets([]float64{1, 2, 3}),
    41  			},
    42  		},
    43  		{
    44  			name: "time_to_write_header_duration_buckets",
    45  			opts: []HandlerFactoryOption{
    46  				WithNamespace("time_to_write_header_duration_buckets"),
    47  				WithTimeToWriteHeaderDurationBuckets([]float64{1, 2, 3}),
    48  			},
    49  		},
    50  		{
    51  			name: "byte_bucket_size_buckets",
    52  			opts: []HandlerFactoryOption{
    53  				WithNamespace("byte_bucket_size_buckets"),
    54  				WithByteSizeBuckets([]float64{1, 2, 3}),
    55  			},
    56  		},
    57  	}
    58  	for _, tt := range tests {
    59  		t.Run(tt.name, func(t *testing.T) {
    60  			got := NewHandlerFactory(tt.opts...)
    61  			require.NotNil(t, got)
    62  
    63  			var invoked bool
    64  			handler := got(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    65  				invoked = true
    66  				w.WriteHeader(200)
    67  				fmt.Fprint(w, "OK")
    68  			}), tt.handlerOpts...)
    69  
    70  			r := httptest.NewRequest("GET", "http://example.com", nil)
    71  
    72  			w := httptest.NewRecorder()
    73  			handler.ServeHTTP(w, r)
    74  
    75  			metrics, err := prometheus.DefaultGatherer.Gather()
    76  			require.NoError(t, err)
    77  			require.NotEmpty(t, metrics)
    78  
    79  			keyedMetrics := make(map[string]*dto.MetricFamily, len(metrics))
    80  			for _, v := range metrics {
    81  				keyedMetrics[*v.Name] = v
    82  			}
    83  
    84  			httpInFlightRequestsMetric := keyedMetrics[tt.name+"_http_"+httpInFlightRequestsMetricName]
    85  			require.NotNil(t, httpInFlightRequestsMetric, "No metric named %v", tt.name+"_http_"+httpInFlightRequestsMetricName)
    86  			require.Equal(t, 0.0, *httpInFlightRequestsMetric.Metric[0].Gauge.Value)
    87  
    88  			httpRequestsTotalMetric := keyedMetrics[tt.name+"_http_"+httpRequestsTotalMetricName]
    89  			require.NotNil(t, httpRequestsTotalMetric, "No metric named %v", tt.name+"_http_"+httpRequestsTotalMetricName)
    90  			require.Equal(t, 1.0, *httpRequestsTotalMetric.Metric[0].Counter.Value)
    91  
    92  			httpRequestDurationSecondsMetric := keyedMetrics[tt.name+"_http_"+httpRequestDurationSecondsMetricName]
    93  			require.NotNil(t, httpRequestDurationSecondsMetric, "No metric named %v", tt.name+"_http_"+httpRequestDurationSecondsMetricName)
    94  			require.Equal(t, uint64(1), *httpRequestDurationSecondsMetric.Metric[0].Histogram.SampleCount)
    95  
    96  			httpRequestSizeBytesMetric := keyedMetrics[tt.name+"_http_"+httpRequestSizeBytesMetricName]
    97  			require.NotNil(t, httpRequestSizeBytesMetric, "No metric named %v", tt.name+"_http_"+httpRequestSizeBytesMetricName)
    98  			require.Equal(t, uint64(1), *httpRequestSizeBytesMetric.Metric[0].Histogram.SampleCount)
    99  
   100  			httpResponseSizeBytesMetric := keyedMetrics[tt.name+"_http_"+httpResponseSizeBytesMetricName]
   101  			require.NotNil(t, httpResponseSizeBytesMetric, "No metric named %v", tt.name+"_http_"+httpResponseSizeBytesMetricName)
   102  			require.Equal(t, uint64(1), *httpResponseSizeBytesMetric.Metric[0].Histogram.SampleCount)
   103  
   104  			httpTimeToWriteHeaderSecondsMetric := keyedMetrics[tt.name+"_http_"+httpTimeToWriteHeaderSecondsMetricName]
   105  			require.NotNil(t, httpTimeToWriteHeaderSecondsMetric, "No metric named %v", tt.name+"_http_"+httpTimeToWriteHeaderSecondsMetricName)
   106  			require.Equal(t, uint64(1), *httpTimeToWriteHeaderSecondsMetric.Metric[0].Histogram.SampleCount)
   107  
   108  			require.True(t, invoked, "handler not executed")
   109  		})
   110  	}
   111  }