Skip to content

Commit 4525d21

Browse files
committed
feat(model): remove deprecated global NameValidationScheme
1 parent 7f8b2a0 commit 4525d21

File tree

12 files changed

+68
-88
lines changed

12 files changed

+68
-88
lines changed

expfmt/decode.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import (
2929

3030
// Decoder types decode an input stream into metric families.
3131
type Decoder interface {
32-
Decode(*dto.MetricFamily) error
32+
Decode(*dto.MetricFamily, model.ValidationScheme) error
3333
}
3434

3535
// DecodeOptions contains options used by the Decoder and in sample extraction.
@@ -86,14 +86,14 @@ type protoDecoder struct {
8686
}
8787

8888
// Decode implements the Decoder interface.
89-
func (d *protoDecoder) Decode(v *dto.MetricFamily) error {
89+
func (d *protoDecoder) Decode(v *dto.MetricFamily, nameValidationScheme model.ValidationScheme) error {
9090
opts := protodelim.UnmarshalOptions{
9191
MaxSize: -1,
9292
}
9393
if err := opts.UnmarshalFrom(d.r, v); err != nil {
9494
return err
9595
}
96-
if !model.IsValidMetricName(model.LabelValue(v.GetName())) {
96+
if !model.IsValidMetricName(model.LabelValue(v.GetName()), nameValidationScheme) {
9797
return fmt.Errorf("invalid metric name %q", v.GetName())
9898
}
9999
for _, m := range v.GetMetric() {
@@ -107,7 +107,7 @@ func (d *protoDecoder) Decode(v *dto.MetricFamily) error {
107107
if !model.LabelValue(l.GetValue()).IsValid() {
108108
return fmt.Errorf("invalid label value %q", l.GetValue())
109109
}
110-
if !model.LabelName(l.GetName()).IsValid() {
110+
if !model.LabelName(l.GetName()).IsValid(nameValidationScheme) {
111111
return fmt.Errorf("invalid label name %q", l.GetName())
112112
}
113113
}
@@ -123,7 +123,7 @@ type textDecoder struct {
123123
}
124124

125125
// Decode implements the Decoder interface.
126-
func (d *textDecoder) Decode(v *dto.MetricFamily) error {
126+
func (d *textDecoder) Decode(v *dto.MetricFamily, _ model.ValidationScheme) error {
127127
if d.err == nil {
128128
// Read all metrics in one shot.
129129
var p TextParser
@@ -156,8 +156,8 @@ type SampleDecoder struct {
156156

157157
// Decode calls the Decode method of the wrapped Decoder and then extracts the
158158
// samples from the decoded MetricFamily into the provided model.Vector.
159-
func (sd *SampleDecoder) Decode(s *model.Vector) error {
160-
err := sd.Dec.Decode(&sd.f)
159+
func (sd *SampleDecoder) Decode(s *model.Vector, nameValidationScheme model.ValidationScheme) error {
160+
err := sd.Dec.Decode(&sd.f, nameValidationScheme)
161161
if err != nil {
162162
return err
163163
}

expfmt/decode_test.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ mf2 4
8888
var all model.Vector
8989
for {
9090
var smpls model.Vector
91-
err := dec.Decode(&smpls)
91+
err := dec.Decode(&smpls, model.UTF8Validation)
9292
if err != nil && errors.Is(err, io.EOF) {
9393
break
9494
}
@@ -369,22 +369,20 @@ func TestProtoDecoder(t *testing.T) {
369369

370370
var all model.Vector
371371
for {
372-
model.NameValidationScheme = model.LegacyValidation //nolint:staticcheck
373372
var smpls model.Vector
374-
err := dec.Decode(&smpls)
373+
err := dec.Decode(&smpls, model.LegacyValidation)
375374
if err != nil && errors.Is(err, io.EOF) {
376375
break
377376
}
378377
if scenario.legacyNameFail {
379378
require.Errorf(t, err, "Expected error when decoding without UTF-8 support enabled but got none")
380-
model.NameValidationScheme = model.UTF8Validation //nolint:staticcheck
381379
dec = &SampleDecoder{
382380
Dec: &protoDecoder{r: strings.NewReader(scenario.in)},
383381
Opts: &DecodeOptions{
384382
Timestamp: testTime,
385383
},
386384
}
387-
err = dec.Decode(&smpls)
385+
err = dec.Decode(&smpls, model.UTF8Validation)
388386
if errors.Is(err, io.EOF) {
389387
break
390388
}
@@ -412,7 +410,7 @@ func TestProtoMultiMessageDecoder(t *testing.T) {
412410
var metrics []*dto.MetricFamily
413411
for {
414412
var mf dto.MetricFamily
415-
if err := decoder.Decode(&mf); err != nil {
413+
if err := decoder.Decode(&mf, model.UTF8Validation); err != nil {
416414
if errors.Is(err, io.EOF) {
417415
break
418416
}
@@ -560,7 +558,7 @@ func TestTextDecoderWithBufioReader(t *testing.T) {
560558
dec := NewDecoder(r, FmtText)
561559
for {
562560
var mf dto.MetricFamily
563-
if err := dec.Decode(&mf); err != nil {
561+
if err := dec.Decode(&mf, model.UTF8Validation); err != nil {
564562
if errors.Is(err, io.EOF) {
565563
break
566564
}

model/alert.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,20 +88,20 @@ func (a *Alert) StatusAt(ts time.Time) AlertStatus {
8888
}
8989

9090
// Validate checks whether the alert data is inconsistent.
91-
func (a *Alert) Validate() error {
91+
func (a *Alert) Validate(nameValidationScheme ValidationScheme) error {
9292
if a.StartsAt.IsZero() {
9393
return errors.New("start time missing")
9494
}
9595
if !a.EndsAt.IsZero() && a.EndsAt.Before(a.StartsAt) {
9696
return errors.New("start time must be before end time")
9797
}
98-
if err := a.Labels.Validate(); err != nil {
98+
if err := a.Labels.Validate(nameValidationScheme); err != nil {
9999
return fmt.Errorf("invalid label set: %w", err)
100100
}
101101
if len(a.Labels) == 0 {
102102
return errors.New("at least one label pair required")
103103
}
104-
if err := a.Annotations.Validate(); err != nil {
104+
if err := a.Annotations.Validate(nameValidationScheme); err != nil {
105105
return fmt.Errorf("invalid annotations: %w", err)
106106
}
107107
return nil

model/alert_test.go

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,91 +22,97 @@ import (
2222
)
2323

2424
func TestAlertValidate(t *testing.T) {
25-
oldScheme := NameValidationScheme
26-
NameValidationScheme = LegacyValidation
27-
defer func() {
28-
NameValidationScheme = oldScheme
29-
}()
3025
ts := time.Now()
3126

3227
cases := []struct {
33-
alert *Alert
34-
err string
28+
alert *Alert
29+
err string
30+
scheme NameValidationScheme
3531
}{
3632
{
3733
alert: &Alert{
3834
Labels: LabelSet{"a": "b"},
3935
StartsAt: ts,
4036
},
37+
scheme: LegacyValidation,
4138
},
4239
{
4340
alert: &Alert{
4441
Labels: LabelSet{"a": "b"},
4542
},
46-
err: "start time missing",
43+
scheme: LegacyValidation,
44+
err: "start time missing",
4745
},
4846
{
4947
alert: &Alert{
5048
Labels: LabelSet{"a": "b"},
5149
StartsAt: ts,
5250
EndsAt: ts,
5351
},
52+
scheme: LegacyValidation,
5453
},
5554
{
5655
alert: &Alert{
5756
Labels: LabelSet{"a": "b"},
5857
StartsAt: ts,
5958
EndsAt: ts.Add(1 * time.Minute),
6059
},
60+
scheme: LegacyValidation,
6161
},
6262
{
6363
alert: &Alert{
6464
Labels: LabelSet{"a": "b"},
6565
StartsAt: ts,
6666
EndsAt: ts.Add(-1 * time.Minute),
6767
},
68-
err: "start time must be before end time",
68+
scheme: LegacyValidation,
69+
err: "start time must be before end time",
6970
},
7071
{
7172
alert: &Alert{
7273
StartsAt: ts,
7374
},
74-
err: "at least one label pair required",
75+
scheme: LegacyValidation,
76+
err: "at least one label pair required",
7577
},
7678
{
7779
alert: &Alert{
7880
Labels: LabelSet{"a": "b", "!bad": "label"},
7981
StartsAt: ts,
8082
},
81-
err: "invalid label set: invalid name",
83+
scheme: LegacyValidation,
84+
err: "invalid label set: invalid name",
8285
},
8386
{
8487
alert: &Alert{
8588
Labels: LabelSet{"a": "b", "bad": "\xfflabel"},
8689
StartsAt: ts,
8790
},
88-
err: "invalid label set: invalid value",
91+
scheme: LegacyValidation,
92+
err: "invalid label set: invalid value",
8993
},
9094
{
9195
alert: &Alert{
9296
Labels: LabelSet{"a": "b"},
9397
Annotations: LabelSet{"!bad": "label"},
9498
StartsAt: ts,
9599
},
96-
err: "invalid annotations: invalid name",
100+
scheme: LegacyValidation,
101+
err: "invalid annotations: invalid name",
97102
},
98103
{
99104
alert: &Alert{
100105
Labels: LabelSet{"a": "b"},
101106
Annotations: LabelSet{"bad": "\xfflabel"},
102107
StartsAt: ts,
103108
},
104-
err: "invalid annotations: invalid value",
109+
scheme: LegacyValidation,
110+
err: "invalid annotations: invalid value",
105111
},
106112
}
107113

108114
for i, c := range cases {
109-
err := c.alert.Validate()
115+
err := c.alert.Validate(c.scheme)
110116
if err == nil {
111117
if c.err == "" {
112118
continue

model/labels.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,17 @@ type LabelName string
106106
// IsValid returns true iff the name matches the pattern of LabelNameRE when
107107
// NameValidationScheme is set to LegacyValidation, or valid UTF-8 if
108108
// NameValidationScheme is set to UTF8Validation.
109-
func (ln LabelName) IsValid() bool {
109+
func (ln LabelName) IsValid(scheme ValidationScheme) bool {
110110
if len(ln) == 0 {
111111
return false
112112
}
113-
switch NameValidationScheme {
113+
switch scheme {
114114
case LegacyValidation:
115115
return ln.IsValidLegacy()
116116
case UTF8Validation:
117117
return utf8.ValidString(string(ln))
118118
default:
119-
panic(fmt.Sprintf("Invalid name validation scheme requested: %d", NameValidationScheme))
119+
panic(fmt.Sprintf("Invalid name validation scheme requested: %d", scheme))
120120
}
121121
}
122122

@@ -137,25 +137,27 @@ func (ln LabelName) IsValidLegacy() bool {
137137
}
138138

139139
// UnmarshalYAML implements the yaml.Unmarshaler interface.
140+
// Validation is done using UTF8Validation.
140141
func (ln *LabelName) UnmarshalYAML(unmarshal func(interface{}) error) error {
141142
var s string
142143
if err := unmarshal(&s); err != nil {
143144
return err
144145
}
145-
if !LabelName(s).IsValid() {
146+
if !LabelName(s).IsValid(UTF8Validation) {
146147
return fmt.Errorf("%q is not a valid label name", s)
147148
}
148149
*ln = LabelName(s)
149150
return nil
150151
}
151152

152153
// UnmarshalJSON implements the json.Unmarshaler interface.
154+
// Validation is done using UTF8Validation.
153155
func (ln *LabelName) UnmarshalJSON(b []byte) error {
154156
var s string
155157
if err := json.Unmarshal(b, &s); err != nil {
156158
return err
157159
}
158-
if !LabelName(s).IsValid() {
160+
if !LabelName(s).IsValid(UTF8Validation) {
159161
return fmt.Errorf("%q is not a valid label name", s)
160162
}
161163
*ln = LabelName(s)

model/labels_test.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,15 +144,13 @@ func TestLabelNameIsValid(t *testing.T) {
144144
}
145145

146146
for _, s := range scenarios {
147-
NameValidationScheme = LegacyValidation
148-
if s.ln.IsValid() != s.legacyValid {
147+
if s.ln.IsValid(LegacyValidation) != s.legacyValid {
149148
t.Errorf("Expected %v for %q using legacy IsValid method", s.legacyValid, s.ln)
150149
}
151150
if LabelNameRE.MatchString(string(s.ln)) != s.legacyValid {
152151
t.Errorf("Expected %v for %q using legacy regexp match", s.legacyValid, s.ln)
153152
}
154-
NameValidationScheme = UTF8Validation
155-
if s.ln.IsValid() != s.utf8Valid {
153+
if s.ln.IsValid(UTF8Validation) != s.utf8Valid {
156154
t.Errorf("Expected %v for %q using UTF-8 IsValid method", s.legacyValid, s.ln)
157155
}
158156
}

model/labelset.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ type LabelSet map[LabelName]LabelValue
2828

2929
// Validate checks whether all names and values in the label set
3030
// are valid.
31-
func (ls LabelSet) Validate() error {
31+
func (ls LabelSet) Validate(nameValidationScheme ValidationScheme) error {
3232
for ln, lv := range ls {
33-
if !ln.IsValid() {
33+
if !ln.IsValid(nameValidationScheme) {
3434
return fmt.Errorf("invalid name %q", ln)
3535
}
3636
if !lv.IsValid() {
@@ -140,6 +140,7 @@ func (ls LabelSet) FastFingerprint() Fingerprint {
140140
}
141141

142142
// UnmarshalJSON implements the json.Unmarshaler interface.
143+
// Validates label names using UTF8Validation.
143144
func (l *LabelSet) UnmarshalJSON(b []byte) error {
144145
var m map[LabelName]LabelValue
145146
if err := json.Unmarshal(b, &m); err != nil {
@@ -149,7 +150,7 @@ func (l *LabelSet) UnmarshalJSON(b []byte) error {
149150
// LabelName as a string and does not call its UnmarshalJSON method.
150151
// Thus, we have to replicate the behavior here.
151152
for ln := range m {
152-
if !ln.IsValid() {
153+
if !ln.IsValid(UTF8Validation) {
153154
return fmt.Errorf("%q is not a valid label name", ln)
154155
}
155156
}

model/labelset_test.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ package model
1616
import (
1717
"encoding/json"
1818
"testing"
19+
20+
"github.com/stretchr/testify/require"
1921
)
2022

2123
func TestUnmarshalJSONLabelSet(t *testing.T) {
@@ -55,12 +57,11 @@ func TestUnmarshalJSONLabelSet(t *testing.T) {
5557
}
5658
}`
5759

58-
NameValidationScheme = LegacyValidation
5960
err = json.Unmarshal([]byte(invalidlabelSetJSON), &c)
60-
expectedErr := `"1nvalid_23name" is not a valid label name`
61-
if err == nil || err.Error() != expectedErr {
62-
t.Errorf("expected an error with message '%s' to be thrown", expectedErr)
63-
}
61+
require.NoError(t, err)
62+
err = c.LabelSet.Validate(LegacyValidation)
63+
expectedErr := `invalid name "1nvalid_23name"`
64+
require.EqualError(t, err, expectedErr)
6465
}
6566

6667
func TestLabelSetClone(t *testing.T) {

0 commit comments

Comments
 (0)