gitlab.com/ignitionrobotics/web/ign-go@v1.0.0-rc4/monitoring/prometheus/prometheus_test.go (about)

     1  package prometheus
     2  
     3  import (
     4  	"github.com/prometheus/client_golang/prometheus"
     5  	"github.com/prometheus/client_golang/prometheus/promhttp"
     6  	"github.com/prometheus/client_golang/prometheus/testutil"
     7  	"github.com/stretchr/testify/suite"
     8  	"net/http"
     9  	"net/http/httptest"
    10  	"reflect"
    11  	"strconv"
    12  	"testing"
    13  )
    14  
    15  func TestWebsocketAddressSuite(t *testing.T) {
    16  	suite.Run(t, &PrometheusProviderTestSuite{})
    17  }
    18  
    19  type PrometheusProviderTestSuite struct {
    20  	suite.Suite
    21  	provider  *provider
    22  	testRoute string
    23  }
    24  
    25  func (suite *PrometheusProviderTestSuite) SetupSuite() {
    26  	suite.provider = NewPrometheusProvider("").(*provider)
    27  	suite.testRoute = "/test/route"
    28  }
    29  
    30  func (suite *PrometheusProviderTestSuite) TestNewPrometheusProvider() {
    31  	route := ""
    32  	p := NewPrometheusProvider(route).(*provider)
    33  	suite.Equal(defaultMetricsRoute, p.route)
    34  
    35  	route = suite.testRoute
    36  	p = NewPrometheusProvider(route).(*provider)
    37  	suite.Equal(route, p.route)
    38  }
    39  
    40  func (suite *PrometheusProviderTestSuite) TestMetricsRoute() {
    41  	suite.Equal(defaultMetricsRoute, suite.provider.MetricsRoute())
    42  }
    43  
    44  func (suite *PrometheusProviderTestSuite) TestMetricsHandler() {
    45  	expected := reflect.ValueOf(promhttp.Handler()).Pointer()
    46  	result := reflect.ValueOf(suite.provider.MetricsHandler()).Pointer()
    47  	suite.Equal(expected, result)
    48  }
    49  
    50  func (suite *PrometheusProviderTestSuite) TestMiddleware() {
    51  	// Prometheus test metrics
    52  	// RequestDurationSeconds
    53  	requestDurationSeconds := prometheus.NewHistogramVec(
    54  		prometheus.HistogramOpts{
    55  			Subsystem: "http",
    56  			Name:      "request_duration_seconds",
    57  			Help:      "Seconds spent serving HTTP requests.",
    58  			Buckets:   prometheus.DefBuckets,
    59  		},
    60  		[]string{"method", "path", "status"},
    61  	)
    62  	suite.provider.requestDurationSeconds = requestDurationSeconds
    63  
    64  	// TotalRequests
    65  	totalRequests := prometheus.NewCounterVec(
    66  		prometheus.CounterOpts{
    67  			Subsystem: "http",
    68  			Name:      "requests_total",
    69  			Help:      "The total number of HTTP requests.",
    70  		},
    71  		[]string{"status"},
    72  	)
    73  	suite.provider.totalRequests = totalRequests
    74  
    75  	testcases := []struct {
    76  		Method string
    77  		Path   string
    78  		Status string
    79  		// CounterValue contains the expected value of the TotalRequests metric for the given labels after processing
    80  		// each request
    81  		CounterValue float64
    82  	}{
    83  		{
    84  			Method:       "GET",
    85  			Path:         suite.testRoute,
    86  			Status:       "200",
    87  			CounterValue: 1,
    88  		},
    89  		{
    90  			Method:       "GET",
    91  			Path:         suite.testRoute,
    92  			Status:       "400",
    93  			CounterValue: 1,
    94  		},
    95  		{
    96  			Method:       "GET",
    97  			Path:         suite.testRoute,
    98  			Status:       "500",
    99  			CounterValue: 1,
   100  		},
   101  		{
   102  			Method:       "POST",
   103  			Path:         suite.testRoute,
   104  			Status:       "200",
   105  			CounterValue: 2,
   106  		},
   107  		{
   108  			Method:       "POST",
   109  			Path:         suite.testRoute,
   110  			Status:       "400",
   111  			CounterValue: 2,
   112  		},
   113  		{
   114  			Method:       "POST",
   115  			Path:         suite.testRoute,
   116  			Status:       "500",
   117  			CounterValue: 2,
   118  		},
   119  	}
   120  
   121  	middleware := suite.provider.Middleware()
   122  	// Creates a mock HTTP handler
   123  	makeHandler := func(status string) http.HandlerFunc {
   124  		intStatus, err := strconv.Atoi(status)
   125  		suite.NoError(err)
   126  
   127  		return func(w http.ResponseWriter, r *http.Request) {
   128  			w.WriteHeader(intStatus)
   129  		}
   130  	}
   131  	for _, tc := range testcases {
   132  		// Check the values before sending the request
   133  		counterValue := testutil.ToFloat64(suite.provider.totalRequests.WithLabelValues(tc.Status))
   134  		suite.Equal(tc.CounterValue-1, counterValue)
   135  
   136  		// Send requests
   137  		req, err := http.NewRequest(tc.Method, "http://example.com"+tc.Path, nil)
   138  		suite.NoError(err)
   139  		rr := httptest.NewRecorder()
   140  
   141  		middleware.ServeHTTP(rr, req, makeHandler(tc.Status))
   142  
   143  		// Check that the counter has been updated
   144  		counterValue = testutil.ToFloat64(suite.provider.totalRequests.WithLabelValues(tc.Status))
   145  		suite.Equal(tc.CounterValue, counterValue)
   146  	}
   147  }