labels: respect Set after Del in Builder (#12322)

* labels: respect Set after Del in Builder

The implementations are not symmetric between `Set()` and `Del()`, so
we must be careful. Add tests for this, both in labels and in relabel
where the issue was reported.

Also make the slice implementation consistent re `slices.Contains`.

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
This commit is contained in:
Bryan Boreham 2023-05-03 11:59:27 +01:00 committed by GitHub
parent d70688038e
commit 7a48a266b6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 8 deletions

View file

@ -533,16 +533,15 @@ func (b *Builder) Set(n, v string) *Builder {
} }
func (b *Builder) Get(n string) string { func (b *Builder) Get(n string) string {
for _, d := range b.del { // Del() removes entries from .add but Set() does not remove from .del, so check .add first.
if d == n {
return ""
}
}
for _, a := range b.add { for _, a := range b.add {
if a.Name == n { if a.Name == n {
return a.Value return a.Value
} }
} }
if slices.Contains(b.del, n) {
return ""
}
return b.base.Get(n) return b.base.Get(n)
} }

View file

@ -593,14 +593,15 @@ func (b *Builder) Set(n, v string) *Builder {
} }
func (b *Builder) Get(n string) string { func (b *Builder) Get(n string) string {
if slices.Contains(b.del, n) { // Del() removes entries from .add but Set() does not remove from .del, so check .add first.
return ""
}
for _, a := range b.add { for _, a := range b.add {
if a.Name == n { if a.Name == n {
return a.Value return a.Value
} }
} }
if slices.Contains(b.del, n) {
return ""
}
return b.base.Get(n) return b.base.Get(n)
} }

View file

@ -607,6 +607,13 @@ func TestBuilder(t *testing.T) {
require.Equal(t, tcase.want.BytesWithoutLabels(nil, "aaa", "bbb"), b.Labels().Bytes(nil)) require.Equal(t, tcase.want.BytesWithoutLabels(nil, "aaa", "bbb"), b.Labels().Bytes(nil))
}) })
} }
t.Run("set_after_del", func(t *testing.T) {
b := NewBuilder(FromStrings("aaa", "111"))
b.Del("bbb")
b.Set("bbb", "222")
require.Equal(t, FromStrings("aaa", "111", "bbb", "222"), b.Labels())
require.Equal(t, "222", b.Get("bbb"))
})
} }
func TestScratchBuilder(t *testing.T) { func TestScratchBuilder(t *testing.T) {

View file

@ -397,6 +397,34 @@ func TestRelabel(t *testing.T) {
"foo": "bar", "foo": "bar",
}), }),
}, },
{ // From https://github.com/prometheus/prometheus/issues/12283
input: labels.FromMap(map[string]string{
"__meta_kubernetes_pod_container_port_name": "foo",
"__meta_kubernetes_pod_annotation_XXX_metrics_port": "9091",
}),
relabel: []*Config{
{
Regex: MustNewRegexp("^__meta_kubernetes_pod_container_port_name$"),
Action: LabelDrop,
},
{
SourceLabels: model.LabelNames{"__meta_kubernetes_pod_annotation_XXX_metrics_port"},
Regex: MustNewRegexp("(.+)"),
Action: Replace,
Replacement: "metrics",
TargetLabel: "__meta_kubernetes_pod_container_port_name",
},
{
SourceLabels: model.LabelNames{"__meta_kubernetes_pod_container_port_name"},
Regex: MustNewRegexp("^metrics$"),
Action: Keep,
},
},
output: labels.FromMap(map[string]string{
"__meta_kubernetes_pod_annotation_XXX_metrics_port": "9091",
"__meta_kubernetes_pod_container_port_name": "metrics",
}),
},
{ {
input: labels.FromMap(map[string]string{ input: labels.FromMap(map[string]string{
"a": "foo", "a": "foo",