// Copyright 2017 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package remote import ( "testing" "github.com/stretchr/testify/require" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/prompb" "github.com/prometheus/prometheus/storage" ) func TestValidateLabelsAndMetricName(t *testing.T) { tests := []struct { input labels.Labels expectedErr string shouldPass bool }{ { input: labels.FromStrings( "__name__", "name", "labelName", "labelValue", ), expectedErr: "", shouldPass: true, }, { input: labels.FromStrings( "__name__", "name", "_labelName", "labelValue", ), expectedErr: "", shouldPass: true, }, { input: labels.FromStrings( "__name__", "name", "@labelName", "labelValue", ), expectedErr: "Invalid label name: @labelName", shouldPass: false, }, { input: labels.FromStrings( "__name__", "name", "123labelName", "labelValue", ), expectedErr: "Invalid label name: 123labelName", shouldPass: false, }, { input: labels.FromStrings( "__name__", "name", "", "labelValue", ), expectedErr: "Invalid label name: ", shouldPass: false, }, { input: labels.FromStrings( "__name__", "name", "labelName", string([]byte{0xff}), ), expectedErr: "Invalid label value: " + string([]byte{0xff}), shouldPass: false, }, { input: labels.FromStrings( "__name__", "@invalid_name", ), expectedErr: "Invalid metric name: @invalid_name", shouldPass: false, }, } for _, test := range tests { err := validateLabelsAndMetricName(test.input) if test.shouldPass != (err == nil) { if test.shouldPass { t.Fatalf("Test should pass, got unexpected error: %v", err) } else { t.Fatalf("Test should fail, unexpected error, got: %v, expected: %v", err, test.expectedErr) } } } } func TestConcreteSeriesSet(t *testing.T) { series1 := &concreteSeries{ labels: labels.FromStrings("foo", "bar"), samples: []prompb.Sample{{Value: 1, Timestamp: 2}}, } series2 := &concreteSeries{ labels: labels.FromStrings("foo", "baz"), samples: []prompb.Sample{{Value: 3, Timestamp: 4}}, } c := &concreteSeriesSet{ series: []storage.Series{series1, series2}, } if !c.Next() { t.Fatalf("Expected Next() to be true.") } if c.At() != series1 { t.Fatalf("Unexpected series returned.") } if !c.Next() { t.Fatalf("Expected Next() to be true.") } if c.At() != series2 { t.Fatalf("Unexpected series returned.") } if c.Next() { t.Fatalf("Expected Next() to be false.") } } func TestConcreteSeriesClonesLabels(t *testing.T) { lbls := labels.Labels{ labels.Label{Name: "a", Value: "b"}, labels.Label{Name: "c", Value: "d"}, } cs := concreteSeries{ labels: labels.New(lbls...), } gotLabels := cs.Labels() require.Equal(t, lbls, gotLabels) gotLabels[0].Value = "foo" gotLabels[1].Value = "bar" gotLabels = cs.Labels() require.Equal(t, lbls, gotLabels) }