@@ -151,6 +151,137 @@ func TestValidateLabels(t *testing.T) {
151151 ` ), "cortex_discarded_samples_total" ))
152152}
153153
154+ // same test
155+ func TestValidateLabels_Legacy (t * testing.T ) {
156+ cfg := new (Limits )
157+ userID := "testUser"
158+
159+ reg := prometheus .NewRegistry ()
160+ validateMetrics := NewValidateMetrics (reg )
161+
162+ cfg .MaxLabelValueLength = 25
163+ cfg .MaxLabelNameLength = 25
164+ cfg .MaxLabelNamesPerSeries = 2
165+ cfg .MaxLabelsSizeBytes = 90
166+ cfg .EnforceMetricName = true
167+ cfg .UseUTF8Validation = false // Legacy validation
168+ cfg .LimitsPerLabelSet = []LimitsPerLabelSet {
169+ {
170+ Limits : LimitsPerLabelSetEntry {MaxSeries : 0 },
171+ LabelSet : labels .FromMap (map [string ]string {
172+ model .MetricNameLabel : "foo" ,
173+ }),
174+ Hash : 0 ,
175+ },
176+ {
177+ Limits : LimitsPerLabelSetEntry {MaxSeries : 0 },
178+ LabelSet : labels .EmptyLabels (),
179+ Hash : 1 ,
180+ },
181+ }
182+
183+ for i , c := range []struct {
184+ metric model.Metric
185+ skipLabelNameValidation bool
186+ expectedErr error
187+ }{
188+ {map [model.LabelName ]model.LabelValue {}, false , newNoMetricNameError ()},
189+ {map [model.LabelName ]model.LabelValue {model .MetricNameLabel : " " }, false , newInvalidMetricNameError (" " )},
190+ {map [model.LabelName ]model.LabelValue {model .MetricNameLabel : "valid" , "foo " : "bar" }, false ,
191+ newInvalidLabelError ([]cortexpb.LabelAdapter {
192+ {Name : model .MetricNameLabel , Value : "valid" },
193+ {Name : "foo " , Value : "bar" },
194+ }, "foo " )},
195+ {map [model.LabelName ]model.LabelValue {model .MetricNameLabel : "valid" }, false , nil },
196+ {
197+ map [model.LabelName ]model.LabelValue {model .MetricNameLabel : "badLabelName" , "this_is_a_really_really_long_name_that_should_cause_an_error" : "test_value_please_ignore" },
198+ false ,
199+ newLabelNameTooLongError ([]cortexpb.LabelAdapter {
200+ {Name : model .MetricNameLabel , Value : "badLabelName" },
201+ {Name : "this_is_a_really_really_long_name_that_should_cause_an_error" , Value : "test_value_please_ignore" },
202+ }, "this_is_a_really_really_long_name_that_should_cause_an_error" , cfg .MaxLabelNameLength ),
203+ },
204+ {
205+ map [model.LabelName ]model.LabelValue {model .MetricNameLabel : "badLabelValue" , "much_shorter_name" : "test_value_please_ignore_no_really_nothing_to_see_here" },
206+ false ,
207+ newLabelValueTooLongError ([]cortexpb.LabelAdapter {
208+ {Name : model .MetricNameLabel , Value : "badLabelValue" },
209+ {Name : "much_shorter_name" , Value : "test_value_please_ignore_no_really_nothing_to_see_here" },
210+ }, "much_shorter_name" , "test_value_please_ignore_no_really_nothing_to_see_here" , cfg .MaxLabelValueLength ),
211+ },
212+ {
213+ map [model.LabelName ]model.LabelValue {model .MetricNameLabel : "foo" , "bar" : "baz" , "blip" : "blop" },
214+ false ,
215+ newTooManyLabelsError ([]cortexpb.LabelAdapter {
216+ {Name : model .MetricNameLabel , Value : "foo" },
217+ {Name : "bar" , Value : "baz" },
218+ {Name : "blip" , Value : "blop" },
219+ }, 2 ),
220+ },
221+ {
222+ map [model.LabelName ]model.LabelValue {model .MetricNameLabel : "exactly_twenty_five_chars" , "exactly_twenty_five_chars" : "exactly_twenty_five_chars" },
223+ false ,
224+ labelSizeBytesExceededError ([]cortexpb.LabelAdapter {
225+ {Name : model .MetricNameLabel , Value : "exactly_twenty_five_chars" },
226+ {Name : "exactly_twenty_five_chars" , Value : "exactly_twenty_five_chars" },
227+ }, 91 , cfg .MaxLabelsSizeBytes ),
228+ },
229+ {map [model.LabelName ]model.LabelValue {model .MetricNameLabel : "foo" , "invalid%label&name" : "bar" }, true , nil },
230+ } {
231+ convertedLabels := cortexpb .FromMetricsToLabelAdapters (c .metric )
232+
233+ t .Logf ("Case %d:\n Input Metric: %+v\n SkipLabelNameValidation: %v" , i , c .metric , c .skipLabelNameValidation )
234+
235+ err := ValidateLabels (validateMetrics , cfg , userID , convertedLabels , c .skipLabelNameValidation )
236+
237+ if err != nil {
238+ t .Logf (" Got Error: %v" , err )
239+ } else {
240+ t .Log (" Got Error: <nil>" )
241+ }
242+
243+ if c .expectedErr != nil {
244+ t .Logf (" Expected Error: %v" , c .expectedErr )
245+ } else {
246+ t .Log (" Expected Error: <nil>" )
247+ }
248+
249+ assert .Equal (t , c .expectedErr , err , "wrong error (case %d)" , i )
250+ }
251+
252+ // Metrics validation
253+ validateMetrics .DiscardedSamples .WithLabelValues ("random reason" , "different user" ).Inc ()
254+
255+ require .NoError (t , testutil .GatherAndCompare (reg , strings .NewReader (`
256+ # HELP cortex_discarded_samples_total The total number of samples that were discarded.
257+ # TYPE cortex_discarded_samples_total counter
258+ cortex_discarded_samples_total{reason="label_invalid",user="testUser"} 1
259+ cortex_discarded_samples_total{reason="label_name_too_long",user="testUser"} 1
260+ cortex_discarded_samples_total{reason="label_value_too_long",user="testUser"} 1
261+ cortex_discarded_samples_total{reason="max_label_names_per_series",user="testUser"} 1
262+ cortex_discarded_samples_total{reason="metric_name_invalid",user="testUser"} 1
263+ cortex_discarded_samples_total{reason="missing_metric_name",user="testUser"} 1
264+ cortex_discarded_samples_total{reason="labels_size_bytes_exceeded",user="testUser"} 1
265+ cortex_discarded_samples_total{reason="random reason",user="different user"} 1
266+ ` ), "cortex_discarded_samples_total" ))
267+
268+ require .NoError (t , testutil .GatherAndCompare (reg , strings .NewReader (`
269+ # HELP cortex_label_size_bytes The combined size in bytes of all labels and label values for a time series.
270+ # TYPE cortex_label_size_bytes histogram
271+ cortex_label_size_bytes_bucket{user="testUser",le="+Inf"} 3
272+ cortex_label_size_bytes_sum{user="testUser"} 148
273+ cortex_label_size_bytes_count{user="testUser"} 3
274+ ` ), "cortex_label_size_bytes" ))
275+
276+ DeletePerUserValidationMetrics (validateMetrics , userID , util_log .Logger )
277+
278+ require .NoError (t , testutil .GatherAndCompare (reg , strings .NewReader (`
279+ # HELP cortex_discarded_samples_total The total number of samples that were discarded.
280+ # TYPE cortex_discarded_samples_total counter
281+ cortex_discarded_samples_total{reason="random reason",user="different user"} 1
282+ ` ), "cortex_discarded_samples_total" ))
283+ }
284+
154285func TestValidateExemplars (t * testing.T ) {
155286 userID := "testUser"
156287 reg := prometheus .NewRegistry ()
0 commit comments