diff --git a/prometheus/histogram.go b/prometheus/histogram.go index 4e0a9c8..6cc6e68 100644 --- a/prometheus/histogram.go +++ b/prometheus/histogram.go @@ -430,8 +430,8 @@ func NewConstHistogram( buckets map[float64]uint64, labelValues ...string, ) (Metric, error) { - if len(desc.variableLabels) != len(labelValues) { - return nil, errInconsistentCardinality + if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil { + return nil, err } return &constHistogram{ desc: desc, diff --git a/prometheus/summary.go b/prometheus/summary.go index 964d8cb..56b0663 100644 --- a/prometheus/summary.go +++ b/prometheus/summary.go @@ -543,8 +543,8 @@ func NewConstSummary( quantiles map[float64]float64, labelValues ...string, ) (Metric, error) { - if len(desc.variableLabels) != len(labelValues) { - return nil, errInconsistentCardinality + if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil { + return nil, err } return &constSummary{ desc: desc, diff --git a/prometheus/value.go b/prometheus/value.go index ff75ce5..c445f67 100644 --- a/prometheus/value.go +++ b/prometheus/value.go @@ -158,8 +158,8 @@ func (v *valueFunc) Write(out *dto.Metric) error { // the Collect method. NewConstMetric returns an error if the length of // labelValues is not consistent with the variable labels in Desc. func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) (Metric, error) { - if len(desc.variableLabels) != len(labelValues) { - return nil, errInconsistentCardinality + if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil { + return nil, err } return &constMetric{ desc: desc, diff --git a/prometheus/value_test.go b/prometheus/value_test.go new file mode 100644 index 0000000..329d938 --- /dev/null +++ b/prometheus/value_test.go @@ -0,0 +1,48 @@ +package prometheus + +import ( + "fmt" + "testing" +) + +func TestNewConstMetricInvalidLabelValues(t *testing.T) { + testCases := []struct { + desc string + labels Labels + }{ + { + desc: "non utf8 label value", + labels: Labels{"a": "\xFF"}, + }, + { + desc: "not enough label values", + labels: Labels{}, + }, + { + desc: "too many label values", + labels: Labels{"a": "1", "b": "2"}, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + metricDesc := NewDesc( + "sample_value", + "sample value", + []string{"a"}, + Labels{}, + ) + + expectPanic(t, func() { + MustNewConstMetric(metricDesc, CounterValue, 0.3, "\xFF") + }, fmt.Sprintf("WithLabelValues: expected panic because: %s", test.desc)) + + if _, err := NewConstMetric(metricDesc, CounterValue, 0.3, "\xFF"); err == nil { + t.Errorf("NewConstMetric: expected error because: %s", test.desc) + } + }) + } +} diff --git a/prometheus/vec.go b/prometheus/vec.go index 728faf9..4e19995 100644 --- a/prometheus/vec.go +++ b/prometheus/vec.go @@ -207,7 +207,7 @@ func (m *metricVec) Reset() { } func (m *metricVec) hashLabelValues(vals []string) (uint64, error) { - if err := validateLabelValues(m.desc, vals); err != nil { + if err := validateLabelValues(vals, len(m.desc.variableLabels)); err != nil { return 0, err } @@ -220,7 +220,7 @@ func (m *metricVec) hashLabelValues(vals []string) (uint64, error) { } func (m *metricVec) hashLabels(labels Labels) (uint64, error) { - if err := validateLabels(m.desc, labels); err != nil { + if err := validateLabels(labels, len(m.desc.variableLabels)); err != nil { return 0, err }