From b0c538787d9f89a7e3a9802223a51bcb84441485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Szulik?= Date: Sat, 4 Sep 2021 14:35:03 +0200 Subject: [PATCH] Refactor scrape tests to use testify. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Paweł Szulik --- scrape/manager_test.go | 60 ++++++++------------ scrape/scrape_test.go | 122 ++++++++++++++++------------------------- scrape/target_test.go | 102 +++++++++------------------------- 3 files changed, 98 insertions(+), 186 deletions(-) diff --git a/scrape/manager_test.go b/scrape/manager_test.go index 524424269..a73b73078 100644 --- a/scrape/manager_test.go +++ b/scrape/manager_test.go @@ -458,9 +458,9 @@ func loadConfiguration(t testing.TB, c string) *config.Config { t.Helper() cfg := &config.Config{} - if err := yaml.UnmarshalStrict([]byte(c), cfg); err != nil { - t.Fatalf("Unable to load YAML config: %s", err) - } + err := yaml.UnmarshalStrict([]byte(c), cfg) + require.NoError(t, err, "Unable to load YAML config.") + return cfg } @@ -533,42 +533,38 @@ scrape_configs: } // Apply the initial configuration. - if err := scrapeManager.ApplyConfig(cfg1); err != nil { - t.Fatalf("unable to apply configuration: %s", err) - } + err = scrapeManager.ApplyConfig(cfg1) + require.NoError(t, err, "Unable to apply configuration.") select { case <-ch: - t.Fatal("reload happened") + require.FailNow(t, "Reload happened.") default: } // Apply a configuration for which the reload fails. - if err := scrapeManager.ApplyConfig(cfg2); err == nil { - t.Fatalf("expecting error but got none") - } + err = scrapeManager.ApplyConfig(cfg2) + require.Error(t, err, "Expecting error but got none.") select { case <-ch: - t.Fatal("reload happened") + require.FailNow(t, "Reload happened.") default: } // Apply a configuration for which the reload succeeds. - if err := scrapeManager.ApplyConfig(cfg3); err != nil { - t.Fatalf("unable to apply configuration: %s", err) - } + err = scrapeManager.ApplyConfig(cfg3) + require.NoError(t, err, "Unable to apply configuration.") select { case <-ch: default: - t.Fatal("reload didn't happen") + require.FailNow(t, "Reload didn't happen.") } // Re-applying the same configuration shouldn't trigger a reload. - if err := scrapeManager.ApplyConfig(cfg3); err != nil { - t.Fatalf("unable to apply configuration: %s", err) - } + err = scrapeManager.ApplyConfig(cfg3) + require.NoError(t, err, "Unable to apply configuration.") select { case <-ch: - t.Fatal("reload happened") + require.FailNow(t, "Reload happened.") default: } } @@ -595,7 +591,7 @@ func TestManagerTargetsUpdates(t *testing.T) { select { case ts <- tgSent: case <-time.After(10 * time.Millisecond): - t.Error("Scrape manager's channel remained blocked after the set threshold.") + require.Fail(t, "Scrape manager's channel remained blocked after the set threshold.") } } @@ -609,7 +605,7 @@ func TestManagerTargetsUpdates(t *testing.T) { select { case <-m.triggerReload: default: - t.Error("No scrape loops reload was triggered after targets update.") + require.Fail(t, "No scrape loops reload was triggered after targets update.") } } @@ -622,9 +618,8 @@ global: ` cfg := &config.Config{} - if err := yaml.UnmarshalStrict([]byte(cfgText), cfg); err != nil { - t.Fatalf("Unable to load YAML config cfgYaml: %s", err) - } + err := yaml.UnmarshalStrict([]byte(cfgText), cfg) + require.NoError(t, err, "Unable to load YAML config cfgYaml.") return cfg } @@ -636,25 +631,18 @@ global: // Load the first config. cfg1 := getConfig("ha1") - if err := scrapeManager.setOffsetSeed(cfg1.GlobalConfig.ExternalLabels); err != nil { - t.Error(err) - } + err = scrapeManager.setOffsetSeed(cfg1.GlobalConfig.ExternalLabels) + require.NoError(t, err) offsetSeed1 := scrapeManager.offsetSeed - if offsetSeed1 == 0 { - t.Error("Offset seed has to be a hash of uint64") - } + require.NotZero(t, offsetSeed1, "Offset seed has to be a hash of uint64.") // Load the first config. cfg2 := getConfig("ha2") - if err := scrapeManager.setOffsetSeed(cfg2.GlobalConfig.ExternalLabels); err != nil { - t.Error(err) - } + require.NoError(t, scrapeManager.setOffsetSeed(cfg2.GlobalConfig.ExternalLabels)) offsetSeed2 := scrapeManager.offsetSeed - if offsetSeed1 == offsetSeed2 { - t.Error("Offset seed should not be the same on different set of external labels") - } + require.NotEqual(t, offsetSeed1, offsetSeed2, "Offset seed should not be the same on different set of external labels.") } func TestManagerScrapePools(t *testing.T) { diff --git a/scrape/scrape_test.go b/scrape/scrape_test.go index 95e4e182a..f827ffc8d 100644 --- a/scrape/scrape_test.go +++ b/scrape/scrape_test.go @@ -72,15 +72,11 @@ func TestNewScrapePool(t *testing.T) { sp, _ = newScrapePool(cfg, app, 0, nil, nil, &Options{}, newTestScrapeMetrics(t)) ) - if a, ok := sp.appendable.(*nopAppendable); !ok || a != app { - t.Fatalf("Wrong sample appender") - } - if sp.config != cfg { - t.Fatalf("Wrong scrape config") - } - if sp.newLoop == nil { - t.Fatalf("newLoop function not initialized") - } + a, ok := sp.appendable.(*nopAppendable) + require.True(t, ok, "Failure to append.") + require.Equal(t, app, a, "Wrong sample appender.") + require.Equal(t, cfg, sp.config, "Wrong scrape config.") + require.NotNil(t, sp.newLoop, "newLoop function not initialized.") } func TestDroppedTargetsList(t *testing.T) { @@ -233,12 +229,10 @@ func TestScrapePoolStop(t *testing.T) { select { case <-time.After(5 * time.Second): - t.Fatalf("scrapeLoop.stop() did not return as expected") + require.Fail(t, "scrapeLoop.stop() did not return as expected") case <-done: // This should have taken at least as long as the last target slept. - if time.Since(stopTime) < time.Duration(numTargets*20)*time.Millisecond { - t.Fatalf("scrapeLoop.stop() exited before all targets stopped") - } + require.GreaterOrEqual(t, time.Since(stopTime), time.Duration(numTargets*20)*time.Millisecond, "scrapeLoop.stop() exited before all targets stopped") } mtx.Lock() @@ -324,12 +318,10 @@ func TestScrapePoolReload(t *testing.T) { select { case <-time.After(5 * time.Second): - t.Fatalf("scrapeLoop.reload() did not return as expected") + require.FailNow(t, "scrapeLoop.reload() did not return as expected") case <-done: // This should have taken at least as long as the last target slept. - if time.Since(reloadTime) < time.Duration(numTargets*20)*time.Millisecond { - t.Fatalf("scrapeLoop.stop() exited before all targets stopped") - } + require.GreaterOrEqual(t, time.Since(reloadTime), time.Duration(numTargets*20)*time.Millisecond, "scrapeLoop.stop() exited before all targets stopped") } mtx.Lock() @@ -703,13 +695,13 @@ func TestScrapeLoopStopBeforeRun(t *testing.T) { select { case <-stopDone: - t.Fatalf("Stopping terminated before run exited successfully") + require.FailNow(t, "Stopping terminated before run exited successfully.") case <-time.After(500 * time.Millisecond): } // Running the scrape loop must exit before calling the scraper even once. scraper.scrapeFunc = func(context.Context, io.Writer) error { - t.Fatalf("scraper was called for terminated scrape loop") + require.FailNow(t, "Scraper was called for terminated scrape loop.") return nil } @@ -722,13 +714,13 @@ func TestScrapeLoopStopBeforeRun(t *testing.T) { select { case <-runDone: case <-time.After(1 * time.Second): - t.Fatalf("Running terminated scrape loop did not exit") + require.FailNow(t, "Running terminated scrape loop did not exit.") } select { case <-stopDone: case <-time.After(1 * time.Second): - t.Fatalf("Stopping did not terminate after running exited") + require.FailNow(t, "Stopping did not terminate after running exited.") } } @@ -765,14 +757,13 @@ func TestScrapeLoopStop(t *testing.T) { select { case <-signal: case <-time.After(5 * time.Second): - t.Fatalf("Scrape wasn't stopped.") + require.FailNow(t, "Scrape wasn't stopped.") } // We expected 1 actual sample for each scrape plus 5 for report samples. // At least 2 scrapes were made, plus the final stale markers. - if len(appender.resultFloats) < 6*3 || len(appender.resultFloats)%6 != 0 { - t.Fatalf("Expected at least 3 scrapes with 6 samples each, got %d samples", len(appender.resultFloats)) - } + require.GreaterOrEqual(t, len(appender.resultFloats), 6*3, "Expected at least 3 scrapes with 6 samples each.") + require.Zero(t, len(appender.resultFloats)%6, "There is a scrape with missing samples.") // All samples in a scrape must have the same timestamp. var ts int64 for i, s := range appender.resultFloats { @@ -785,9 +776,7 @@ func TestScrapeLoopStop(t *testing.T) { } // All samples from the last scrape must be stale markers. for _, s := range appender.resultFloats[len(appender.resultFloats)-5:] { - if !value.IsStaleNaN(s.f) { - t.Fatalf("Appended last sample not as expected. Wanted: stale NaN Got: %x", math.Float64bits(s.f)) - } + require.True(t, value.IsStaleNaN(s.f), "Appended last sample not as expected. Wanted: stale NaN Got: %x", math.Float64bits(s.f)) } } @@ -843,9 +832,9 @@ func TestScrapeLoopRun(t *testing.T) { select { case <-signal: case <-time.After(5 * time.Second): - t.Fatalf("Cancellation during initial offset failed") + require.FailNow(t, "Cancellation during initial offset failed.") case err := <-errc: - t.Fatalf("Unexpected error: %s", err) + require.FailNow(t, "Unexpected error: %s", err) } // The provided timeout must cause cancellation of the context passed down to the @@ -873,11 +862,9 @@ func TestScrapeLoopRun(t *testing.T) { select { case err := <-errc: - if !errors.Is(err, context.DeadlineExceeded) { - t.Fatalf("Expected timeout error but got: %s", err) - } + require.ErrorIs(t, err, context.DeadlineExceeded) case <-time.After(3 * time.Second): - t.Fatalf("Expected timeout error but got none") + require.FailNow(t, "Expected timeout error but got none.") } // We already caught the timeout error and are certainly in the loop. @@ -890,9 +877,9 @@ func TestScrapeLoopRun(t *testing.T) { case <-signal: // Loop terminated as expected. case err := <-errc: - t.Fatalf("Unexpected error: %s", err) + require.FailNow(t, "Unexpected error: %s", err) case <-time.After(3 * time.Second): - t.Fatalf("Loop did not terminate on context cancellation") + require.FailNow(t, "Loop did not terminate on context cancellation") } } @@ -912,7 +899,7 @@ func TestScrapeLoopForcedErr(t *testing.T) { sl.setForcedError(forcedErr) scraper.scrapeFunc = func(context.Context, io.Writer) error { - t.Fatalf("should not be scraped") + require.FailNow(t, "Should not be scraped.") return nil } @@ -923,18 +910,16 @@ func TestScrapeLoopForcedErr(t *testing.T) { select { case err := <-errc: - if !errors.Is(err, forcedErr) { - t.Fatalf("Expected forced error but got: %s", err) - } + require.ErrorIs(t, err, forcedErr) case <-time.After(3 * time.Second): - t.Fatalf("Expected forced error but got none") + require.FailNow(t, "Expected forced error but got none.") } cancel() select { case <-signal: case <-time.After(5 * time.Second): - t.Fatalf("Scrape not stopped") + require.FailNow(t, "Scrape not stopped.") } } @@ -1141,7 +1126,7 @@ func TestScrapeLoopRunCreatesStaleMarkersOnFailedScrape(t *testing.T) { select { case <-signal: case <-time.After(5 * time.Second): - t.Fatalf("Scrape wasn't stopped.") + require.FailNow(t, "Scrape wasn't stopped.") } // 1 successfully scraped sample, 1 stale marker after first fail, 5 report samples for @@ -1188,7 +1173,7 @@ func TestScrapeLoopRunCreatesStaleMarkersOnParseFailure(t *testing.T) { select { case <-signal: case <-time.After(5 * time.Second): - t.Fatalf("Scrape wasn't stopped.") + require.FailNow(t, "Scrape wasn't stopped.") } // 1 successfully scraped sample, 1 stale marker after first fail, 5 report samples for @@ -1220,19 +1205,15 @@ func TestScrapeLoopCache(t *testing.T) { scraper.scrapeFunc = func(ctx context.Context, w io.Writer) error { switch numScrapes { case 1, 2: - if _, ok := sl.cache.series["metric_a"]; !ok { - t.Errorf("metric_a missing from cache after scrape %d", numScrapes) - } - if _, ok := sl.cache.series["metric_b"]; !ok { - t.Errorf("metric_b missing from cache after scrape %d", numScrapes) - } + _, ok := sl.cache.series["metric_a"] + require.True(t, ok, "metric_a missing from cache after scrape %d", numScrapes) + _, ok = sl.cache.series["metric_b"] + require.True(t, ok, "metric_b missing from cache after scrape %d", numScrapes) case 3: - if _, ok := sl.cache.series["metric_a"]; !ok { - t.Errorf("metric_a missing from cache after scrape %d", numScrapes) - } - if _, ok := sl.cache.series["metric_b"]; ok { - t.Errorf("metric_b present in cache after scrape %d", numScrapes) - } + _, ok := sl.cache.series["metric_a"] + require.True(t, ok, "metric_a missing from cache after scrape %d", numScrapes) + _, ok = sl.cache.series["metric_b"] + require.False(t, ok, "metric_b present in cache after scrape %d", numScrapes) } numScrapes++ @@ -1257,7 +1238,7 @@ func TestScrapeLoopCache(t *testing.T) { select { case <-signal: case <-time.After(5 * time.Second): - t.Fatalf("Scrape wasn't stopped.") + require.FailNow(t, "Scrape wasn't stopped.") } // 1 successfully scraped sample, 1 stale marker after first fail, 5 report samples for @@ -1305,12 +1286,10 @@ func TestScrapeLoopCacheMemoryExhaustionProtection(t *testing.T) { select { case <-signal: case <-time.After(5 * time.Second): - t.Fatalf("Scrape wasn't stopped.") + require.FailNow(t, "Scrape wasn't stopped.") } - if len(sl.cache.series) > 2000 { - t.Fatalf("More than 2000 series cached. Got: %d", len(sl.cache.series)) - } + require.LessOrEqual(t, len(sl.cache.series), 2000, "More than 2000 series cached.") } func TestScrapeLoopAppend(t *testing.T) { @@ -1541,9 +1520,7 @@ func TestScrapeLoopAppendSampleLimit(t *testing.T) { now := time.Now() slApp := sl.appender(context.Background()) total, added, seriesAdded, err := sl.append(app, []byte("metric_a 1\nmetric_b 1\nmetric_c 1\n"), "", now) - if !errors.Is(err, errSampleLimit) { - t.Fatalf("Did not see expected sample limit error: %s", err) - } + require.ErrorIs(t, err, errSampleLimit) require.NoError(t, slApp.Rollback()) require.Equal(t, 3, total) require.Equal(t, 3, added) @@ -1572,9 +1549,7 @@ func TestScrapeLoopAppendSampleLimit(t *testing.T) { now = time.Now() slApp = sl.appender(context.Background()) total, added, seriesAdded, err = sl.append(slApp, []byte("metric_a 1\nmetric_b 1\nmetric_c{deleteme=\"yes\"} 1\nmetric_d 1\nmetric_e 1\nmetric_f 1\nmetric_g 1\nmetric_h{deleteme=\"yes\"} 1\nmetric_i{deleteme=\"yes\"} 1\n"), "", now) - if !errors.Is(err, errSampleLimit) { - t.Fatalf("Did not see expected sample limit error: %s", err) - } + require.ErrorIs(t, err, errSampleLimit) require.NoError(t, slApp.Rollback()) require.Equal(t, 9, total) require.Equal(t, 6, added) @@ -2357,15 +2332,12 @@ func TestTargetScraperScrapeOK(t *testing.T) { http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if protobufParsing { accept := r.Header.Get("Accept") - if !strings.HasPrefix(accept, "application/vnd.google.protobuf;") { - t.Errorf("Expected Accept header to prefer application/vnd.google.protobuf, got %q", accept) - } + require.True(t, strings.HasPrefix(accept, "application/vnd.google.protobuf;"), + "Expected Accept header to prefer application/vnd.google.protobuf.") } timeout := r.Header.Get("X-Prometheus-Scrape-Timeout-Seconds") - if timeout != expectedTimeout { - t.Errorf("Expected scrape timeout header %q, got %q", expectedTimeout, timeout) - } + require.Equal(t, expectedTimeout, timeout, "Expected scrape timeout header.") w.Header().Set("Content-Type", `text/plain; version=0.0.4`) w.Write([]byte("metric_a 1\nmetric_b 2\n")) @@ -2453,7 +2425,7 @@ func TestTargetScrapeScrapeCancel(t *testing.T) { select { case <-time.After(5 * time.Second): - t.Fatalf("Scrape function did not return unexpectedly") + require.FailNow(t, "Scrape function did not return unexpectedly.") case err := <-errc: require.NoError(t, err) } @@ -3053,7 +3025,7 @@ func TestScrapeReportSingleAppender(t *testing.T) { select { case <-signal: case <-time.After(5 * time.Second): - t.Fatalf("Scrape wasn't stopped.") + require.FailNow(t, "Scrape wasn't stopped.") } } diff --git a/scrape/target_test.go b/scrape/target_test.go index dac502a80..6e87ce71d 100644 --- a/scrape/target_test.go +++ b/scrape/target_test.go @@ -77,9 +77,7 @@ func TestTargetOffset(t *testing.T) { buckets := make([]int, interval/bucketSize) for _, offset := range offsets { - if offset < 0 || offset >= interval { - t.Fatalf("Offset %v out of bounds", offset) - } + require.InDelta(t, time.Duration(0), offset, float64(interval), "Offset %v out of bounds.", offset) bucket := offset / bucketSize buckets[bucket]++ @@ -98,9 +96,7 @@ func TestTargetOffset(t *testing.T) { diff = -diff } - if float64(diff)/float64(avg) > tolerance { - t.Fatalf("Bucket out of tolerance bounds") - } + require.LessOrEqual(t, float64(diff)/float64(avg), tolerance, "Bucket out of tolerance bounds.") } } @@ -150,9 +146,7 @@ func TestNewHTTPBearerToken(t *testing.T) { func(w http.ResponseWriter, r *http.Request) { expected := "Bearer 1234" received := r.Header.Get("Authorization") - if expected != received { - t.Fatalf("Authorization header was not set correctly: expected '%v', got '%v'", expected, received) - } + require.Equal(t, expected, received, "Authorization header was not set correctly.") }, ), ) @@ -162,13 +156,9 @@ func TestNewHTTPBearerToken(t *testing.T) { BearerToken: "1234", } c, err := config_util.NewClientFromConfig(cfg, "test") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) _, err = c.Get(server.URL) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) } func TestNewHTTPBearerTokenFile(t *testing.T) { @@ -177,9 +167,7 @@ func TestNewHTTPBearerTokenFile(t *testing.T) { func(w http.ResponseWriter, r *http.Request) { expected := "Bearer 12345" received := r.Header.Get("Authorization") - if expected != received { - t.Fatalf("Authorization header was not set correctly: expected '%v', got '%v'", expected, received) - } + require.Equal(t, expected, received, "Authorization header was not set correctly.") }, ), ) @@ -189,13 +177,9 @@ func TestNewHTTPBearerTokenFile(t *testing.T) { BearerTokenFile: "testdata/bearertoken.txt", } c, err := config_util.NewClientFromConfig(cfg, "test") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) _, err = c.Get(server.URL) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) } func TestNewHTTPBasicAuth(t *testing.T) { @@ -203,9 +187,9 @@ func TestNewHTTPBasicAuth(t *testing.T) { http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { username, password, ok := r.BasicAuth() - if !(ok && username == "user" && password == "password123") { - t.Fatalf("Basic authorization header was not set correctly: expected '%v:%v', got '%v:%v'", "user", "password123", username, password) - } + require.True(t, ok, "Basic authorization header was not set correctly.") + require.Equal(t, "user", username) + require.Equal(t, "password123", password) }, ), ) @@ -218,13 +202,9 @@ func TestNewHTTPBasicAuth(t *testing.T) { }, } c, err := config_util.NewClientFromConfig(cfg, "test") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) _, err = c.Get(server.URL) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) } func TestNewHTTPCACert(t *testing.T) { @@ -246,13 +226,9 @@ func TestNewHTTPCACert(t *testing.T) { }, } c, err := config_util.NewClientFromConfig(cfg, "test") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) _, err = c.Get(server.URL) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) } func TestNewHTTPClientCert(t *testing.T) { @@ -279,13 +255,9 @@ func TestNewHTTPClientCert(t *testing.T) { }, } c, err := config_util.NewClientFromConfig(cfg, "test") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) _, err = c.Get(server.URL) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) } func TestNewHTTPWithServerName(t *testing.T) { @@ -308,13 +280,9 @@ func TestNewHTTPWithServerName(t *testing.T) { }, } c, err := config_util.NewClientFromConfig(cfg, "test") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) _, err = c.Get(server.URL) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) } func TestNewHTTPWithBadServerName(t *testing.T) { @@ -337,31 +305,23 @@ func TestNewHTTPWithBadServerName(t *testing.T) { }, } c, err := config_util.NewClientFromConfig(cfg, "test") - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) _, err = c.Get(server.URL) - if err == nil { - t.Fatal("Expected error, got nil.") - } + require.Error(t, err) } func newTLSConfig(certName string, t *testing.T) *tls.Config { tlsConfig := &tls.Config{} caCertPool := x509.NewCertPool() caCert, err := os.ReadFile(caCertPath) - if err != nil { - t.Fatalf("Couldn't set up TLS server: %v", err) - } + require.NoError(t, err, "Couldn't read CA cert.") caCertPool.AppendCertsFromPEM(caCert) tlsConfig.RootCAs = caCertPool tlsConfig.ServerName = "127.0.0.1" certPath := fmt.Sprintf("testdata/%s.cer", certName) keyPath := fmt.Sprintf("testdata/%s.key", certName) cert, err := tls.LoadX509KeyPair(certPath, keyPath) - if err != nil { - t.Errorf("Unable to use specified server cert (%s) & key (%v): %s", certPath, keyPath, err) - } + require.NoError(t, err, "Unable to use specified server cert (%s) & key (%v).", certPath, keyPath) tlsConfig.Certificates = []tls.Certificate{cert} return tlsConfig } @@ -375,9 +335,7 @@ func TestNewClientWithBadTLSConfig(t *testing.T) { }, } _, err := config_util.NewClientFromConfig(cfg, "test") - if err == nil { - t.Fatalf("Expected error, got nil.") - } + require.Error(t, err) } func TestTargetsFromGroup(t *testing.T) { @@ -389,15 +347,9 @@ func TestTargetsFromGroup(t *testing.T) { } lb := labels.NewBuilder(labels.EmptyLabels()) targets, failures := TargetsFromGroup(&targetgroup.Group{Targets: []model.LabelSet{{}, {model.AddressLabel: "localhost:9090"}}}, &cfg, false, nil, lb) - if len(targets) != 1 { - t.Fatalf("Expected 1 target, got %v", len(targets)) - } - if len(failures) != 1 { - t.Fatalf("Expected 1 failure, got %v", len(failures)) - } - if failures[0].Error() != expectedError { - t.Fatalf("Expected error %s, got %s", expectedError, failures[0]) - } + require.Len(t, targets, 1) + require.Len(t, failures, 1) + require.EqualError(t, failures[0], expectedError) } func BenchmarkTargetsFromGroup(b *testing.B) {