Skip to content

Commit

Permalink
Add integration test assertion to ensure cortex_distributor_replicati…
Browse files Browse the repository at this point in the history
…on_factor is not exported when ingest storage is enabled (#9385)

* Add integration test to ensure cortex_distributor_replication_factor is not exported when ingest storage is enabled

Signed-off-by: Marco Pracucci <[email protected]>

* Added counterproof that cortex_distributor_replication_factor is exported when ingest storage is disabled

Signed-off-by: Marco Pracucci <[email protected]>

---------

Signed-off-by: Marco Pracucci <[email protected]>
  • Loading branch information
pracucci authored Sep 24, 2024
1 parent 9698ad8 commit 41a6c6d
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 0 deletions.
54 changes: 54 additions & 0 deletions integration/asserts.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strings"
"testing"

"github.com/grafana/regexp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

Expand Down Expand Up @@ -96,3 +97,56 @@ func getBlacklistedMetricsPrefixesByService(serviceType ServiceType) []string {

return blacklist
}

func assertServiceMetricsNotMatching(t *testing.T, metricName string, services ...*e2emimir.MimirService) {
for _, service := range services {
if service == nil {
continue
}

metrics, err := service.Metrics()
require.NoError(t, err)

if isRawMetricsContainingMetricName(metricName, metrics) {
assert.Failf(t, "the service %s exported metrics include the metric name %s but it should not export it", service.Name(), metricName)
}
}
}

func assertServiceMetricsMatching(t *testing.T, metricName string, services ...*e2emimir.MimirService) {
for _, service := range services {
if service == nil {
continue
}

metrics, err := service.Metrics()
require.NoError(t, err)

if !isRawMetricsContainingMetricName(metricName, metrics) {
assert.Failf(t, "the service %s exported metrics don't include the metric name %s but it should export it", service.Name(), metricName)
}
}
}

func isRawMetricsContainingMetricName(metricName string, metrics string) bool {
metricNameRegex := regexp.MustCompile("^[^ \\{]+")

// Ensure no metric name matches the input one.
for _, metricLine := range strings.Split(metrics, "\n") {
metricLine = strings.TrimSpace(metricLine)
if metricLine == "" || strings.HasPrefix(metricLine, "#") {
continue
}

actualMetricName := metricNameRegex.FindStringSubmatch(metricLine)
if len(actualMetricName) != 1 {
continue
}

if actualMetricName[0] == metricName {
return true
}
}

return false
}
36 changes: 36 additions & 0 deletions integration/asserts_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: AGPL-3.0-only
// Provenance-includes-location: https://github.com/cortexproject/cortex/blob/master/integration/asserts.go
// Provenance-includes-license: Apache-2.0
// Provenance-includes-copyright: The Cortex Authors.
//go:build requires_docker

package integration

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestIsRawMetricsContainingMetricName(t *testing.T) {
rawMetrics := `
# HELP metric_1 Test
# TYPE metric_1 counter
metric_1{a="b"} 0
metric_1{c="d"} 0
# HELP metric_10 Test
# TYPE metric_10 counter
metric_10 0
# HELP metric_20 Test
# TYPE metric_20 counter
metric_20 0
`

assert.True(t, isRawMetricsContainingMetricName("metric_1", rawMetrics))
assert.True(t, isRawMetricsContainingMetricName("metric_10", rawMetrics))
assert.True(t, isRawMetricsContainingMetricName("metric_20", rawMetrics))
assert.False(t, isRawMetricsContainingMetricName("metric_2", rawMetrics))
assert.False(t, isRawMetricsContainingMetricName("metric_200", rawMetrics))
}
8 changes: 8 additions & 0 deletions integration/query_frontend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,14 @@ func runQueryFrontendTest(t *testing.T, cfg queryFrontendTestConfig) {
assertServiceMetricsPrefixes(t, Querier, querier)
assertServiceMetricsPrefixes(t, QueryFrontend, queryFrontend)
assertServiceMetricsPrefixes(t, QueryScheduler, queryScheduler)

if flags["-ingest-storage.enabled"] == "true" {
// Ensure cortex_distributor_replication_factor is not exported when ingest storage is enabled
// because it's how we detect whether a Mimir cluster is running with ingest storage.
assertServiceMetricsNotMatching(t, "cortex_distributor_replication_factor", queryFrontend, queryScheduler, distributor, ingester, querier)
} else {
assertServiceMetricsMatching(t, "cortex_distributor_replication_factor", distributor)
}
}

// This spins up a minimal query-frontend setup and compares if errors returned
Expand Down
8 changes: 8 additions & 0 deletions integration/ruler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1208,6 +1208,10 @@ func TestRulerRemoteEvaluation_ShouldEnforceStrongReadConsistencyForDependentRul
// have run with eventual consistency because they are independent.
require.NoError(t, queryFrontend.WaitSumMetrics(e2e.Equals(0), "cortex_ingest_storage_strong_consistency_requests_total"))
require.NoError(t, ingester.WaitSumMetrics(e2e.Equals(0), "cortex_ingest_storage_strong_consistency_requests_total"))

// Ensure cortex_distributor_replication_factor is not exported when ingest storage is enabled
// because it's how we detect whether a Mimir cluster is running with ingest storage.
assertServiceMetricsNotMatching(t, "cortex_distributor_replication_factor", queryFrontend, distributor, ingester, querier, ruler)
})

t.Run("evaluation of dependent rules should require strong consistency", func(t *testing.T) {
Expand Down Expand Up @@ -1242,6 +1246,10 @@ func TestRulerRemoteEvaluation_ShouldEnforceStrongReadConsistencyForDependentRul
// We expect the offsets to be fetched by query-frontend and then propagated to ingesters.
require.NoError(t, ingester.WaitSumMetricsWithOptions(e2e.GreaterOrEqual(1), []string{"cortex_ingest_storage_strong_consistency_requests_total"}, e2e.WithLabelMatchers(labels.MustNewMatcher(labels.MatchEqual, "with_offset", "true"))))
require.NoError(t, ingester.WaitSumMetricsWithOptions(e2e.Equals(0), []string{"cortex_ingest_storage_strong_consistency_requests_total"}, e2e.WithLabelMatchers(labels.MustNewMatcher(labels.MatchEqual, "with_offset", "false"))))

// Ensure cortex_distributor_replication_factor is not exported when ingest storage is enabled
// because it's how we detect whether a Mimir cluster is running with ingest storage.
assertServiceMetricsNotMatching(t, "cortex_distributor_replication_factor", queryFrontend, distributor, ingester, querier, ruler)
})
}

Expand Down

0 comments on commit 41a6c6d

Please sign in to comment.