Skip to content

Commit 24e6573

Browse files
committed
Adding testing
Signed-off-by: Paurush Garg <[email protected]>
1 parent 20bbde4 commit 24e6573

File tree

4 files changed

+124
-22
lines changed

4 files changed

+124
-22
lines changed

pkg/ingester/ingester.go

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,21 +1224,22 @@ func (i *Ingester) Push(ctx context.Context, req *cortexpb.WriteRequest) (*corte
12241224
// Keep track of some stats which are tracked only if the samples will be
12251225
// successfully committed
12261226
var (
1227-
succeededSamplesCount = 0
1228-
failedSamplesCount = 0
1229-
succeededHistogramsCount = 0
1230-
failedHistogramsCount = 0
1231-
succeededExemplarsCount = 0
1232-
failedExemplarsCount = 0
1233-
startAppend = time.Now()
1234-
sampleOutOfBoundsCount = 0
1235-
sampleOutOfOrderCount = 0
1236-
sampleTooOldCount = 0
1237-
newValueForTimestampCount = 0
1238-
perUserSeriesLimitCount = 0
1239-
perLabelSetSeriesLimitCount = 0
1240-
perMetricSeriesLimitCount = 0
1241-
discardedNativeHistogramCount = 0
1227+
succeededSamplesCount = 0
1228+
failedSamplesCount = 0
1229+
succeededHistogramsCount = 0
1230+
failedHistogramsCount = 0
1231+
succeededExemplarsCount = 0
1232+
failedExemplarsCount = 0
1233+
startAppend = time.Now()
1234+
sampleOutOfBoundsCount = 0
1235+
sampleOutOfOrderCount = 0
1236+
sampleTooOldCount = 0
1237+
newValueForTimestampCount = 0
1238+
perUserSeriesLimitCount = 0
1239+
perUserNativeHistogramsSeriesLimitCount = 0
1240+
perLabelSetSeriesLimitCount = 0
1241+
perMetricSeriesLimitCount = 0
1242+
discardedNativeHistogramCount = 0
12421243

12431244
updateFirstPartial = func(errFn func() error) {
12441245
if firstPartialErr == nil {
@@ -1274,6 +1275,12 @@ func (i *Ingester) Push(ctx context.Context, req *cortexpb.WriteRequest) (*corte
12741275
return makeLimitError(perUserSeriesLimit, i.limiter.FormatError(userID, cause, copiedLabels))
12751276
})
12761277

1278+
case errors.Is(cause, errMaxNativeHistogramsSeriesPerUserLimitExceeded):
1279+
perUserNativeHistogramsSeriesLimitCount++
1280+
updateFirstPartial(func() error {
1281+
return makeLimitError(perUserSeriesLimit, i.limiter.FormatError(userID, cause, copiedLabels))
1282+
})
1283+
12771284
case errors.Is(cause, errMaxSeriesPerMetricLimitExceeded):
12781285
perMetricSeriesLimitCount++
12791286
updateFirstPartial(func() error {
@@ -1517,6 +1524,9 @@ func (i *Ingester) Push(ctx context.Context, req *cortexpb.WriteRequest) (*corte
15171524
if perUserSeriesLimitCount > 0 {
15181525
i.validateMetrics.DiscardedSamples.WithLabelValues(perUserSeriesLimit, userID).Add(float64(perUserSeriesLimitCount))
15191526
}
1527+
if perUserNativeHistogramsSeriesLimitCount > 0 {
1528+
i.validateMetrics.DiscardedSamples.WithLabelValues(perUserNativeHistogramsSeriesLimit, userID).Add(float64(perUserNativeHistogramsSeriesLimitCount))
1529+
}
15201530
if perMetricSeriesLimitCount > 0 {
15211531
i.validateMetrics.DiscardedSamples.WithLabelValues(perMetricSeriesLimit, userID).Add(float64(perMetricSeriesLimitCount))
15221532
}

pkg/ingester/ingester_test.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,93 @@ func TestIngesterUserLimitExceeded(t *testing.T) {
868868

869869
}
870870

871+
func TestIngesterUserLimitExceededForNativeHistograms(t *testing.T) {
872+
limits := defaultLimitsTestConfig()
873+
limits.EnableNativeHistograms = true
874+
limits.MaxLocalNativeHistogramsSeriesPerUser = 1
875+
limits.MaxLocalSeriesPerUser = 1
876+
limits.MaxLocalMetricsWithMetadataPerUser = 1
877+
878+
userID := "1"
879+
// Series
880+
labels1 := labels.Labels{{Name: labels.MetricName, Value: "testmetric"}, {Name: "foo", Value: "bar"}}
881+
labels3 := labels.Labels{{Name: labels.MetricName, Value: "testmetric"}, {Name: "foo", Value: "biz"}}
882+
sampleNativeHistogram1 := cortexpb.HistogramToHistogramProto(0, tsdbutil.GenerateTestHistogram(1))
883+
sampleNativeHistogram2 := cortexpb.HistogramToHistogramProto(1, tsdbutil.GenerateTestHistogram(2))
884+
sampleNativeHistogram3 := cortexpb.HistogramToHistogramProto(0, tsdbutil.GenerateTestHistogram(3))
885+
886+
// Metadata
887+
metadata1 := &cortexpb.MetricMetadata{MetricFamilyName: "testmetric", Help: "a help for testmetric", Type: cortexpb.COUNTER}
888+
metadata2 := &cortexpb.MetricMetadata{MetricFamilyName: "testmetric2", Help: "a help for testmetric2", Type: cortexpb.COUNTER}
889+
890+
dir := t.TempDir()
891+
892+
chunksDir := filepath.Join(dir, "chunks")
893+
blocksDir := filepath.Join(dir, "blocks")
894+
require.NoError(t, os.Mkdir(chunksDir, os.ModePerm))
895+
require.NoError(t, os.Mkdir(blocksDir, os.ModePerm))
896+
897+
blocksIngesterGenerator := func(reg prometheus.Registerer) *Ingester {
898+
ing, err := prepareIngesterWithBlocksStorageAndLimits(t, defaultIngesterTestConfig(t), limits, nil, blocksDir, reg)
899+
require.NoError(t, err)
900+
require.NoError(t, services.StartAndAwaitRunning(context.Background(), ing))
901+
// Wait until it's ACTIVE
902+
test.Poll(t, time.Second, ring.ACTIVE, func() interface{} {
903+
return ing.lifecycler.GetState()
904+
})
905+
906+
return ing
907+
}
908+
909+
tests := []string{"blocks"}
910+
for i, ingGenerator := range []func(reg prometheus.Registerer) *Ingester{blocksIngesterGenerator} {
911+
t.Run(tests[i], func(t *testing.T) {
912+
reg := prometheus.NewRegistry()
913+
ing := ingGenerator(reg)
914+
915+
// Append only one series and one metadata first, expect no error.
916+
ctx := user.InjectOrgID(context.Background(), userID)
917+
_, err := ing.Push(ctx, cortexpb.ToWriteRequest([]labels.Labels{labels1}, nil, []*cortexpb.MetricMetadata{metadata1}, []cortexpb.Histogram{sampleNativeHistogram1}, cortexpb.API))
918+
require.NoError(t, err)
919+
920+
testLimits := func(reg prometheus.Gatherer) {
921+
// Append to two series, expect series-exceeded error.
922+
_, err = ing.Push(ctx, cortexpb.ToWriteRequest([]labels.Labels{labels1, labels3}, nil, nil, []cortexpb.Histogram{sampleNativeHistogram2, sampleNativeHistogram3}, cortexpb.API))
923+
httpResp, ok := httpgrpc.HTTPResponseFromError(err)
924+
require.True(t, ok, "returned error is not an httpgrpc response")
925+
assert.Equal(t, http.StatusBadRequest, int(httpResp.Code))
926+
assert.Equal(t, wrapWithUser(makeLimitError(perUserNativeHistogramsSeriesLimit, ing.limiter.FormatError(userID, errMaxNativeHistogramsSeriesPerUserLimitExceeded, labels1)), userID).Error(), string(httpResp.Body))
927+
928+
// Append two metadata, expect no error since metadata is a best effort approach.
929+
_, err = ing.Push(ctx, cortexpb.ToWriteRequest(nil, nil, []*cortexpb.MetricMetadata{metadata1, metadata2}, nil, cortexpb.API))
930+
require.NoError(t, err)
931+
932+
// Read samples back via ingester queries.
933+
res, _, err := runTestQuery(ctx, t, ing, labels.MatchEqual, model.MetricNameLabel, "testmetric")
934+
require.NoError(t, err)
935+
require.NotNil(t, res)
936+
937+
// Verify metadata
938+
m, err := ing.MetricsMetadata(ctx, &client.MetricsMetadataRequest{Limit: -1, LimitPerMetric: -1, Metric: ""})
939+
require.NoError(t, err)
940+
assert.Equal(t, []*cortexpb.MetricMetadata{metadata1}, m.Metadata)
941+
}
942+
943+
testLimits(reg)
944+
945+
// Limits should hold after restart.
946+
services.StopAndAwaitTerminated(context.Background(), ing) //nolint:errcheck
947+
// Use new registry to prevent metrics registration panic.
948+
reg = prometheus.NewRegistry()
949+
ing = ingGenerator(reg)
950+
defer services.StopAndAwaitTerminated(context.Background(), ing) //nolint:errcheck
951+
952+
testLimits(reg)
953+
})
954+
}
955+
956+
}
957+
871958
func benchmarkData(nSeries int) (allLabels []labels.Labels, allSamples []cortexpb.Sample) {
872959
for j := 0; j < nSeries; j++ {
873960
labels := chunk.BenchmarkLabels.Copy()

pkg/ingester/limiter_test.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -656,10 +656,11 @@ func TestLimiter_FormatError(t *testing.T) {
656656

657657
// Mock limits
658658
limits, err := validation.NewOverrides(validation.Limits{
659-
MaxGlobalSeriesPerUser: 100,
660-
MaxGlobalSeriesPerMetric: 20,
661-
MaxGlobalMetricsWithMetadataPerUser: 10,
662-
MaxGlobalMetadataPerMetric: 3,
659+
MaxGlobalSeriesPerUser: 100,
660+
MaxGlobalNativeHistogramsSeriesPerUser: 100,
661+
MaxGlobalSeriesPerMetric: 20,
662+
MaxGlobalMetricsWithMetadataPerUser: 10,
663+
MaxGlobalMetadataPerMetric: 3,
663664
}, nil)
664665
require.NoError(t, err)
665666

@@ -669,6 +670,9 @@ func TestLimiter_FormatError(t *testing.T) {
669670
actual := limiter.FormatError("user-1", errMaxSeriesPerUserLimitExceeded, lbls)
670671
assert.EqualError(t, actual, "per-user series limit of 100 exceeded, please contact administrator to raise it (local limit: 0 global limit: 100 actual local limit: 100)")
671672

673+
actual = limiter.FormatError("user-1", errMaxNativeHistogramsSeriesPerUserLimitExceeded, lbls)
674+
assert.EqualError(t, actual, "per-user nativeHistograms series limit of 100 exceeded, please contact administrator to raise it (local limit: 0 global limit: 100 actual local limit: 100)")
675+
672676
actual = limiter.FormatError("user-1", errMaxSeriesPerMetricLimitExceeded, lbls)
673677
assert.EqualError(t, actual, "per-metric series limit of 20 exceeded for metric testMetric, please contact administrator to raise it (local limit: 0 global limit: 20 actual local limit: 20)")
674678

pkg/ingester/user_state.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ import (
1616

1717
// DiscardedSamples metric labels
1818
const (
19-
perUserSeriesLimit = "per_user_series_limit"
20-
perMetricSeriesLimit = "per_metric_series_limit"
21-
perLabelsetSeriesLimit = "per_labelset_series_limit"
19+
perUserSeriesLimit = "per_user_series_limit"
20+
perUserNativeHistogramsSeriesLimit = "per_user_native_histograms_series_limit"
21+
perMetricSeriesLimit = "per_metric_series_limit"
22+
perLabelsetSeriesLimit = "per_labelset_series_limit"
2223
)
2324

2425
const numMetricCounterShards = 128

0 commit comments

Comments
 (0)