@@ -366,22 +366,77 @@ func TestIngesterPerLabelsetLimitExceeded(t *testing.T) {
366
366
cortex_ingester_usage_per_labelset{labelset="{comp2=\"compValue2\"}",limit="max_series",user="1"} 3
367
367
` ), "cortex_ingester_usage_per_labelset" , "cortex_ingester_limits_per_labelset" ))
368
368
369
- // Should remove metrics when the limits is removed
369
+ // Add default partition -> no label set configured working as a fallback when a series
370
+ // doesn't match any existing label set limit.
371
+ emptyLabels := labels .EmptyLabels ()
372
+ defaultPartitionLimits := validation.LimitsPerLabelSet {LabelSet : emptyLabels ,
373
+ Limits : validation.LimitsPerLabelSetEntry {
374
+ MaxSeries : 2 ,
375
+ },
376
+ }
377
+ limits .LimitsPerLabelSet = append (limits .LimitsPerLabelSet , defaultPartitionLimits )
378
+ b , err = json .Marshal (limits )
379
+ require .NoError (t , err )
380
+ require .NoError (t , limits .UnmarshalJSON (b ))
381
+ tenantLimits .setLimits (userID , & limits )
382
+
383
+ lbls = []string {labels .MetricName , "test_default" }
384
+ for i := 0 ; i < 2 ; i ++ {
385
+ _ , err = ing .Push (ctx , cortexpb .ToWriteRequest (
386
+ []labels.Labels {labels .FromStrings (append (lbls , "series" , strconv .Itoa (i ))... )}, samples , nil , nil , cortexpb .API ))
387
+ require .NoError (t , err )
388
+ }
389
+
390
+ // Max series limit for default partition is 2 so 1 more series will be throttled.
391
+ _ , err = ing .Push (ctx , cortexpb .ToWriteRequest (
392
+ []labels.Labels {labels .FromStrings (append (lbls , "extraLabel" , "extraValueUpdate2" )... )}, samples , nil , nil , cortexpb .API ))
393
+ httpResp , ok = httpgrpc .HTTPResponseFromError (err )
394
+ require .True (t , ok , "returned error is not an httpgrpc response" )
395
+ assert .Equal (t , http .StatusBadRequest , int (httpResp .Code ))
396
+ require .ErrorContains (t , err , emptyLabels .String ())
397
+
398
+ ing .updateActiveSeries (ctx )
399
+ require .NoError (t , testutil .GatherAndCompare (registry , bytes .NewBufferString (`
400
+ # HELP cortex_ingester_limits_per_labelset Limits per user and labelset.
401
+ # TYPE cortex_ingester_limits_per_labelset gauge
402
+ cortex_ingester_limits_per_labelset{labelset="{__name__=\"metric_name\", comp2=\"compValue2\"}",limit="max_series",user="1"} 3
403
+ cortex_ingester_limits_per_labelset{labelset="{comp1=\"compValue1\", comp2=\"compValue2\"}",limit="max_series",user="1"} 2
404
+ cortex_ingester_limits_per_labelset{labelset="{comp1=\"compValue1\"}",limit="max_series",user="1"} 10
405
+ cortex_ingester_limits_per_labelset{labelset="{comp2=\"compValue2\"}",limit="max_series",user="1"} 10
406
+ cortex_ingester_limits_per_labelset{labelset="{label1=\"value1\"}",limit="max_series",user="1"} 3
407
+ cortex_ingester_limits_per_labelset{labelset="{label2=\"value2\"}",limit="max_series",user="1"} 2
408
+ cortex_ingester_limits_per_labelset{labelset="{}",limit="max_series",user="1"} 2
409
+ # HELP cortex_ingester_usage_per_labelset Current usage per user and labelset.
410
+ # TYPE cortex_ingester_usage_per_labelset gauge
411
+ cortex_ingester_usage_per_labelset{labelset="{__name__=\"metric_name\", comp2=\"compValue2\"}",limit="max_series",user="1"} 3
412
+ cortex_ingester_usage_per_labelset{labelset="{label1=\"value1\"}",limit="max_series",user="1"} 3
413
+ cortex_ingester_usage_per_labelset{labelset="{label2=\"value2\"}",limit="max_series",user="1"} 2
414
+ cortex_ingester_usage_per_labelset{labelset="{comp1=\"compValue1\", comp2=\"compValue2\"}",limit="max_series",user="1"} 2
415
+ cortex_ingester_usage_per_labelset{labelset="{comp1=\"compValue1\"}",limit="max_series",user="1"} 7
416
+ cortex_ingester_usage_per_labelset{labelset="{comp2=\"compValue2\"}",limit="max_series",user="1"} 3
417
+ cortex_ingester_usage_per_labelset{labelset="{}",limit="max_series",user="1"} 2
418
+ ` ), "cortex_ingester_usage_per_labelset" , "cortex_ingester_limits_per_labelset" ))
419
+
420
+ // Should remove metrics when the limits is removed, keep default partition limit
370
421
limits .LimitsPerLabelSet = limits .LimitsPerLabelSet [:2 ]
422
+ limits .LimitsPerLabelSet = append (limits .LimitsPerLabelSet , defaultPartitionLimits )
371
423
b , err = json .Marshal (limits )
372
424
require .NoError (t , err )
373
425
require .NoError (t , limits .UnmarshalJSON (b ))
374
426
tenantLimits .setLimits (userID , & limits )
375
427
ing .updateActiveSeries (ctx )
428
+ // Default partition usage increased from 2 to 10 as some existing partitions got removed.
376
429
require .NoError (t , testutil .GatherAndCompare (registry , bytes .NewBufferString (`
377
430
# HELP cortex_ingester_limits_per_labelset Limits per user and labelset.
378
431
# TYPE cortex_ingester_limits_per_labelset gauge
379
432
cortex_ingester_limits_per_labelset{labelset="{label1=\"value1\"}",limit="max_series",user="1"} 3
380
433
cortex_ingester_limits_per_labelset{labelset="{label2=\"value2\"}",limit="max_series",user="1"} 2
434
+ cortex_ingester_limits_per_labelset{labelset="{}",limit="max_series",user="1"} 2
381
435
# HELP cortex_ingester_usage_per_labelset Current usage per user and labelset.
382
436
# TYPE cortex_ingester_usage_per_labelset gauge
383
437
cortex_ingester_usage_per_labelset{labelset="{label1=\"value1\"}",limit="max_series",user="1"} 3
384
438
cortex_ingester_usage_per_labelset{labelset="{label2=\"value2\"}",limit="max_series",user="1"} 2
439
+ cortex_ingester_usage_per_labelset{labelset="{}",limit="max_series",user="1"} 10
385
440
` ), "cortex_ingester_usage_per_labelset" , "cortex_ingester_limits_per_labelset" ))
386
441
387
442
// Should persist between restarts
@@ -396,10 +451,12 @@ func TestIngesterPerLabelsetLimitExceeded(t *testing.T) {
396
451
# TYPE cortex_ingester_limits_per_labelset gauge
397
452
cortex_ingester_limits_per_labelset{labelset="{label1=\"value1\"}",limit="max_series",user="1"} 3
398
453
cortex_ingester_limits_per_labelset{labelset="{label2=\"value2\"}",limit="max_series",user="1"} 2
454
+ cortex_ingester_limits_per_labelset{labelset="{}",limit="max_series",user="1"} 2
399
455
# HELP cortex_ingester_usage_per_labelset Current usage per user and labelset.
400
456
# TYPE cortex_ingester_usage_per_labelset gauge
401
457
cortex_ingester_usage_per_labelset{labelset="{label1=\"value1\"}",limit="max_series",user="1"} 3
402
458
cortex_ingester_usage_per_labelset{labelset="{label2=\"value2\"}",limit="max_series",user="1"} 2
459
+ cortex_ingester_usage_per_labelset{labelset="{}",limit="max_series",user="1"} 10
403
460
` ), "cortex_ingester_usage_per_labelset" , "cortex_ingester_limits_per_labelset" ))
404
461
services .StopAndAwaitTerminated (context .Background (), ing ) //nolint:errcheck
405
462
@@ -420,6 +477,13 @@ func TestPushRace(t *testing.T) {
420
477
MaxSeries : 10e10 ,
421
478
},
422
479
},
480
+ {
481
+ // Default partition.
482
+ LabelSet : labels .EmptyLabels (),
483
+ Limits : validation.LimitsPerLabelSetEntry {
484
+ MaxSeries : 10e10 ,
485
+ },
486
+ },
423
487
}
424
488
425
489
dir := t .TempDir ()
@@ -451,6 +515,10 @@ func TestPushRace(t *testing.T) {
451
515
defer wg .Done ()
452
516
_ , err := ing .Push (ctx , cortexpb .ToWriteRequest ([]labels.Labels {labels .FromStrings (labels .MetricName , "foo" , "userId" , userID , "k" , strconv .Itoa (k ))}, []cortexpb.Sample {sample1 }, nil , nil , cortexpb .API ))
453
517
require .NoError (t , err )
518
+
519
+ // Go to default partition.
520
+ _ , err = ing .Push (ctx , cortexpb .ToWriteRequest ([]labels.Labels {labels .FromStrings (labels .MetricName , "bar" , "userId" , userID , "k" , strconv .Itoa (k ))}, []cortexpb.Sample {sample1 }, nil , nil , cortexpb .API ))
521
+ require .NoError (t , err )
454
522
}()
455
523
}
456
524
}
@@ -472,13 +540,13 @@ func TestPushRace(t *testing.T) {
472
540
err = ir .Series (p .At (), & builder , nil )
473
541
require .NoError (t , err )
474
542
lbls := builder .Labels ()
475
- require .Equal (t , "foo" , lbls .Get (labels .MetricName ))
543
+ require .True (t , lbls . Get ( labels . MetricName ) == "foo" || lbls .Get (labels .MetricName ) == "bar" )
476
544
require .Equal (t , "1" , lbls .Get ("userId" ))
477
545
require .NotEmpty (t , lbls .Get ("k" ))
478
546
builder .Reset ()
479
547
}
480
- require .Equal (t , numberOfSeries , total )
481
- require .Equal (t , uint64 (numberOfSeries ), db .Head ().NumSeries ())
548
+ require .Equal (t , 2 * numberOfSeries , total )
549
+ require .Equal (t , uint64 (2 * numberOfSeries ), db .Head ().NumSeries ())
482
550
}
483
551
484
552
func TestIngesterUserLimitExceeded (t * testing.T ) {
0 commit comments