Skip to content

Commit 5f11806

Browse files
committed
add tests for WorkStatusController onAdd/onUpdate/onDelete
Signed-off-by: zach593 <[email protected]>
1 parent deeadfe commit 5f11806

File tree

1 file changed

+124
-14
lines changed

1 file changed

+124
-14
lines changed

pkg/controllers/status/work_status_controller_test.go

Lines changed: 124 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,19 @@ import (
2323
"testing"
2424
"time"
2525

26+
clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1"
27+
workv1alpha1 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha1"
28+
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
29+
"github.com/karmada-io/karmada/pkg/events"
30+
"github.com/karmada-io/karmada/pkg/resourceinterpreter/default/native"
31+
"github.com/karmada-io/karmada/pkg/sharedcli/ratelimiterflag"
32+
"github.com/karmada-io/karmada/pkg/util"
33+
"github.com/karmada-io/karmada/pkg/util/fedinformer/genericmanager"
34+
"github.com/karmada-io/karmada/pkg/util/fedinformer/keys"
35+
"github.com/karmada-io/karmada/pkg/util/gclient"
36+
"github.com/karmada-io/karmada/pkg/util/helper"
37+
"github.com/karmada-io/karmada/pkg/util/objectwatcher"
38+
testhelper "github.com/karmada-io/karmada/test/helper"
2639
"github.com/stretchr/testify/assert"
2740
corev1 "k8s.io/api/core/v1"
2841
rbacv1 "k8s.io/api/rbac/v1"
@@ -36,25 +49,12 @@ import (
3649
"k8s.io/apimachinery/pkg/util/uuid"
3750
dynamicfake "k8s.io/client-go/dynamic/fake"
3851
"k8s.io/client-go/kubernetes/scheme"
52+
"k8s.io/client-go/tools/cache"
3953
"k8s.io/client-go/tools/record"
4054
"k8s.io/utils/ptr"
4155
controllerruntime "sigs.k8s.io/controller-runtime"
4256
"sigs.k8s.io/controller-runtime/pkg/client"
4357
"sigs.k8s.io/controller-runtime/pkg/client/fake"
44-
45-
clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1"
46-
workv1alpha1 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha1"
47-
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
48-
"github.com/karmada-io/karmada/pkg/events"
49-
"github.com/karmada-io/karmada/pkg/resourceinterpreter/default/native"
50-
"github.com/karmada-io/karmada/pkg/sharedcli/ratelimiterflag"
51-
"github.com/karmada-io/karmada/pkg/util"
52-
"github.com/karmada-io/karmada/pkg/util/fedinformer/genericmanager"
53-
"github.com/karmada-io/karmada/pkg/util/fedinformer/keys"
54-
"github.com/karmada-io/karmada/pkg/util/gclient"
55-
"github.com/karmada-io/karmada/pkg/util/helper"
56-
"github.com/karmada-io/karmada/pkg/util/objectwatcher"
57-
testhelper "github.com/karmada-io/karmada/test/helper"
5858
)
5959

6060
func newCluster(name string, clusterType string, clusterStatus metav1.ConditionStatus) *clusterv1alpha1.Cluster {
@@ -1096,3 +1096,113 @@ func TestWorkStatusController_interpretHealth(t *testing.T) {
10961096
})
10971097
}
10981098
}
1099+
1100+
type TestObject struct {
1101+
metav1.TypeMeta
1102+
metav1.ObjectMeta
1103+
Spec string
1104+
}
1105+
1106+
func (in *TestObject) DeepCopyObject() runtime.Object {
1107+
return &TestObject{
1108+
TypeMeta: in.TypeMeta,
1109+
ObjectMeta: in.ObjectMeta,
1110+
Spec: in.Spec,
1111+
}
1112+
}
1113+
1114+
// mockAsyncWorker implements util.AsyncPriorityWorker for testing onAdd/onUpdate/onDelete behavior.
1115+
type mockAsyncWorker struct {
1116+
receivedObjs []any // objects passed via EnqueueWithOpts (onAdd)
1117+
receivedPriorities []*int // priorities captured from EnqueueWithOpts
1118+
enqueuedObjs []any // objects passed via Enqueue (onUpdate/onDelete)
1119+
}
1120+
1121+
func (m *mockAsyncWorker) EnqueueWithOpts(opts util.AddOpts, obj any) { // capture inputs for onAdd
1122+
m.receivedObjs = append(m.receivedObjs, obj)
1123+
m.receivedPriorities = append(m.receivedPriorities, opts.Priority)
1124+
}
1125+
func (m *mockAsyncWorker) AddWithOpts(_ util.AddOpts, _ ...any) {}
1126+
func (m *mockAsyncWorker) Add(_ interface{}) {}
1127+
func (m *mockAsyncWorker) AddAfter(_ interface{}, _ time.Duration) {}
1128+
func (m *mockAsyncWorker) Enqueue(obj interface{}) { // capture inputs for onUpdate/onDelete
1129+
m.enqueuedObjs = append(m.enqueuedObjs, obj)
1130+
}
1131+
func (m *mockAsyncWorker) Run(_ context.Context, _ int) {}
1132+
1133+
func TestWorkStatusController_onAdd(t *testing.T) {
1134+
cluster := newCluster("cluster", clusterv1alpha1.ClusterConditionReady, metav1.ConditionTrue)
1135+
c := newWorkStatusController(cluster)
1136+
mockWorker := &mockAsyncWorker{}
1137+
c.worker = mockWorker
1138+
1139+
obj := &TestObject{ObjectMeta: metav1.ObjectMeta{Name: "test-obj"}}
1140+
1141+
t.Run("in initial list -> low priority", func(t *testing.T) {
1142+
c.onAdd(obj, true)
1143+
assert.Equal(t, 1, len(mockWorker.receivedObjs))
1144+
assert.Equal(t, obj, mockWorker.receivedObjs[0])
1145+
if assert.NotNil(t, mockWorker.receivedPriorities[0]) {
1146+
assert.Equal(t, util.LowPriority, *mockWorker.receivedPriorities[0])
1147+
}
1148+
})
1149+
1150+
t.Run("not in initial list -> nil priority", func(t *testing.T) {
1151+
c.onAdd(obj, false)
1152+
assert.Equal(t, 2, len(mockWorker.receivedObjs))
1153+
assert.Equal(t, obj, mockWorker.receivedObjs[1])
1154+
assert.Nil(t, mockWorker.receivedPriorities[1])
1155+
})
1156+
}
1157+
1158+
func TestWorkStatusController_onUpdate(t *testing.T) {
1159+
cluster := newCluster("cluster", clusterv1alpha1.ClusterConditionReady, metav1.ConditionTrue)
1160+
c := newWorkStatusController(cluster)
1161+
mockWorker := &mockAsyncWorker{}
1162+
c.worker = mockWorker
1163+
1164+
oldObj := &TestObject{ObjectMeta: metav1.ObjectMeta{Name: "test-obj"}, Spec: "same"}
1165+
// Deep copy same content
1166+
curSame := oldObj.DeepCopyObject().(*TestObject)
1167+
// Different spec
1168+
curDiff := &TestObject{ObjectMeta: metav1.ObjectMeta{Name: "test-obj"}, Spec: "different"}
1169+
1170+
t.Run("objects equal -> no enqueue", func(t *testing.T) {
1171+
c.onUpdate(oldObj, curSame)
1172+
assert.Equal(t, 0, len(mockWorker.enqueuedObjs))
1173+
})
1174+
1175+
t.Run("objects differ -> enqueue", func(t *testing.T) {
1176+
c.onUpdate(oldObj, curDiff)
1177+
assert.Equal(t, 1, len(mockWorker.enqueuedObjs))
1178+
assert.Equal(t, curDiff, mockWorker.enqueuedObjs[0])
1179+
})
1180+
}
1181+
1182+
func TestWorkStatusController_onDelete(t *testing.T) {
1183+
cluster := newCluster("cluster", clusterv1alpha1.ClusterConditionReady, metav1.ConditionTrue)
1184+
c := newWorkStatusController(cluster)
1185+
mockWorker := &mockAsyncWorker{}
1186+
c.worker = mockWorker
1187+
1188+
obj := &TestObject{ObjectMeta: metav1.ObjectMeta{Name: "to-delete"}}
1189+
1190+
t.Run("direct object -> enqueue", func(t *testing.T) {
1191+
c.onDelete(obj)
1192+
assert.Equal(t, 1, len(mockWorker.enqueuedObjs))
1193+
assert.Equal(t, obj, mockWorker.enqueuedObjs[0])
1194+
})
1195+
1196+
t.Run("DeletedFinalStateUnknown wrapper -> enqueue", func(t *testing.T) {
1197+
wrapped := cache.DeletedFinalStateUnknown{Obj: &TestObject{ObjectMeta: metav1.ObjectMeta{Name: "wrapped"}}}
1198+
c.onDelete(wrapped)
1199+
assert.Equal(t, 2, len(mockWorker.enqueuedObjs))
1200+
assert.Equal(t, "wrapped", mockWorker.enqueuedObjs[1].(*TestObject).Name)
1201+
})
1202+
1203+
t.Run("DeletedFinalStateUnknown with nil Obj -> no additional enqueue", func(t *testing.T) {
1204+
wrappedNil := cache.DeletedFinalStateUnknown{Obj: nil}
1205+
c.onDelete(wrappedNil)
1206+
assert.Equal(t, 2, len(mockWorker.enqueuedObjs)) // unchanged
1207+
})
1208+
}

0 commit comments

Comments
 (0)