github.com/netdata/go.d.plugin@v0.58.1/modules/prometheus/prometheus_test.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package prometheus 4 5 import ( 6 "fmt" 7 "net/http" 8 "net/http/httptest" 9 "testing" 10 11 "github.com/netdata/go.d.plugin/agent/module" 12 "github.com/netdata/go.d.plugin/pkg/prometheus/selector" 13 "github.com/netdata/go.d.plugin/pkg/web" 14 15 "github.com/stretchr/testify/assert" 16 "github.com/stretchr/testify/require" 17 ) 18 19 func TestPrometheus_Init(t *testing.T) { 20 tests := map[string]struct { 21 config Config 22 wantFail bool 23 }{ 24 "non empty URL": { 25 wantFail: false, 26 config: Config{HTTP: web.HTTP{Request: web.Request{URL: "http://127.0.0.1:9090/metric"}}}, 27 }, 28 "invalid selector syntax": { 29 wantFail: true, 30 config: Config{ 31 HTTP: web.HTTP{Request: web.Request{URL: "http://127.0.0.1:9090/metric"}}, 32 Selector: selector.Expr{Allow: []string{`name{label=#"value"}`}}, 33 }, 34 }, 35 "default": { 36 wantFail: true, 37 config: New().Config, 38 }, 39 } 40 41 for name, test := range tests { 42 t.Run(name, func(t *testing.T) { 43 prom := New() 44 prom.Config = test.config 45 46 if test.wantFail { 47 assert.False(t, prom.Init()) 48 } else { 49 assert.True(t, prom.Init()) 50 } 51 }) 52 } 53 } 54 55 func TestPrometheus_Cleanup(t *testing.T) { 56 assert.NotPanics(t, New().Cleanup) 57 58 prom := New() 59 prom.URL = "http://127.0.0.1" 60 require.True(t, prom.Init()) 61 assert.NotPanics(t, prom.Cleanup) 62 } 63 64 func TestPrometheus_Check(t *testing.T) { 65 tests := map[string]struct { 66 prepare func() (prom *Prometheus, cleanup func()) 67 wantFail bool 68 }{ 69 "success if endpoint returns valid metrics in prometheus format": { 70 wantFail: false, 71 prepare: func() (prom *Prometheus, cleanup func()) { 72 srv := httptest.NewServer(http.HandlerFunc( 73 func(w http.ResponseWriter, r *http.Request) { 74 _, _ = w.Write([]byte(`test_counter_no_meta_metric_1_total{label1="value1"} 11`)) 75 })) 76 prom = New() 77 prom.URL = srv.URL 78 79 return prom, srv.Close 80 }, 81 }, 82 "fail if the total num of metrics exceeds the limit": { 83 wantFail: true, 84 prepare: func() (prom *Prometheus, cleanup func()) { 85 srv := httptest.NewServer(http.HandlerFunc( 86 func(w http.ResponseWriter, r *http.Request) { 87 _, _ = w.Write([]byte(` 88 test_counter_no_meta_metric_1_total{label1="value1"} 11 89 test_counter_no_meta_metric_1_total{label1="value2"} 11 90 `)) 91 })) 92 prom = New() 93 prom.URL = srv.URL 94 prom.MaxTS = 1 95 96 return prom, srv.Close 97 }, 98 }, 99 "fail if the num time series in the metric exceeds the limit": { 100 wantFail: true, 101 prepare: func() (prom *Prometheus, cleanup func()) { 102 srv := httptest.NewServer(http.HandlerFunc( 103 func(w http.ResponseWriter, r *http.Request) { 104 _, _ = w.Write([]byte(` 105 test_counter_no_meta_metric_1_total{label1="value1"} 11 106 test_counter_no_meta_metric_1_total{label1="value2"} 11 107 `)) 108 })) 109 prom = New() 110 prom.URL = srv.URL 111 prom.MaxTSPerMetric = 1 112 113 return prom, srv.Close 114 }, 115 }, 116 "fail if metrics have no expected prefix": { 117 wantFail: true, 118 prepare: func() (prom *Prometheus, cleanup func()) { 119 srv := httptest.NewServer(http.HandlerFunc( 120 func(w http.ResponseWriter, r *http.Request) { 121 _, _ = w.Write([]byte(`test_counter_no_meta_metric_1_total{label1="value1"} 11`)) 122 })) 123 prom = New() 124 prom.URL = srv.URL 125 prom.ExpectedPrefix = "prefix_" 126 127 return prom, srv.Close 128 }, 129 }, 130 "fail if endpoint returns data not in prometheus format": { 131 wantFail: true, 132 prepare: func() (prom *Prometheus, cleanup func()) { 133 srv := httptest.NewServer(http.HandlerFunc( 134 func(w http.ResponseWriter, r *http.Request) { 135 _, _ = w.Write([]byte("hello and\n goodbye")) 136 })) 137 prom = New() 138 prom.URL = srv.URL 139 140 return prom, srv.Close 141 }, 142 }, 143 "fail if connection refused": { 144 wantFail: true, 145 prepare: func() (prom *Prometheus, cleanup func()) { 146 prom = New() 147 prom.URL = "http://127.0.0.1:38001/metrics" 148 149 return prom, func() {} 150 }, 151 }, 152 "fail if endpoint returns 404": { 153 wantFail: true, 154 prepare: func() (prom *Prometheus, cleanup func()) { 155 srv := httptest.NewServer(http.HandlerFunc( 156 func(w http.ResponseWriter, r *http.Request) { 157 w.WriteHeader(http.StatusNotFound) 158 })) 159 prom = New() 160 prom.URL = srv.URL 161 162 return prom, srv.Close 163 }, 164 }, 165 } 166 167 for name, test := range tests { 168 t.Run(name, func(t *testing.T) { 169 prom, cleanup := test.prepare() 170 defer cleanup() 171 172 require.True(t, prom.Init()) 173 174 if test.wantFail { 175 assert.False(t, prom.Check()) 176 } else { 177 assert.True(t, prom.Check()) 178 } 179 }) 180 } 181 } 182 183 func TestPrometheus_Collect(t *testing.T) { 184 type testCaseStep struct { 185 desc string 186 input string 187 wantCollected map[string]int64 188 wantCharts int 189 } 190 tests := map[string]struct { 191 prepare func() *Prometheus 192 steps []testCaseStep 193 }{ 194 "Gauge": { 195 prepare: New, 196 steps: []testCaseStep{ 197 { 198 desc: "Two first seen series, no meta series ignored", 199 input: ` 200 # HELP test_gauge_metric_1 Test Gauge Metric 1 201 # TYPE test_gauge_metric_1 gauge 202 test_gauge_metric_1{label1="value1"} 11 203 test_gauge_metric_1{label1="value2"} 12 204 test_gauge_no_meta_metric_1{label1="value1"} 11 205 test_gauge_no_meta_metric_1{label1="value2"} 12 206 `, 207 wantCollected: map[string]int64{ 208 "test_gauge_metric_1-label1=value1": 11000, 209 "test_gauge_metric_1-label1=value2": 12000, 210 }, 211 wantCharts: 2, 212 }, 213 { 214 desc: "One series removed", 215 input: ` 216 # HELP test_gauge_metric_1 Test Gauge Metric 1 217 # TYPE test_gauge_metric_1 gauge 218 test_gauge_metric_1{label1="value1"} 11 219 `, 220 wantCollected: map[string]int64{ 221 "test_gauge_metric_1-label1=value1": 11000, 222 }, 223 wantCharts: 1, 224 }, 225 { 226 desc: "One series (re)added", 227 input: ` 228 # HELP test_gauge_metric_1 Test Gauge Metric 1 229 # TYPE test_gauge_metric_1 gauge 230 test_gauge_metric_1{label1="value1"} 11 231 test_gauge_metric_1{label1="value2"} 12 232 `, 233 wantCollected: map[string]int64{ 234 "test_gauge_metric_1-label1=value1": 11000, 235 "test_gauge_metric_1-label1=value2": 12000, 236 }, 237 wantCharts: 2, 238 }, 239 }, 240 }, 241 "Counter": { 242 prepare: New, 243 steps: []testCaseStep{ 244 { 245 desc: "Four first seen series, no meta series collected", 246 input: ` 247 # HELP test_counter_metric_1_total Test Counter Metric 1 248 # TYPE test_counter_metric_1_total counter 249 test_counter_metric_1_total{label1="value1"} 11 250 test_counter_metric_1_total{label1="value2"} 12 251 test_counter_no_meta_metric_1_total{label1="value1"} 11 252 test_counter_no_meta_metric_1_total{label1="value2"} 12 253 `, 254 wantCollected: map[string]int64{ 255 "test_counter_metric_1_total-label1=value1": 11000, 256 "test_counter_metric_1_total-label1=value2": 12000, 257 "test_counter_no_meta_metric_1_total-label1=value1": 11000, 258 "test_counter_no_meta_metric_1_total-label1=value2": 12000, 259 }, 260 wantCharts: 4, 261 }, 262 { 263 desc: "Two series removed", 264 input: ` 265 # HELP test_counter_metric_1_total Test Counter Metric 1 266 # TYPE test_counter_metric_1_total counter 267 test_counter_metric_1_total{label1="value1"} 11 268 test_counter_no_meta_metric_1_total{label1="value1"} 11 269 `, 270 wantCollected: map[string]int64{ 271 "test_counter_metric_1_total-label1=value1": 11000, 272 "test_counter_no_meta_metric_1_total-label1=value1": 11000, 273 }, 274 wantCharts: 2, 275 }, 276 { 277 desc: "Two series (re)added", 278 input: ` 279 # HELP test_counter_metric_1_total Test Counter Metric 1 280 # TYPE test_counter_metric_1_total counter 281 test_counter_metric_1_total{label1="value1"} 11 282 test_counter_metric_1_total{label1="value2"} 12 283 test_counter_no_meta_metric_1_total{label1="value1"} 11 284 test_counter_no_meta_metric_1_total{label1="value2"} 12 285 `, 286 wantCollected: map[string]int64{ 287 "test_counter_metric_1_total-label1=value1": 11000, 288 "test_counter_metric_1_total-label1=value2": 12000, 289 "test_counter_no_meta_metric_1_total-label1=value1": 11000, 290 "test_counter_no_meta_metric_1_total-label1=value2": 12000, 291 }, 292 wantCharts: 4, 293 }, 294 }, 295 }, 296 "Summary": { 297 prepare: New, 298 steps: []testCaseStep{ 299 { 300 desc: "Two first seen series, no meta series collected", 301 input: ` 302 # HELP test_summary_1_duration_microseconds Test Summary Metric 1 303 # TYPE test_summary_1_duration_microseconds summary 304 test_summary_1_duration_microseconds{label1="value1",quantile="0.5"} 4931.921 305 test_summary_1_duration_microseconds{label1="value1",quantile="0.9"} 4932.921 306 test_summary_1_duration_microseconds{label1="value1",quantile="0.99"} 4933.921 307 test_summary_1_duration_microseconds_sum{label1="value1"} 283201.29 308 test_summary_1_duration_microseconds_count{label1="value1"} 31 309 test_summary_no_meta_1_duration_microseconds{label1="value1",quantile="0.5"} 4931.921 310 test_summary_no_meta_1_duration_microseconds{label1="value1",quantile="0.9"} 4932.921 311 test_summary_no_meta_1_duration_microseconds{label1="value1",quantile="0.99"} 4933.921 312 test_summary_no_meta_1_duration_microseconds_sum{label1="value1"} 283201.29 313 test_summary_no_meta_1_duration_microseconds_count{label1="value1"} 31 314 `, 315 wantCollected: map[string]int64{ 316 "test_summary_1_duration_microseconds-label1=value1_count": 31, 317 "test_summary_1_duration_microseconds-label1=value1_quantile=0.5": 4931921000, 318 "test_summary_1_duration_microseconds-label1=value1_quantile=0.9": 4932921000, 319 "test_summary_1_duration_microseconds-label1=value1_quantile=0.99": 4933921000, 320 "test_summary_1_duration_microseconds-label1=value1_sum": 283201290, 321 "test_summary_no_meta_1_duration_microseconds-label1=value1_count": 31, 322 "test_summary_no_meta_1_duration_microseconds-label1=value1_quantile=0.5": 4931921000, 323 "test_summary_no_meta_1_duration_microseconds-label1=value1_quantile=0.9": 4932921000, 324 "test_summary_no_meta_1_duration_microseconds-label1=value1_quantile=0.99": 4933921000, 325 "test_summary_no_meta_1_duration_microseconds-label1=value1_sum": 283201290, 326 }, 327 wantCharts: 6, 328 }, 329 { 330 desc: "One series removed", 331 input: ` 332 # HELP test_summary_1_duration_microseconds Test Summary Metric 1 333 # TYPE test_summary_1_duration_microseconds summary 334 test_summary_1_duration_microseconds{label1="value1",quantile="0.5"} 4931.921 335 test_summary_1_duration_microseconds{label1="value1",quantile="0.9"} 4932.921 336 test_summary_1_duration_microseconds{label1="value1",quantile="0.99"} 4933.921 337 test_summary_1_duration_microseconds_sum{label1="value1"} 283201.29 338 test_summary_1_duration_microseconds_count{label1="value1"} 31 339 `, 340 wantCollected: map[string]int64{ 341 "test_summary_1_duration_microseconds-label1=value1_count": 31, 342 "test_summary_1_duration_microseconds-label1=value1_quantile=0.5": 4931921000, 343 "test_summary_1_duration_microseconds-label1=value1_quantile=0.9": 4932921000, 344 "test_summary_1_duration_microseconds-label1=value1_quantile=0.99": 4933921000, 345 "test_summary_1_duration_microseconds-label1=value1_sum": 283201290, 346 }, 347 wantCharts: 3, 348 }, 349 { 350 desc: "One series (re)added", 351 input: ` 352 # HELP test_summary_1_duration_microseconds Test Summary Metric 1 353 # TYPE test_summary_1_duration_microseconds summary 354 test_summary_1_duration_microseconds{label1="value1",quantile="0.5"} 4931.921 355 test_summary_1_duration_microseconds{label1="value1",quantile="0.9"} 4932.921 356 test_summary_1_duration_microseconds{label1="value1",quantile="0.99"} 4933.921 357 test_summary_1_duration_microseconds_sum{label1="value1"} 283201.29 358 test_summary_1_duration_microseconds_count{label1="value1"} 31 359 test_summary_no_meta_1_duration_microseconds{label1="value1",quantile="0.5"} 4931.921 360 test_summary_no_meta_1_duration_microseconds{label1="value1",quantile="0.9"} 4932.921 361 test_summary_no_meta_1_duration_microseconds{label1="value1",quantile="0.99"} 4933.921 362 test_summary_no_meta_1_duration_microseconds_sum{label1="value1"} 283201.29 363 test_summary_no_meta_1_duration_microseconds_count{label1="value1"} 31 364 `, 365 wantCollected: map[string]int64{ 366 "test_summary_1_duration_microseconds-label1=value1_count": 31, 367 "test_summary_1_duration_microseconds-label1=value1_quantile=0.5": 4931921000, 368 "test_summary_1_duration_microseconds-label1=value1_quantile=0.9": 4932921000, 369 "test_summary_1_duration_microseconds-label1=value1_quantile=0.99": 4933921000, 370 "test_summary_1_duration_microseconds-label1=value1_sum": 283201290, 371 "test_summary_no_meta_1_duration_microseconds-label1=value1_count": 31, 372 "test_summary_no_meta_1_duration_microseconds-label1=value1_quantile=0.5": 4931921000, 373 "test_summary_no_meta_1_duration_microseconds-label1=value1_quantile=0.9": 4932921000, 374 "test_summary_no_meta_1_duration_microseconds-label1=value1_quantile=0.99": 4933921000, 375 "test_summary_no_meta_1_duration_microseconds-label1=value1_sum": 283201290, 376 }, 377 wantCharts: 6, 378 }, 379 }, 380 }, 381 "Summary with NaN": { 382 prepare: New, 383 steps: []testCaseStep{ 384 { 385 desc: "Two first seen series, no meta series collected", 386 input: ` 387 # HELP test_summary_1_duration_microseconds Test Summary Metric 1 388 # TYPE test_summary_1_duration_microseconds summary 389 test_summary_1_duration_microseconds{label1="value1",quantile="0.5"} NaN 390 test_summary_1_duration_microseconds{label1="value1",quantile="0.9"} NaN 391 test_summary_1_duration_microseconds{label1="value1",quantile="0.99"} NaN 392 test_summary_1_duration_microseconds_sum{label1="value1"} 283201.29 393 test_summary_1_duration_microseconds_count{label1="value1"} 31 394 test_summary_no_meta_1_duration_microseconds{label1="value1",quantile="0.5"} NaN 395 test_summary_no_meta_1_duration_microseconds{label1="value1",quantile="0.9"} NaN 396 test_summary_no_meta_1_duration_microseconds{label1="value1",quantile="0.99"} NaN 397 test_summary_no_meta_1_duration_microseconds_sum{label1="value1"} 283201.29 398 test_summary_no_meta_1_duration_microseconds_count{label1="value1"} 31 399 `, 400 wantCollected: map[string]int64{ 401 "test_summary_1_duration_microseconds-label1=value1_count": 31, 402 "test_summary_1_duration_microseconds-label1=value1_sum": 283201290, 403 "test_summary_no_meta_1_duration_microseconds-label1=value1_count": 31, 404 "test_summary_no_meta_1_duration_microseconds-label1=value1_sum": 283201290, 405 }, 406 wantCharts: 6, 407 }, 408 }, 409 }, 410 "Histogram": { 411 prepare: New, 412 steps: []testCaseStep{ 413 { 414 desc: "Two first seen series, no meta series collected", 415 input: ` 416 # HELP test_histogram_1_duration_seconds Test Histogram Metric 1 417 # TYPE test_histogram_1_duration_seconds histogram 418 test_histogram_1_duration_seconds_bucket{label1="value1",le="0.1"} 4 419 test_histogram_1_duration_seconds_bucket{label1="value1",le="0.5"} 5 420 test_histogram_1_duration_seconds_bucket{label1="value1",le="+Inf"} 6 421 test_histogram_1_duration_seconds_sum{label1="value1"} 0.00147889 422 test_histogram_1_duration_seconds_count{label1="value1"} 6 423 test_histogram_no_meta_1_duration_seconds_bucket{label1="value1",le="0.1"} 4 424 test_histogram_no_meta_1_duration_seconds_bucket{label1="value1",le="0.5"} 5 425 test_histogram_no_meta_1_duration_seconds_bucket{label1="value1",le="+Inf"} 6 426 test_histogram_no_meta_1_duration_seconds_sum{label1="value1"} 0.00147889 427 test_histogram_no_meta_1_duration_seconds_count{label1="value1"} 6 428 `, 429 wantCollected: map[string]int64{ 430 "test_histogram_1_duration_seconds-label1=value1_bucket=+Inf": 6, 431 "test_histogram_1_duration_seconds-label1=value1_bucket=0.1": 4, 432 "test_histogram_1_duration_seconds-label1=value1_bucket=0.5": 5, 433 "test_histogram_1_duration_seconds-label1=value1_count": 6, 434 "test_histogram_1_duration_seconds-label1=value1_sum": 1, 435 "test_histogram_no_meta_1_duration_seconds-label1=value1_bucket=+Inf": 6, 436 "test_histogram_no_meta_1_duration_seconds-label1=value1_bucket=0.1": 4, 437 "test_histogram_no_meta_1_duration_seconds-label1=value1_bucket=0.5": 5, 438 "test_histogram_no_meta_1_duration_seconds-label1=value1_count": 6, 439 "test_histogram_no_meta_1_duration_seconds-label1=value1_sum": 1, 440 }, 441 wantCharts: 6, 442 }, 443 { 444 desc: "One series removed", 445 input: ` 446 # HELP test_histogram_1_duration_seconds Test Histogram Metric 1 447 # TYPE test_histogram_1_duration_seconds histogram 448 test_histogram_1_duration_seconds_bucket{label1="value1",le="0.1"} 4 449 test_histogram_1_duration_seconds_bucket{label1="value1",le="0.5"} 5 450 test_histogram_1_duration_seconds_bucket{label1="value1",le="+Inf"} 6 451 `, 452 wantCollected: map[string]int64{ 453 "test_histogram_1_duration_seconds-label1=value1_bucket=+Inf": 6, 454 "test_histogram_1_duration_seconds-label1=value1_bucket=0.1": 4, 455 "test_histogram_1_duration_seconds-label1=value1_bucket=0.5": 5, 456 "test_histogram_1_duration_seconds-label1=value1_count": 0, 457 "test_histogram_1_duration_seconds-label1=value1_sum": 0, 458 }, 459 wantCharts: 3, 460 }, 461 { 462 desc: "One series (re)added", 463 input: ` 464 # HELP test_histogram_1_duration_seconds Test Histogram Metric 1 465 # TYPE test_histogram_1_duration_seconds histogram 466 test_histogram_1_duration_seconds_bucket{label1="value1",le="0.1"} 4 467 test_histogram_1_duration_seconds_bucket{label1="value1",le="0.5"} 5 468 test_histogram_1_duration_seconds_bucket{label1="value1",le="+Inf"} 6 469 test_histogram_1_duration_seconds_sum{label1="value1"} 0.00147889 470 test_histogram_1_duration_seconds_count{label1="value1"} 6 471 test_histogram_no_meta_1_duration_seconds_bucket{label1="value1",le="0.1"} 4 472 test_histogram_no_meta_1_duration_seconds_bucket{label1="value1",le="0.5"} 5 473 test_histogram_no_meta_1_duration_seconds_bucket{label1="value1",le="+Inf"} 6 474 test_histogram_no_meta_1_duration_seconds_sum{label1="value1"} 0.00147889 475 test_histogram_no_meta_1_duration_seconds_count{label1="value1"} 6 476 `, 477 wantCollected: map[string]int64{ 478 "test_histogram_1_duration_seconds-label1=value1_bucket=+Inf": 6, 479 "test_histogram_1_duration_seconds-label1=value1_bucket=0.1": 4, 480 "test_histogram_1_duration_seconds-label1=value1_bucket=0.5": 5, 481 "test_histogram_1_duration_seconds-label1=value1_count": 6, 482 "test_histogram_1_duration_seconds-label1=value1_sum": 1, 483 "test_histogram_no_meta_1_duration_seconds-label1=value1_bucket=+Inf": 6, 484 "test_histogram_no_meta_1_duration_seconds-label1=value1_bucket=0.1": 4, 485 "test_histogram_no_meta_1_duration_seconds-label1=value1_bucket=0.5": 5, 486 "test_histogram_no_meta_1_duration_seconds-label1=value1_count": 6, 487 "test_histogram_no_meta_1_duration_seconds-label1=value1_sum": 1, 488 }, 489 wantCharts: 6, 490 }, 491 }, 492 }, 493 "match Untyped as Gauge": { 494 prepare: func() *Prometheus { 495 prom := New() 496 prom.FallbackType.Gauge = []string{"test_gauge_no_meta*"} 497 return prom 498 }, 499 steps: []testCaseStep{ 500 { 501 desc: "Two first seen series, meta series processed as Gauge", 502 input: ` 503 # HELP test_gauge_metric_1 Test Untyped Metric 1 504 # TYPE test_gauge_metric_1 gauge 505 test_gauge_metric_1{label1="value1"} 11 506 test_gauge_metric_1{label1="value2"} 12 507 test_gauge_no_meta_metric_1{label1="value1"} 11 508 test_gauge_no_meta_metric_1{label1="value2"} 12 509 `, 510 wantCollected: map[string]int64{ 511 "test_gauge_metric_1-label1=value1": 11000, 512 "test_gauge_metric_1-label1=value2": 12000, 513 "test_gauge_no_meta_metric_1-label1=value1": 11000, 514 "test_gauge_no_meta_metric_1-label1=value2": 12000, 515 }, 516 wantCharts: 4, 517 }, 518 }, 519 }, 520 "match Untyped as Counter": { 521 prepare: func() *Prometheus { 522 prom := New() 523 prom.FallbackType.Counter = []string{"test_gauge_no_meta*"} 524 return prom 525 }, 526 steps: []testCaseStep{ 527 { 528 desc: "Two first seen series, meta series processed as Counter", 529 input: ` 530 # HELP test_gauge_metric_1 Test Untyped Metric 1 531 # TYPE test_gauge_metric_1 gauge 532 test_gauge_metric_1{label1="value1"} 11 533 test_gauge_metric_1{label1="value2"} 12 534 test_gauge_no_meta_metric_1{label1="value1"} 11 535 test_gauge_no_meta_metric_1{label1="value2"} 12 536 `, 537 wantCollected: map[string]int64{ 538 "test_gauge_metric_1-label1=value1": 11000, 539 "test_gauge_metric_1-label1=value2": 12000, 540 "test_gauge_no_meta_metric_1-label1=value1": 11000, 541 "test_gauge_no_meta_metric_1-label1=value2": 12000, 542 }, 543 wantCharts: 4, 544 }, 545 }, 546 }, 547 } 548 549 for name, test := range tests { 550 t.Run(name, func(t *testing.T) { 551 prom := test.prepare() 552 553 var metrics []byte 554 srv := httptest.NewServer(http.HandlerFunc( 555 func(w http.ResponseWriter, r *http.Request) { 556 _, _ = w.Write(metrics) 557 })) 558 defer srv.Close() 559 560 prom.URL = srv.URL 561 require.True(t, prom.Init()) 562 563 for num, step := range test.steps { 564 t.Run(fmt.Sprintf("step num %d ('%s')", num+1, step.desc), func(t *testing.T) { 565 566 metrics = []byte(step.input) 567 568 var mx map[string]int64 569 570 for i := 0; i < maxNotSeenTimes+1; i++ { 571 mx = prom.Collect() 572 } 573 574 assert.Equal(t, step.wantCollected, mx) 575 removeObsoleteCharts(prom.Charts()) 576 assert.Len(t, *prom.Charts(), step.wantCharts) 577 }) 578 } 579 }) 580 } 581 } 582 583 func removeObsoleteCharts(charts *module.Charts) { 584 var i int 585 for _, chart := range *charts { 586 if !chart.Obsolete { 587 (*charts)[i] = chart 588 i++ 589 } 590 } 591 *charts = (*charts)[:i] 592 }