mirror of
https://github.com/projectcapsule/capsule.git
synced 2026-04-22 10:36:41 +00:00
feat: diverse performance improvements (#1861)
Signed-off-by: Oliver Bähler <oliverbaehler@hotmail.com>
This commit is contained in:
@@ -20,7 +20,7 @@ func (PromotedServiceaccountPredicate) Create(e event.CreateEvent) bool {
|
||||
|
||||
v, ok := e.Object.GetLabels()[meta.OwnerPromotionLabel]
|
||||
|
||||
return ok && v == meta.OwnerPromotionLabelTrigger
|
||||
return ok && v == meta.ValueTrue
|
||||
}
|
||||
|
||||
func (PromotedServiceaccountPredicate) Delete(e event.DeleteEvent) bool {
|
||||
@@ -30,7 +30,7 @@ func (PromotedServiceaccountPredicate) Delete(e event.DeleteEvent) bool {
|
||||
|
||||
v, ok := e.Object.GetLabels()[meta.OwnerPromotionLabel]
|
||||
|
||||
return ok && v == meta.OwnerPromotionLabelTrigger
|
||||
return ok && v == meta.ValueTrue
|
||||
}
|
||||
|
||||
func (PromotedServiceaccountPredicate) Update(e event.UpdateEvent) bool {
|
||||
|
||||
@@ -49,7 +49,7 @@ func TestPromotedServiceaccountPredicate_CreateDelete(t *testing.T) {
|
||||
t.Fatalf("Create() = %v, want false (wrong value)", got)
|
||||
}
|
||||
|
||||
if got := p.Create(event.CreateEvent{Object: mk(map[string]string{meta.OwnerPromotionLabel: meta.OwnerPromotionLabelTrigger})}); !got {
|
||||
if got := p.Create(event.CreateEvent{Object: mk(map[string]string{meta.OwnerPromotionLabel: meta.ValueTrue})}); !got {
|
||||
t.Fatalf("Create() = %v, want true (trigger)", got)
|
||||
}
|
||||
})
|
||||
@@ -65,7 +65,7 @@ func TestPromotedServiceaccountPredicate_CreateDelete(t *testing.T) {
|
||||
t.Fatalf("Delete() = %v, want false (wrong value)", got)
|
||||
}
|
||||
|
||||
if got := p.Delete(event.DeleteEvent{Object: mk(map[string]string{meta.OwnerPromotionLabel: meta.OwnerPromotionLabelTrigger})}); !got {
|
||||
if got := p.Delete(event.DeleteEvent{Object: mk(map[string]string{meta.OwnerPromotionLabel: meta.ValueTrue})}); !got {
|
||||
t.Fatalf("Delete() = %v, want true (trigger)", got)
|
||||
}
|
||||
})
|
||||
@@ -93,8 +93,8 @@ func TestPromotedServiceaccountPredicate_Update(t *testing.T) {
|
||||
want bool
|
||||
}{
|
||||
{"no label in either", nil, nil, false},
|
||||
{"label added", nil, map[string]string{meta.OwnerPromotionLabel: meta.OwnerPromotionLabelTrigger}, true},
|
||||
{"label removed", map[string]string{meta.OwnerPromotionLabel: meta.OwnerPromotionLabelTrigger}, nil, true},
|
||||
{"label added", nil, map[string]string{meta.OwnerPromotionLabel: meta.ValueTrue}, true},
|
||||
{"label removed", map[string]string{meta.OwnerPromotionLabel: meta.ValueTrue}, nil, true},
|
||||
{"label value changed", map[string]string{meta.OwnerPromotionLabel: "a"}, map[string]string{meta.OwnerPromotionLabel: "b"}, true},
|
||||
{"label unchanged", map[string]string{meta.OwnerPromotionLabel: "a"}, map[string]string{meta.OwnerPromotionLabel: "a"}, false},
|
||||
}
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
|
||||
package predicates
|
||||
|
||||
import "sigs.k8s.io/controller-runtime/pkg/event"
|
||||
import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/utils"
|
||||
)
|
||||
|
||||
type UpdatedLabelsPredicate struct{}
|
||||
|
||||
@@ -16,5 +20,5 @@ func (UpdatedLabelsPredicate) Update(e event.UpdateEvent) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
return !LabelsEqual(e.ObjectOld.GetLabels(), e.ObjectNew.GetLabels())
|
||||
return !utils.MapEqual(e.ObjectOld.GetLabels(), e.ObjectNew.GetLabels())
|
||||
}
|
||||
|
||||
@@ -1,72 +1,112 @@
|
||||
// Copyright 2020-2025 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package predicates_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
. "github.com/onsi/gomega"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/runtime/predicates"
|
||||
)
|
||||
|
||||
func TestUpdatedMetadataPredicate_StaticFuncs(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
func TestUpdatedLabelsPredicate_StaticEvents(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
p := predicates.UpdatedLabelsPredicate{}
|
||||
|
||||
if got := p.Generic(event.GenericEvent{}); got {
|
||||
t.Fatalf("Generic() = %v, want false", got)
|
||||
}
|
||||
if got := p.Create(event.CreateEvent{}); !got {
|
||||
t.Fatalf("Create() = %v, want true", got)
|
||||
}
|
||||
if got := p.Delete(event.DeleteEvent{}); !got {
|
||||
t.Fatalf("Delete() = %v, want true", got)
|
||||
}
|
||||
g.Expect(p.Create(event.CreateEvent{})).To(BeTrue())
|
||||
g.Expect(p.Delete(event.DeleteEvent{})).To(BeTrue())
|
||||
g.Expect(p.Generic(event.GenericEvent{})).To(BeFalse())
|
||||
}
|
||||
|
||||
func TestUpdatedMetadataPredicate_Update(t *testing.T) {
|
||||
t.Parallel()
|
||||
func TestUpdatedLabelsPredicate_Update(t *testing.T) {
|
||||
pod := func(labels map[string]string) *corev1.Pod {
|
||||
return &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "p",
|
||||
Labels: labels,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
p := predicates.UpdatedLabelsPredicate{}
|
||||
|
||||
mk := func(lbl map[string]string) *unstructured.Unstructured {
|
||||
u := &unstructured.Unstructured{}
|
||||
u.SetAPIVersion("v1")
|
||||
u.SetKind("ConfigMap")
|
||||
u.SetName("cm")
|
||||
u.SetNamespace("ns")
|
||||
u.SetLabels(lbl)
|
||||
return u
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
old map[string]string
|
||||
new map[string]string
|
||||
old *corev1.Pod
|
||||
new *corev1.Pod
|
||||
want bool
|
||||
}{
|
||||
{"both nil", nil, nil, false},
|
||||
{"nil to empty", nil, map[string]string{}, false},
|
||||
{"same labels", map[string]string{"a": "1"}, map[string]string{"a": "1"}, false},
|
||||
{"label added", nil, map[string]string{"a": "1"}, true},
|
||||
{"label removed", map[string]string{"a": "1"}, nil, true},
|
||||
{"label value changed", map[string]string{"a": "1"}, map[string]string{"a": "2"}, true},
|
||||
{"label key changed", map[string]string{"a": "1"}, map[string]string{"b": "1"}, true},
|
||||
{
|
||||
name: "nil old => false",
|
||||
old: pod(nil),
|
||||
new: pod(map[string]string{"a": "1"}),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "nil new => false",
|
||||
old: pod(map[string]string{"a": "1"}),
|
||||
new: pod(nil),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "both nil => false",
|
||||
old: pod(nil),
|
||||
new: pod(nil),
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "labels unchanged => false",
|
||||
old: pod(map[string]string{"a": "1", "b": "2"}),
|
||||
new: pod(map[string]string{"b": "2", "a": "1"}), // order irrelevant
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "label value changed => true",
|
||||
old: pod(map[string]string{"a": "1"}),
|
||||
new: pod(map[string]string{"a": "2"}),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "label added => true",
|
||||
old: pod(map[string]string{"a": "1"}),
|
||||
new: pod(map[string]string{"a": "1", "b": "2"}),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "label removed => true",
|
||||
old: pod(map[string]string{"a": "1", "b": "2"}),
|
||||
new: pod(map[string]string{"a": "1"}),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "nil vs empty labels => unchanged (MapEqual treats both len==0 as equal)",
|
||||
old: pod(nil),
|
||||
new: pod(map[string]string{}),
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "empty vs nil labels => unchanged (MapEqual treats both len==0 as equal)",
|
||||
old: pod(map[string]string{}),
|
||||
new: pod(nil),
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
g := NewWithT(t)
|
||||
|
||||
ev := event.UpdateEvent{ObjectOld: mk(tt.old), ObjectNew: mk(tt.new)}
|
||||
if got := p.Update(ev); got != tt.want {
|
||||
t.Fatalf("Update() = %v, want %v", got, tt.want)
|
||||
ev := event.UpdateEvent{
|
||||
ObjectOld: tt.old,
|
||||
ObjectNew: tt.new,
|
||||
}
|
||||
|
||||
got := p.Update(ev)
|
||||
g.Expect(got).To(Equal(tt.want))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
133
pkg/runtime/predicates/updated_metadata_test.go
Normal file
133
pkg/runtime/predicates/updated_metadata_test.go
Normal file
@@ -0,0 +1,133 @@
|
||||
// Copyright 2020-2026 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package predicates_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/runtime/predicates"
|
||||
)
|
||||
|
||||
func TestUpdatedMetadataPredicate_StaticEvents(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
p := predicates.UpdatedMetadataPredicate{}
|
||||
|
||||
g.Expect(p.Create(event.CreateEvent{})).To(BeTrue())
|
||||
g.Expect(p.Delete(event.DeleteEvent{})).To(BeTrue())
|
||||
g.Expect(p.Generic(event.GenericEvent{})).To(BeFalse())
|
||||
}
|
||||
|
||||
func TestUpdatedMetadataPredicate_Update(t *testing.T) {
|
||||
type tc struct {
|
||||
name string
|
||||
old *corev1.Pod
|
||||
new *corev1.Pod
|
||||
want bool
|
||||
}
|
||||
|
||||
// Helper to build pods with labels/annotations
|
||||
pod := func(labels, ann map[string]string) *corev1.Pod {
|
||||
return &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "p",
|
||||
Labels: labels,
|
||||
Annotations: ann,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
tests := []tc{
|
||||
{
|
||||
name: "labels changed => true (even if annotations unchanged)",
|
||||
old: pod(map[string]string{"a": "1"}, map[string]string{"x": "1"}),
|
||||
new: pod(map[string]string{"a": "2"}, map[string]string{"x": "1"}),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "labels added => true",
|
||||
old: pod(map[string]string{"a": "1"}, nil),
|
||||
new: pod(map[string]string{"a": "1", "b": "2"}, nil),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "labels removed => true",
|
||||
old: pod(map[string]string{"a": "1", "b": "2"}, nil),
|
||||
new: pod(map[string]string{"a": "1"}, nil),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "labels same, annotations changed => true",
|
||||
old: pod(map[string]string{"a": "1"}, map[string]string{"x": "1"}),
|
||||
new: pod(map[string]string{"a": "1"}, map[string]string{"x": "2"}),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "labels same, annotations added => true",
|
||||
old: pod(map[string]string{"a": "1"}, nil),
|
||||
new: pod(map[string]string{"a": "1"}, map[string]string{"x": "1"}),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "labels same, annotations removed => true",
|
||||
old: pod(map[string]string{"a": "1"}, map[string]string{"x": "1"}),
|
||||
new: pod(map[string]string{"a": "1"}, nil),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "labels and annotations unchanged => false",
|
||||
old: pod(map[string]string{"a": "1"}, map[string]string{"x": "1"}),
|
||||
new: pod(map[string]string{"a": "1"}, map[string]string{"x": "1"}),
|
||||
want: false,
|
||||
},
|
||||
|
||||
// These two cases depend on your utils.MapEqual semantics:
|
||||
// Some implementations consider nil and empty maps equal.
|
||||
// If MapEqual treats nil != empty, then these should be true.
|
||||
// If MapEqual treats nil == empty, then these should be false.
|
||||
{
|
||||
name: "nil labels vs empty labels (depends on utils.MapEqual)",
|
||||
old: pod(nil, map[string]string{"x": "1"}),
|
||||
new: pod(map[string]string{}, map[string]string{"x": "1"}),
|
||||
want: mapEqualNilEmptyBehavior(),
|
||||
},
|
||||
{
|
||||
name: "nil annotations vs empty annotations (depends on utils.MapEqual)",
|
||||
old: pod(map[string]string{"a": "1"}, nil),
|
||||
new: pod(map[string]string{"a": "1"}, map[string]string{}),
|
||||
want: mapEqualNilEmptyBehavior(),
|
||||
},
|
||||
}
|
||||
|
||||
p := predicates.UpdatedMetadataPredicate{}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
|
||||
ev := event.UpdateEvent{
|
||||
ObjectOld: tt.old,
|
||||
ObjectNew: tt.new,
|
||||
}
|
||||
|
||||
got := p.Update(ev)
|
||||
g.Expect(got).To(Equal(tt.want))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// mapEqualNilEmptyBehavior returns the expected result for cases where one map is nil and the other is empty.
|
||||
// If your utils.MapEqual treats nil and empty as equal, expected is false (no change).
|
||||
// If it treats them as different, expected is true (change detected).
|
||||
//
|
||||
// Update this helper to match your actual utils.MapEqual behavior, or (better) directly test utils.MapEqual in its own unit tests.
|
||||
func mapEqualNilEmptyBehavior() bool {
|
||||
// Default assumption: nil and empty are equal => no change => false.
|
||||
// If your MapEqual treats them differently, change to true.
|
||||
return false
|
||||
}
|
||||
28
pkg/runtime/predicates/updated_metdata.go
Normal file
28
pkg/runtime/predicates/updated_metdata.go
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2020-2026 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package predicates
|
||||
|
||||
import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/utils"
|
||||
)
|
||||
|
||||
type UpdatedMetadataPredicate struct{}
|
||||
|
||||
func (UpdatedMetadataPredicate) Create(event.CreateEvent) bool { return true }
|
||||
func (UpdatedMetadataPredicate) Delete(event.DeleteEvent) bool { return true }
|
||||
func (UpdatedMetadataPredicate) Generic(event.GenericEvent) bool { return false }
|
||||
|
||||
func (UpdatedMetadataPredicate) Update(e event.UpdateEvent) bool {
|
||||
if e.ObjectOld == nil || e.ObjectNew == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if !utils.MapEqual(e.ObjectOld.GetLabels(), e.ObjectNew.GetLabels()) {
|
||||
return true
|
||||
}
|
||||
|
||||
return !utils.MapEqual(e.ObjectOld.GetAnnotations(), e.ObjectNew.GetAnnotations())
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright 2020-2026 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package predicates
|
||||
|
||||
func LabelsEqual(a, b map[string]string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for k, v := range a {
|
||||
if bv, ok := b[k]; !ok || bv != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func LabelsChanged(keys []string, oldLabels, newLabels map[string]string) bool {
|
||||
for _, key := range keys {
|
||||
oldVal, oldOK := oldLabels[key]
|
||||
newVal, newOK := newLabels[key]
|
||||
|
||||
if oldOK != newOK || oldVal != newVal {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
@@ -1,210 +0,0 @@
|
||||
// Copyright 2020-2026 Project Capsule Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package predicates_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/projectcapsule/capsule/pkg/runtime/predicates"
|
||||
)
|
||||
|
||||
func TestLabelsEqual(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type tc struct {
|
||||
name string
|
||||
a map[string]string
|
||||
b map[string]string
|
||||
want bool
|
||||
}
|
||||
|
||||
tests := []tc{
|
||||
{
|
||||
name: "both nil => equal",
|
||||
a: nil,
|
||||
b: nil,
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "nil vs empty => equal (len==0)",
|
||||
a: nil,
|
||||
b: map[string]string{},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "empty vs nil => equal (len==0)",
|
||||
a: map[string]string{},
|
||||
b: nil,
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "same single entry => equal",
|
||||
a: map[string]string{"a": "1"},
|
||||
b: map[string]string{"a": "1"},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "same entries different insertion order => equal",
|
||||
a: map[string]string{"a": "1", "b": "2"},
|
||||
b: map[string]string{"b": "2", "a": "1"},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "different lengths => not equal",
|
||||
a: map[string]string{"a": "1"},
|
||||
b: map[string]string{"a": "1", "b": "2"},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "missing key in b => not equal",
|
||||
a: map[string]string{"a": "1", "b": "2"},
|
||||
b: map[string]string{"a": "1", "c": "2"},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "same keys but different value => not equal",
|
||||
a: map[string]string{"a": "1"},
|
||||
b: map[string]string{"a": "2"},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "b has extra key (len differs) => not equal",
|
||||
a: map[string]string{"a": "1"},
|
||||
b: map[string]string{"a": "1", "x": "y"},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := predicates.LabelsEqual(tt.a, tt.b)
|
||||
if got != tt.want {
|
||||
t.Fatalf("LabelsEqual(%v, %v) = %v, want %v", tt.a, tt.b, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLabelsChanged(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type tc struct {
|
||||
name string
|
||||
keys []string
|
||||
oldLabels map[string]string
|
||||
newLabels map[string]string
|
||||
want bool
|
||||
}
|
||||
|
||||
tests := []tc{
|
||||
{
|
||||
name: "no keys => unchanged (false)",
|
||||
keys: nil,
|
||||
oldLabels: map[string]string{"a": "1"},
|
||||
newLabels: map[string]string{"a": "2"},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "key unchanged => false",
|
||||
keys: []string{"a"},
|
||||
oldLabels: map[string]string{"a": "1"},
|
||||
newLabels: map[string]string{"a": "1"},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "value changed => true",
|
||||
keys: []string{"a"},
|
||||
oldLabels: map[string]string{"a": "1"},
|
||||
newLabels: map[string]string{"a": "2"},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "key added => true",
|
||||
keys: []string{"a"},
|
||||
oldLabels: map[string]string{},
|
||||
newLabels: map[string]string{"a": "1"},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "key removed => true",
|
||||
keys: []string{"a"},
|
||||
oldLabels: map[string]string{"a": "1"},
|
||||
newLabels: map[string]string{},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "old nil new has key => true",
|
||||
keys: []string{"a"},
|
||||
oldLabels: nil,
|
||||
newLabels: map[string]string{"a": "1"},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "old has key new nil => true",
|
||||
keys: []string{"a"},
|
||||
oldLabels: map[string]string{"a": "1"},
|
||||
newLabels: nil,
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "both nil and key missing => false",
|
||||
keys: []string{"a"},
|
||||
oldLabels: nil,
|
||||
newLabels: nil,
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "multiple keys: one changed => true",
|
||||
keys: []string{"a", "b"},
|
||||
oldLabels: map[string]string{"a": "1", "b": "2"},
|
||||
newLabels: map[string]string{"a": "1", "b": "3"},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "multiple keys: only non-watched key changed => false",
|
||||
keys: []string{"a"},
|
||||
oldLabels: map[string]string{"a": "1", "x": "old"},
|
||||
newLabels: map[string]string{"a": "1", "x": "new"},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "watched key absent in both even if other keys differ => false",
|
||||
keys: []string{"a"},
|
||||
oldLabels: map[string]string{"x": "1"},
|
||||
newLabels: map[string]string{"x": "2"},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "duplicate keys in keys slice still behaves correctly",
|
||||
keys: []string{"a", "a"},
|
||||
oldLabels: map[string]string{"a": "1"},
|
||||
newLabels: map[string]string{"a": "1"},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "duplicate keys in keys slice with change => true",
|
||||
keys: []string{"a", "a"},
|
||||
oldLabels: map[string]string{"a": "1"},
|
||||
newLabels: map[string]string{"a": "2"},
|
||||
want: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := predicates.LabelsChanged(tt.keys, tt.oldLabels, tt.newLabels)
|
||||
if got != tt.want {
|
||||
t.Fatalf("LabelsChanged(keys=%v, old=%v, new=%v) = %v, want %v",
|
||||
tt.keys, tt.oldLabels, tt.newLabels, got, tt.want,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user