labels: in tests use labels.FromStrings

Replacing code which assumes the internal structure of `Labels`.

Add a convenience function `EmptyLabels()` which is more efficient than
calling `New()`.

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
This commit is contained in:
Bryan Boreham 2022-05-26 14:58:06 +00:00 committed by Julien Pivotto
parent ec6c1f17d1
commit 5421c778ba
2 changed files with 146 additions and 325 deletions

View file

@ -333,6 +333,11 @@ func (ls Labels) Map() map[string]string {
return m return m
} }
// EmptyLabels returns n empty Labels value, for convenience.
func EmptyLabels() Labels {
return Labels{}
}
// New returns a sorted Labels from the given labels. // New returns a sorted Labels from the given labels.
// The caller has to guarantee that all label names are unique. // The caller has to guarantee that all label names are unique.
func New(ls ...Label) Labels { func New(ls ...Label) Labels {

View file

@ -29,16 +29,7 @@ func TestLabels_String(t *testing.T) {
expected string expected string
}{ }{
{ {
lables: Labels{ lables: FromStrings("t1", "t1", "t2", "t2"),
{
Name: "t1",
Value: "t1",
},
{
Name: "t2",
Value: "t2",
},
},
expected: "{t1=\"t1\", t2=\"t2\"}", expected: "{t1=\"t1\", t2=\"t2\"}",
}, },
{ {
@ -57,32 +48,13 @@ func TestLabels_String(t *testing.T) {
} }
func TestLabels_MatchLabels(t *testing.T) { func TestLabels_MatchLabels(t *testing.T) {
labels := Labels{ labels := FromStrings(
{ "__name__", "ALERTS",
Name: "__name__", "alertname", "HTTPRequestRateLow",
Value: "ALERTS", "alertstate", "pending",
}, "instance", "0",
{ "job", "app-server",
Name: "alertname", "severity", "critical")
Value: "HTTPRequestRateLow",
},
{
Name: "alertstate",
Value: "pending",
},
{
Name: "instance",
Value: "0",
},
{
Name: "job",
Value: "app-server",
},
{
Name: "severity",
Value: "critical",
},
}
tests := []struct { tests := []struct {
providedNames []string providedNames []string
@ -98,24 +70,11 @@ func TestLabels_MatchLabels(t *testing.T) {
"instance", "instance",
}, },
on: true, on: true,
expected: Labels{ expected: FromStrings(
{ "__name__", "ALERTS",
Name: "__name__", "alertname", "HTTPRequestRateLow",
Value: "ALERTS", "alertstate", "pending",
}, "instance", "0"),
{
Name: "alertname",
Value: "HTTPRequestRateLow",
},
{
Name: "alertstate",
Value: "pending",
},
{
Name: "instance",
Value: "0",
},
},
}, },
// on = false, explicitly excluding metric name from matching. // on = false, explicitly excluding metric name from matching.
{ {
@ -126,16 +85,9 @@ func TestLabels_MatchLabels(t *testing.T) {
"instance", "instance",
}, },
on: false, on: false,
expected: Labels{ expected: FromStrings(
{ "job", "app-server",
Name: "job", "severity", "critical"),
Value: "app-server",
},
{
Name: "severity",
Value: "critical",
},
},
}, },
// on = true, explicitly excluding metric name from matching. // on = true, explicitly excluding metric name from matching.
{ {
@ -145,20 +97,10 @@ func TestLabels_MatchLabels(t *testing.T) {
"instance", "instance",
}, },
on: true, on: true,
expected: Labels{ expected: FromStrings(
{ "alertname", "HTTPRequestRateLow",
Name: "alertname", "alertstate", "pending",
Value: "HTTPRequestRateLow", "instance", "0"),
},
{
Name: "alertstate",
Value: "pending",
},
{
Name: "instance",
Value: "0",
},
},
}, },
// on = false, implicitly excluding metric name from matching. // on = false, implicitly excluding metric name from matching.
{ {
@ -168,16 +110,9 @@ func TestLabels_MatchLabels(t *testing.T) {
"instance", "instance",
}, },
on: false, on: false,
expected: Labels{ expected: FromStrings(
{ "job", "app-server",
Name: "job", "severity", "critical"),
Value: "app-server",
},
{
Name: "severity",
Value: "critical",
},
},
}, },
} }
@ -197,10 +132,7 @@ func TestLabels_HasDuplicateLabelNames(t *testing.T) {
Input: FromMap(map[string]string{"__name__": "up", "hostname": "localhost"}), Input: FromMap(map[string]string{"__name__": "up", "hostname": "localhost"}),
Duplicate: false, Duplicate: false,
}, { }, {
Input: append( Input: FromStrings("__name__", "up", "hostname", "localhost", "hostname", "127.0.0.1"),
FromMap(map[string]string{"__name__": "up", "hostname": "localhost"}),
FromMap(map[string]string{"hostname": "127.0.0.1"})...,
),
Duplicate: true, Duplicate: true,
LabelName: "hostname", LabelName: "hostname",
}, },
@ -219,73 +151,63 @@ func TestLabels_WithoutEmpty(t *testing.T) {
expected Labels expected Labels
}{ }{
{ {
input: Labels{ input: FromStrings(
{Name: "foo"}, "foo", "",
{Name: "bar"}, "bar", ""),
}, expected: EmptyLabels(),
expected: Labels{},
}, },
{ {
input: Labels{ input: FromStrings(
{Name: "foo"}, "foo", "",
{Name: "bar"}, "bar", "",
{Name: "baz"}, "baz", ""),
}, expected: EmptyLabels(),
expected: Labels{},
}, },
{ {
input: Labels{ input: FromStrings(
{Name: "__name__", Value: "test"}, "__name__", "test",
{Name: "hostname", Value: "localhost"}, "hostname", "localhost",
{Name: "job", Value: "check"}, "job", "check"),
}, expected: FromStrings(
expected: Labels{ "__name__", "test",
{Name: "__name__", Value: "test"}, "hostname", "localhost",
{Name: "hostname", Value: "localhost"}, "job", "check"),
{Name: "job", Value: "check"},
},
}, },
{ {
input: Labels{ input: FromStrings(
{Name: "__name__", Value: "test"}, "__name__", "test",
{Name: "hostname", Value: "localhost"}, "hostname", "localhost",
{Name: "bar"}, "bar", "",
{Name: "job", Value: "check"}, "job", "check"),
}, expected: FromStrings(
expected: Labels{ "__name__", "test",
{Name: "__name__", Value: "test"}, "hostname", "localhost",
{Name: "hostname", Value: "localhost"}, "job", "check"),
{Name: "job", Value: "check"},
},
}, },
{ {
input: Labels{ input: FromStrings(
{Name: "__name__", Value: "test"}, "__name__", "test",
{Name: "foo"}, "foo", "",
{Name: "hostname", Value: "localhost"}, "hostname", "localhost",
{Name: "bar"}, "bar", "",
{Name: "job", Value: "check"}, "job", "check"),
}, expected: FromStrings(
expected: Labels{ "__name__", "test",
{Name: "__name__", Value: "test"}, "hostname", "localhost",
{Name: "hostname", Value: "localhost"}, "job", "check"),
{Name: "job", Value: "check"},
},
}, },
{ {
input: Labels{ input: FromStrings(
{Name: "__name__", Value: "test"}, "__name__", "test",
{Name: "foo"}, "foo", "",
{Name: "baz"}, "baz", "",
{Name: "hostname", Value: "localhost"}, "hostname", "localhost",
{Name: "bar"}, "bar", "",
{Name: "job", Value: "check"}, "job", "check"),
}, expected: FromStrings(
expected: Labels{ "__name__", "test",
{Name: "__name__", Value: "test"}, "hostname", "localhost",
{Name: "hostname", Value: "localhost"}, "job", "check"),
{Name: "job", Value: "check"},
},
}, },
} { } {
t.Run("", func(t *testing.T) { t.Run("", func(t *testing.T) {
@ -295,75 +217,37 @@ func TestLabels_WithoutEmpty(t *testing.T) {
} }
func TestLabels_Equal(t *testing.T) { func TestLabels_Equal(t *testing.T) {
labels := Labels{ labels := FromStrings(
{ "aaa", "111",
Name: "aaa", "bbb", "222")
Value: "111",
},
{
Name: "bbb",
Value: "222",
},
}
tests := []struct { tests := []struct {
compared Labels compared Labels
expected bool expected bool
}{ }{
{ {
compared: Labels{ compared: FromStrings(
{ "aaa", "111",
Name: "aaa", "bbb", "222",
Value: "111", "ccc", "333"),
},
{
Name: "bbb",
Value: "222",
},
{
Name: "ccc",
Value: "333",
},
},
expected: false, expected: false,
}, },
{ {
compared: Labels{ compared: FromStrings(
{ "aaa", "111",
Name: "aaa", "bar", "222"),
Value: "111",
},
{
Name: "bar",
Value: "222",
},
},
expected: false, expected: false,
}, },
{ {
compared: Labels{ compared: FromStrings(
{ "aaa", "111",
Name: "aaa", "bbb", "233"),
Value: "111",
},
{
Name: "bbb",
Value: "233",
},
},
expected: false, expected: false,
}, },
{ {
compared: Labels{ compared: FromStrings(
{ "aaa", "111",
Name: "aaa", "bbb", "222"),
Value: "111",
},
{
Name: "bbb",
Value: "222",
},
},
expected: true, expected: true,
}, },
} }
@ -393,114 +277,55 @@ func TestLabels_FromStrings(t *testing.T) {
} }
func TestLabels_Compare(t *testing.T) { func TestLabels_Compare(t *testing.T) {
labels := Labels{ labels := FromStrings(
{ "aaa", "111",
Name: "aaa", "bbb", "222")
Value: "111",
},
{
Name: "bbb",
Value: "222",
},
}
tests := []struct { tests := []struct {
compared Labels compared Labels
expected int expected int
}{ }{
{ {
compared: Labels{ compared: FromStrings(
{ "aaa", "110",
Name: "aaa", "bbb", "222"),
Value: "110",
},
{
Name: "bbb",
Value: "222",
},
},
expected: 1, expected: 1,
}, },
{ {
compared: Labels{ compared: FromStrings(
{ "aaa", "111",
Name: "aaa", "bbb", "233"),
Value: "111",
},
{
Name: "bbb",
Value: "233",
},
},
expected: -1, expected: -1,
}, },
{ {
compared: Labels{ compared: FromStrings(
{ "aaa", "111",
Name: "aaa", "bar", "222"),
Value: "111",
},
{
Name: "bar",
Value: "222",
},
},
expected: 1, expected: 1,
}, },
{ {
compared: Labels{ compared: FromStrings(
{ "aaa", "111",
Name: "aaa", "bbc", "222"),
Value: "111",
},
{
Name: "bbc",
Value: "222",
},
},
expected: -1, expected: -1,
}, },
{ {
compared: Labels{ compared: FromStrings(
{ "aaa", "111"),
Name: "aaa",
Value: "111",
},
},
expected: 1, expected: 1,
}, },
{ {
compared: Labels{ compared: FromStrings(
{ "aaa", "111",
Name: "aaa", "bbb", "222",
Value: "111", "ccc", "333",
}, "ddd", "444"),
{
Name: "bbb",
Value: "222",
},
{
Name: "ccc",
Value: "333",
},
{
Name: "ddd",
Value: "444",
},
},
expected: -2, expected: -2,
}, },
{ {
compared: Labels{ compared: FromStrings(
{ "aaa", "111",
Name: "aaa", "bbb", "222"),
Value: "111",
},
{
Name: "bbb",
Value: "222",
},
},
expected: 0, expected: 0,
}, },
} }
@ -536,16 +361,9 @@ func TestLabels_Has(t *testing.T) {
}, },
} }
labelsSet := Labels{ labelsSet := FromStrings(
{ "aaa", "111",
Name: "aaa", "bbb", "222")
Value: "111",
},
{
Name: "bbb",
Value: "222",
},
}
for i, test := range tests { for i, test := range tests {
got := labelsSet.Has(test.input) got := labelsSet.Has(test.input)
@ -554,8 +372,8 @@ func TestLabels_Has(t *testing.T) {
} }
func TestLabels_Get(t *testing.T) { func TestLabels_Get(t *testing.T) {
require.Equal(t, "", Labels{{"aaa", "111"}, {"bbb", "222"}}.Get("foo")) require.Equal(t, "", FromStrings("aaa", "111", "bbb", "222").Get("foo"))
require.Equal(t, "111", Labels{{"aaa", "111"}, {"bbb", "222"}}.Get("aaa")) require.Equal(t, "111", FromStrings("aaa", "111", "bbb", "222").Get("aaa"))
} }
// BenchmarkLabels_Get was written to check whether a binary search can improve the performance vs the linear search implementation // BenchmarkLabels_Get was written to check whether a binary search can improve the performance vs the linear search implementation
@ -605,18 +423,18 @@ func BenchmarkLabels_Equals(b *testing.B) {
}{ }{
{ {
"equal", "equal",
Labels{{"a_label_name", "a_label_value"}, {"another_label_name", "another_label_value"}}, FromStrings("a_label_name", "a_label_value", "another_label_name", "another_label_value"),
Labels{{"a_label_name", "a_label_value"}, {"another_label_name", "another_label_value"}}, FromStrings("a_label_name", "a_label_value", "another_label_name", "another_label_value"),
}, },
{ {
"not equal", "not equal",
Labels{{"a_label_name", "a_label_value"}, {"another_label_name", "another_label_value"}}, FromStrings("a_label_name", "a_label_value", "another_label_name", "another_label_value"),
Labels{{"a_label_name", "a_label_value"}, {"another_label_name", "a_different_label_value"}}, FromStrings("a_label_name", "a_label_value", "another_label_name", "a_different_label_value"),
}, },
{ {
"different sizes", "different sizes",
Labels{{"a_label_name", "a_label_value"}, {"another_label_name", "another_label_value"}}, FromStrings("a_label_name", "a_label_value", "another_label_name", "another_label_value"),
Labels{{"a_label_name", "a_label_value"}}, FromStrings("a_label_name", "a_label_value"),
}, },
} { } {
b.Run(scenario.desc, func(b *testing.B) { b.Run(scenario.desc, func(b *testing.B) {
@ -629,22 +447,22 @@ func BenchmarkLabels_Equals(b *testing.B) {
} }
func TestLabels_Copy(t *testing.T) { func TestLabels_Copy(t *testing.T) {
require.Equal(t, Labels{{"aaa", "111"}, {"bbb", "222"}}, Labels{{"aaa", "111"}, {"bbb", "222"}}.Copy()) require.Equal(t, FromStrings("aaa", "111", "bbb", "222"), FromStrings("aaa", "111", "bbb", "222").Copy())
} }
func TestLabels_Map(t *testing.T) { func TestLabels_Map(t *testing.T) {
require.Equal(t, map[string]string{"aaa": "111", "bbb": "222"}, Labels{{"aaa", "111"}, {"bbb", "222"}}.Map()) require.Equal(t, map[string]string{"aaa": "111", "bbb": "222"}, FromStrings("aaa", "111", "bbb", "222").Map())
} }
func TestLabels_BytesWithLabels(t *testing.T) { func TestLabels_BytesWithLabels(t *testing.T) {
require.Equal(t, Labels{{"aaa", "111"}, {"bbb", "222"}}.Bytes(nil), Labels{{"aaa", "111"}, {"bbb", "222"}, {"ccc", "333"}}.BytesWithLabels(nil, "aaa", "bbb")) require.Equal(t, FromStrings("aaa", "111", "bbb", "222").Bytes(nil), FromStrings("aaa", "111", "bbb", "222", "ccc", "333").BytesWithLabels(nil, "aaa", "bbb"))
require.Equal(t, Labels{}.Bytes(nil), Labels{{"aaa", "111"}, {"bbb", "222"}, {"ccc", "333"}}.BytesWithLabels(nil)) require.Equal(t, FromStrings().Bytes(nil), FromStrings("aaa", "111", "bbb", "222", "ccc", "333").BytesWithLabels(nil))
} }
func TestLabels_BytesWithoutLabels(t *testing.T) { func TestLabels_BytesWithoutLabels(t *testing.T) {
require.Equal(t, Labels{{"aaa", "111"}}.Bytes(nil), Labels{{"aaa", "111"}, {"bbb", "222"}, {"ccc", "333"}}.BytesWithoutLabels(nil, "bbb", "ccc")) require.Equal(t, FromStrings("aaa", "111").Bytes(nil), FromStrings("aaa", "111", "bbb", "222", "ccc", "333").BytesWithoutLabels(nil, "bbb", "ccc"))
require.Equal(t, Labels{{MetricName, "333"}, {"aaa", "111"}}.Bytes(nil), Labels{{MetricName, "333"}, {"aaa", "111"}, {"bbb", "222"}}.BytesWithoutLabels(nil, "bbb")) require.Equal(t, FromStrings(MetricName, "333", "aaa", "111").Bytes(nil), FromStrings(MetricName, "333", "aaa", "111", "bbb", "222").BytesWithoutLabels(nil, "bbb"))
require.Equal(t, Labels{{"aaa", "111"}}.Bytes(nil), Labels{{MetricName, "333"}, {"aaa", "111"}, {"bbb", "222"}}.BytesWithoutLabels(nil, MetricName, "bbb")) require.Equal(t, FromStrings("aaa", "111").Bytes(nil), FromStrings(MetricName, "333", "aaa", "111", "bbb", "222").BytesWithoutLabels(nil, MetricName, "bbb"))
} }
func TestBuilder(t *testing.T) { func TestBuilder(t *testing.T) {
@ -728,11 +546,9 @@ func TestBuilder(t *testing.T) {
} }
func TestLabels_Hash(t *testing.T) { func TestLabels_Hash(t *testing.T) {
lbls := Labels{ lbls := FromStrings("foo", "bar", "baz", "qux")
{Name: "foo", Value: "bar"},
{Name: "baz", Value: "qux"},
}
require.Equal(t, lbls.Hash(), lbls.Hash()) require.Equal(t, lbls.Hash(), lbls.Hash())
require.NotEqual(t, lbls.Hash(), Labels{lbls[1], lbls[0]}.Hash(), "unordered labels match.")
require.NotEqual(t, lbls.Hash(), Labels{lbls[0]}.Hash(), "different labels match.") require.NotEqual(t, lbls.Hash(), Labels{lbls[0]}.Hash(), "different labels match.")
} }
@ -746,23 +562,23 @@ func BenchmarkLabels_Hash(b *testing.B) {
{ {
name: "typical labels under 1KB", name: "typical labels under 1KB",
lbls: func() Labels { lbls: func() Labels {
lbls := make(Labels, 10) b := NewBuilder(EmptyLabels())
for i := 0; i < len(lbls); i++ { for i := 0; i < 10; i++ {
// Label ~20B name, 50B value. // Label ~20B name, 50B value.
lbls[i] = Label{Name: fmt.Sprintf("abcdefghijabcdefghijabcdefghij%d", i), Value: fmt.Sprintf("abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij%d", i)} b.Set(fmt.Sprintf("abcdefghijabcdefghijabcdefghij%d", i), fmt.Sprintf("abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij%d", i))
} }
return lbls return b.Labels(nil)
}(), }(),
}, },
{ {
name: "bigger labels over 1KB", name: "bigger labels over 1KB",
lbls: func() Labels { lbls: func() Labels {
lbls := make(Labels, 10) b := NewBuilder(EmptyLabels())
for i := 0; i < len(lbls); i++ { for i := 0; i < 10; i++ {
// Label ~50B name, 50B value. // Label ~50B name, 50B value.
lbls[i] = Label{Name: fmt.Sprintf("abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij%d", i), Value: fmt.Sprintf("abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij%d", i)} b.Set(fmt.Sprintf("abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij%d", i), fmt.Sprintf("abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij%d", i))
} }
return lbls return b.Labels(nil)
}(), }(),
}, },
{ {
@ -774,7 +590,7 @@ func BenchmarkLabels_Hash(b *testing.B) {
for i := 0; i < lbl.Cap()/len(word); i++ { for i := 0; i < lbl.Cap()/len(word); i++ {
_, _ = lbl.WriteString(word) _, _ = lbl.WriteString(word)
} }
return Labels{{Name: "__name__", Value: lbl.String()}} return FromStrings("__name__", lbl.String())
}(), }(),
}, },
} { } {