gitlab.com/gitlab-org/labkit@v1.21.0/monitoring/start_options_test.go (about) 1 package monitoring 2 3 import ( 4 "net" 5 "net/http" 6 "runtime/debug" 7 "testing" 8 "time" 9 10 "github.com/prometheus/client_golang/prometheus" 11 dto "github.com/prometheus/client_model/go" 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 ) 15 16 type customGatherer struct { 17 } 18 19 func (c customGatherer) Gather() ([]*dto.MetricFamily, error) { 20 return nil, nil 21 } 22 23 type customRegisterer struct { 24 } 25 26 func (c customRegisterer) Register(collector prometheus.Collector) error { 27 return nil 28 } 29 30 func (c customRegisterer) MustRegister(collector ...prometheus.Collector) { 31 } 32 33 func (c customRegisterer) Unregister(collector prometheus.Collector) bool { 34 return false 35 } 36 37 func checkDefaultGatherer(t *testing.T, g prometheus.Gatherer) { 38 t.Helper() 39 40 assert.Equal(t, prometheus.DefaultGatherer, g) 41 } 42 43 func checkCustomGatherer(t *testing.T, g prometheus.Gatherer) { 44 t.Helper() 45 46 assert.Equal(t, customGatherer{}, g) 47 } 48 49 func checkDefaultRegisterer(t *testing.T, g prometheus.Registerer) { 50 t.Helper() 51 52 assert.Equal(t, prometheus.DefaultRegisterer, g) 53 } 54 55 func checkCustomRegisterer(t *testing.T, g prometheus.Registerer) { 56 t.Helper() 57 58 assert.Equal(t, customRegisterer{}, g) 59 } 60 func checkDefaultListener(t *testing.T, f listenerFactory) { 61 t.Helper() 62 63 gotListener, err := f() 64 require.Exactly(t, nil, gotListener) 65 require.NoError(t, err) 66 } 67 68 func isTCPListener(t *testing.T, f listenerFactory) { 69 t.Helper() 70 71 gotListener, err := f() 72 require.NoError(t, err) 73 require.IsType(t, &net.TCPListener{}, gotListener) 74 } 75 76 func Test_applyOptions(t *testing.T) { 77 testListener, err := net.Listen("tcp", ":0") 78 require.NoError(t, err) 79 defer testListener.Close() 80 81 isTestListener := func(t *testing.T, f listenerFactory) { 82 t.Helper() 83 84 gotListener, err := f() 85 require.NoError(t, err) 86 require.Exactly(t, testListener, gotListener) 87 } 88 89 testMux := http.NewServeMux() 90 testMux.HandleFunc("/debug/foo", func(writer http.ResponseWriter, r *http.Request) {}) 91 92 testServer := &http.Server{ 93 ReadTimeout: 1 * time.Second, 94 } 95 96 tests := []struct { 97 name string 98 opts []Option 99 wantListenerCheck func(t *testing.T, f listenerFactory) 100 wantGathererCheck func(t *testing.T, g prometheus.Gatherer) 101 wantRegistererCheck func(t *testing.T, g prometheus.Registerer) 102 wantbuildInfoGaugeLabels prometheus.Labels 103 wantVersion string 104 wantContinuousProfilingDisabled bool 105 wantMetricsDisabled bool 106 wantPprofDisabled bool 107 wantMetricsHandlerPattern string 108 wantProfilerCredentialsFile string 109 wantServeMux *http.ServeMux 110 wantServer *http.Server 111 }{ 112 { 113 name: "empty", 114 opts: nil, 115 wantListenerCheck: checkDefaultListener, 116 wantGathererCheck: checkDefaultGatherer, 117 wantRegistererCheck: checkDefaultRegisterer, 118 wantMetricsHandlerPattern: "/metrics", 119 wantServeMux: http.NewServeMux(), 120 wantServer: &http.Server{}, 121 }, 122 { 123 name: "with_server", 124 opts: []Option{WithServer(testServer)}, 125 wantListenerCheck: checkDefaultListener, 126 wantGathererCheck: checkDefaultGatherer, 127 wantRegistererCheck: checkDefaultRegisterer, 128 wantMetricsHandlerPattern: "/metrics", 129 wantServeMux: http.NewServeMux(), 130 wantServer: testServer, 131 }, 132 { 133 name: "with_listener", 134 opts: []Option{WithListener(testListener)}, 135 wantListenerCheck: isTestListener, 136 wantGathererCheck: checkDefaultGatherer, 137 wantRegistererCheck: checkDefaultRegisterer, 138 wantMetricsHandlerPattern: "/metrics", 139 wantServeMux: http.NewServeMux(), 140 wantServer: &http.Server{}, 141 }, 142 { 143 name: "with_listen_address", 144 opts: []Option{WithListenerAddress(":0")}, 145 wantListenerCheck: isTCPListener, 146 wantGathererCheck: checkDefaultGatherer, 147 wantRegistererCheck: checkDefaultRegisterer, 148 wantMetricsHandlerPattern: "/metrics", 149 wantServeMux: http.NewServeMux(), 150 wantServer: &http.Server{}, 151 }, 152 { 153 name: "with_build_information", 154 opts: []Option{WithBuildInformation("1.0.0", "2018-01-02T00:00:00Z")}, 155 wantListenerCheck: checkDefaultListener, 156 wantGathererCheck: checkDefaultGatherer, 157 wantRegistererCheck: checkDefaultRegisterer, 158 wantbuildInfoGaugeLabels: prometheus.Labels{"built": "2018-01-02T00:00:00Z", "version": "1.0.0"}, 159 wantVersion: "1.0.0", 160 wantMetricsHandlerPattern: "/metrics", 161 wantServeMux: http.NewServeMux(), 162 wantServer: &http.Server{}, 163 }, 164 { 165 name: "with_build_extra_labels", 166 opts: []Option{WithBuildExtraLabels(map[string]string{"git_version": "2.0.0"})}, 167 wantListenerCheck: checkDefaultListener, 168 wantGathererCheck: checkDefaultGatherer, 169 wantRegistererCheck: checkDefaultRegisterer, 170 wantbuildInfoGaugeLabels: prometheus.Labels{"git_version": "2.0.0"}, 171 wantMetricsHandlerPattern: "/metrics", 172 wantServeMux: http.NewServeMux(), 173 wantServer: &http.Server{}, 174 }, 175 { 176 name: "with_build_information_and_extra_labels", 177 opts: []Option{ 178 WithBuildInformation("1.0.0", "2018-01-02T00:00:00Z"), 179 WithBuildExtraLabels(map[string]string{"git_version": "2.0.0"}), 180 }, 181 wantListenerCheck: checkDefaultListener, 182 wantGathererCheck: checkDefaultGatherer, 183 wantRegistererCheck: checkDefaultRegisterer, 184 wantbuildInfoGaugeLabels: prometheus.Labels{ 185 "built": "2018-01-02T00:00:00Z", 186 "version": "1.0.0", 187 "git_version": "2.0.0", 188 }, 189 wantVersion: "1.0.0", 190 wantMetricsHandlerPattern: "/metrics", 191 wantServeMux: http.NewServeMux(), 192 wantServer: &http.Server{}, 193 }, 194 { 195 name: "Go build information", 196 opts: []Option{ 197 WithGoBuildInformation(&debug.BuildInfo{ 198 GoVersion: "1.18", 199 Path: "gitlab.com/gitlab-org/labkit", 200 Main: debug.Module{ 201 Version: "1.0.0", 202 }, 203 Settings: []debug.BuildSetting{ 204 {Key: "vcs.revision", Value: "61b68cb5bb5c906a89bf3009e5f229caaccb6317"}, 205 {Key: "vcs.modified", Value: "false"}, 206 {Key: "vcs.time", Value: "2018-01-02T00:00:00Z"}, 207 }, 208 }), 209 }, 210 wantListenerCheck: checkDefaultListener, 211 wantGathererCheck: checkDefaultGatherer, 212 wantRegistererCheck: checkDefaultRegisterer, 213 wantbuildInfoGaugeLabels: prometheus.Labels{ 214 "committed": "2018-01-02T00:00:00Z", 215 "go_version": "1.18", 216 "module_path": "gitlab.com/gitlab-org/labkit", 217 "module_version": "1.0.0", 218 "modified": "false", 219 "version": "61b68cb5bb5c906a89bf3009e5f229caaccb6317", 220 }, 221 wantVersion: "61b68cb5bb5c906a89bf3009e5f229caaccb6317", 222 wantMetricsHandlerPattern: "/metrics", 223 wantServeMux: http.NewServeMux(), 224 wantServer: &http.Server{}, 225 }, 226 { 227 name: "combined", 228 opts: []Option{ 229 WithListenerAddress(":0"), 230 WithBuildInformation("1.0.0", "2018-01-02T00:00:00Z"), 231 WithBuildExtraLabels(map[string]string{"git_version": "2.0.0"}), 232 }, 233 wantListenerCheck: isTCPListener, 234 wantGathererCheck: checkDefaultGatherer, 235 wantRegistererCheck: checkDefaultRegisterer, 236 wantbuildInfoGaugeLabels: prometheus.Labels{ 237 "built": "2018-01-02T00:00:00Z", 238 "version": "1.0.0", 239 "git_version": "2.0.0", 240 }, 241 wantVersion: "1.0.0", 242 wantMetricsHandlerPattern: "/metrics", 243 wantServeMux: http.NewServeMux(), 244 wantServer: &http.Server{}, 245 }, 246 { 247 name: "without continuous profiling", 248 opts: []Option{WithoutContinuousProfiling()}, 249 wantListenerCheck: checkDefaultListener, 250 wantGathererCheck: checkDefaultGatherer, 251 wantRegistererCheck: checkDefaultRegisterer, 252 wantContinuousProfilingDisabled: true, 253 wantMetricsHandlerPattern: "/metrics", 254 wantServeMux: http.NewServeMux(), 255 wantServer: &http.Server{}, 256 }, 257 { 258 name: "without metrics", 259 opts: []Option{WithoutMetrics()}, 260 wantListenerCheck: checkDefaultListener, 261 wantGathererCheck: checkDefaultGatherer, 262 wantRegistererCheck: checkDefaultRegisterer, 263 wantMetricsDisabled: true, 264 wantMetricsHandlerPattern: "/metrics", 265 wantServeMux: http.NewServeMux(), 266 wantServer: &http.Server{}, 267 }, 268 { 269 name: "without pprof", 270 opts: []Option{WithoutPprof()}, 271 wantListenerCheck: checkDefaultListener, 272 wantGathererCheck: checkDefaultGatherer, 273 wantRegistererCheck: checkDefaultRegisterer, 274 wantPprofDisabled: true, 275 wantMetricsHandlerPattern: "/metrics", 276 wantServeMux: http.NewServeMux(), 277 wantServer: &http.Server{}, 278 }, 279 { 280 name: "with custom metrics handler pattern", 281 opts: []Option{WithMetricsHandlerPattern("/foo")}, 282 wantListenerCheck: checkDefaultListener, 283 wantGathererCheck: checkDefaultGatherer, 284 wantRegistererCheck: checkDefaultRegisterer, 285 wantMetricsHandlerPattern: "/foo", 286 wantServeMux: http.NewServeMux(), 287 wantServer: &http.Server{}, 288 }, 289 { 290 name: "with profiler credentials file", 291 opts: []Option{WithProfilerCredentialsFile("/path/to/credentials.json")}, 292 wantListenerCheck: checkDefaultListener, 293 wantGathererCheck: checkDefaultGatherer, 294 wantRegistererCheck: checkDefaultRegisterer, 295 wantMetricsHandlerPattern: "/metrics", 296 wantProfilerCredentialsFile: "/path/to/credentials.json", 297 wantServeMux: http.NewServeMux(), 298 wantServer: &http.Server{}, 299 }, 300 { 301 name: "with custom gatherer", 302 opts: []Option{WithPrometheusGatherer(customGatherer{})}, 303 wantListenerCheck: checkDefaultListener, 304 wantGathererCheck: checkCustomGatherer, 305 wantRegistererCheck: checkDefaultRegisterer, 306 wantMetricsHandlerPattern: "/metrics", 307 wantServeMux: http.NewServeMux(), 308 wantServer: &http.Server{}, 309 }, 310 { 311 name: "with custom registerer", 312 opts: []Option{WithPrometheusRegisterer(customRegisterer{})}, 313 wantListenerCheck: checkDefaultListener, 314 wantGathererCheck: checkDefaultGatherer, 315 wantRegistererCheck: checkCustomRegisterer, 316 wantMetricsHandlerPattern: "/metrics", 317 wantServeMux: http.NewServeMux(), 318 wantServer: &http.Server{}, 319 }, 320 { 321 name: "with custom mux", 322 opts: []Option{WithServeMux(testMux)}, 323 wantListenerCheck: checkDefaultListener, 324 wantGathererCheck: checkDefaultGatherer, 325 wantRegistererCheck: checkDefaultRegisterer, 326 wantMetricsHandlerPattern: "/metrics", 327 wantServeMux: testMux, 328 wantServer: &http.Server{}, 329 }, 330 { 331 name: "with custom mux and server", 332 opts: []Option{WithServeMux(testMux), WithServer(testServer)}, 333 wantListenerCheck: checkDefaultListener, 334 wantGathererCheck: checkDefaultGatherer, 335 wantRegistererCheck: checkDefaultRegisterer, 336 wantMetricsHandlerPattern: "/metrics", 337 wantServeMux: testMux, 338 wantServer: testServer, 339 }, 340 } 341 for _, tt := range tests { 342 t.Run(tt.name, func(t *testing.T) { 343 got := applyOptions(tt.opts) 344 tt.wantListenerCheck(t, got.listenerFactory) 345 tt.wantGathererCheck(t, got.gatherer) 346 tt.wantRegistererCheck(t, got.registerer) 347 require.Equal(t, tt.wantVersion, got.version) 348 require.Equal(t, tt.wantContinuousProfilingDisabled, got.continuousProfilingDisabled) 349 require.Equal(t, tt.wantMetricsDisabled, got.metricsDisabled) 350 require.Equal(t, tt.wantPprofDisabled, got.pprofDisabled) 351 require.Equal(t, tt.wantMetricsHandlerPattern, got.metricsHandlerPattern) 352 require.Equal(t, tt.wantProfilerCredentialsFile, got.profilerCredentialsFile) 353 require.Equal(t, tt.wantServeMux, got.serveMux) 354 require.Equal(t, tt.wantServer, got.server) 355 356 if tt.wantbuildInfoGaugeLabels == nil { 357 require.Equal(t, prometheus.Labels{}, got.buildInfoGaugeLabels) 358 } else { 359 require.Equal(t, tt.wantbuildInfoGaugeLabels, got.buildInfoGaugeLabels) 360 } 361 }) 362 } 363 }