Skip to content

Commit 8786810

Browse files
committed
add ut for node selector
Signed-off-by: bingshen.wbs <[email protected]>
1 parent 9fb9928 commit 8786810

File tree

3 files changed

+220
-19
lines changed

3 files changed

+220
-19
lines changed

cmd/controller/main.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,10 @@ func main() {
169169
}
170170

171171
if err = (&controller.NodeReconciler{
172-
Client: mgr.GetClient(),
173-
Scheme: mgr.GetScheme(),
174-
EriClient: eriClient,
172+
Client: mgr.GetClient(),
173+
Scheme: mgr.GetScheme(),
174+
EriClient: eriClient,
175+
CtrlConfig: config.GetConfig(),
175176
}).SetupWithManager(mgr); err != nil {
176177
setupLog.Error(err, "unable to create controller", "controller", "Node")
177178
os.Exit(1)

internal/controller/node_controller.go

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"time"
66

7-
"github.com/AliyunContainerService/alibabacloud-erdma-controller/internal/config"
87
"github.com/AliyunContainerService/alibabacloud-erdma-controller/internal/types"
98
"github.com/samber/lo"
109
k8stypes "k8s.io/apimachinery/pkg/types"
@@ -34,8 +33,9 @@ const (
3433
// NodeReconciler reconciles a ERdmaDevice object
3534
type NodeReconciler struct {
3635
client.Client
37-
Scheme *runtime.Scheme
38-
EriClient *EriClient
36+
Scheme *runtime.Scheme
37+
EriClient *EriClient
38+
CtrlConfig *types.Config
3939
}
4040

4141
// +kubebuilder:rbac:groups=network.alibabacloud.com,resources=erdmadevices,verbs=get;list;watch;create;update;patch;delete
@@ -178,14 +178,29 @@ func (r *NodeReconciler) OwnNode(node *v1.Node) bool {
178178
if node == nil {
179179
return false
180180
}
181-
for k, v := range config.GetConfig().NodeSelector {
181+
for k, v := range r.CtrlConfig.NodeSelector {
182182
if node.Labels[k] != v {
183183
return false
184184
}
185185
}
186186
return true
187187
}
188188

189+
func (r *NodeReconciler) PredictNodeUpdate(oldNode, newNode *v1.Node) bool {
190+
if !r.OwnNode(newNode) {
191+
return false
192+
}
193+
if !r.OwnNode(oldNode) && r.OwnNode(newNode) {
194+
return true
195+
}
196+
197+
if newNode.DeletionTimestamp != nil {
198+
return true
199+
}
200+
201+
return oldNode.Spec.ProviderID != newNode.Spec.ProviderID
202+
}
203+
189204
// SetupWithManager sets up the controller with the Manager.
190205
func (r *NodeReconciler) SetupWithManager(mgr ctrl.Manager) error {
191206
pred := predicate.TypedFuncs[*v1.Node]{
@@ -196,18 +211,7 @@ func (r *NodeReconciler) SetupWithManager(mgr ctrl.Manager) error {
196211
return r.OwnNode(e.Object)
197212
},
198213
UpdateFunc: func(e event.TypedUpdateEvent[*v1.Node]) bool {
199-
if !r.OwnNode(e.ObjectNew) {
200-
return false
201-
}
202-
if !r.OwnNode(e.ObjectOld) && r.OwnNode(e.ObjectNew) {
203-
return true
204-
}
205-
206-
if e.ObjectNew.DeletionTimestamp != nil {
207-
return true
208-
}
209-
210-
return e.ObjectOld.Spec.ProviderID != e.ObjectNew.Spec.ProviderID
214+
return r.PredictNodeUpdate(e.ObjectOld, e.ObjectNew)
211215
},
212216
GenericFunc: func(e event.TypedGenericEvent[*v1.Node]) bool {
213217
return r.OwnNode(e.Object)
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
package controller
2+
3+
import (
4+
"testing"
5+
6+
"github.com/AliyunContainerService/alibabacloud-erdma-controller/internal/types"
7+
8+
v1 "k8s.io/api/core/v1"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
)
11+
12+
func TestNodeReconciler_OwnNode(t *testing.T) {
13+
testcases := []struct {
14+
name string
15+
selector map[string]string
16+
node *v1.Node
17+
expected bool
18+
}{
19+
{
20+
name: "node is nil",
21+
selector: nil,
22+
node: nil,
23+
expected: false,
24+
},
25+
{
26+
name: "selector all nodes",
27+
selector: nil,
28+
node: &v1.Node{
29+
ObjectMeta: metav1.ObjectMeta{
30+
Labels: map[string]string{
31+
"kubernetes.io/nodename": "cn-hangzhou.1.1.1.1",
32+
},
33+
},
34+
},
35+
expected: true,
36+
},
37+
{
38+
name: "selector match",
39+
selector: map[string]string{
40+
"selector1": "value1",
41+
},
42+
node: &v1.Node{
43+
ObjectMeta: metav1.ObjectMeta{
44+
Labels: map[string]string{
45+
"kubernetes.io/nodename": "cn-hangzhou.1.1.1.1",
46+
"selector1": "value1",
47+
},
48+
},
49+
},
50+
expected: true,
51+
},
52+
{
53+
name: "selector partial match",
54+
selector: map[string]string{
55+
"selector1": "value1",
56+
"selector2": "value2",
57+
},
58+
node: &v1.Node{
59+
ObjectMeta: metav1.ObjectMeta{
60+
Labels: map[string]string{
61+
"kubernetes.io/nodename": "cn-hangzhou.1.1.1.1",
62+
"selector1": "value1",
63+
},
64+
},
65+
},
66+
expected: false,
67+
},
68+
}
69+
for _, tc := range testcases {
70+
t.Run(tc.name, func(t *testing.T) {
71+
r := &NodeReconciler{
72+
CtrlConfig: &types.Config{
73+
NodeSelector: tc.selector,
74+
},
75+
}
76+
result := r.OwnNode(tc.node)
77+
if result != tc.expected {
78+
t.Errorf("expected %v, but got %v", tc.expected, result)
79+
}
80+
})
81+
}
82+
}
83+
84+
func TestPredictNodeUpdate(t *testing.T) {
85+
tests := []struct {
86+
name string
87+
oldNode *v1.Node
88+
newNode *v1.Node
89+
expected bool
90+
}{
91+
{
92+
name: "New node not owned",
93+
oldNode: &v1.Node{
94+
ObjectMeta: metav1.ObjectMeta{
95+
Name: "node1",
96+
Labels: map[string]string{
97+
"test-key": "test-value",
98+
},
99+
},
100+
},
101+
newNode: &v1.Node{
102+
ObjectMeta: metav1.ObjectMeta{
103+
Name: "node1",
104+
Labels: map[string]string{
105+
"test-key": "different-value",
106+
},
107+
},
108+
},
109+
expected: false,
110+
},
111+
{
112+
name: "Old node not owned, new node owned",
113+
oldNode: &v1.Node{
114+
ObjectMeta: metav1.ObjectMeta{
115+
Name: "node1",
116+
Labels: map[string]string{
117+
"test-key": "not-owned",
118+
},
119+
},
120+
},
121+
newNode: &v1.Node{
122+
ObjectMeta: metav1.ObjectMeta{
123+
Name: "node1",
124+
Labels: map[string]string{
125+
"test-key": "test-value",
126+
},
127+
},
128+
},
129+
expected: true,
130+
},
131+
{
132+
name: "Node with deletion timestamp",
133+
oldNode: &v1.Node{
134+
ObjectMeta: metav1.ObjectMeta{
135+
Name: "node1",
136+
Labels: map[string]string{
137+
"test-key": "test-value",
138+
},
139+
},
140+
},
141+
newNode: &v1.Node{
142+
ObjectMeta: metav1.ObjectMeta{
143+
Name: "node1",
144+
DeletionTimestamp: &metav1.Time{},
145+
Labels: map[string]string{
146+
"test-key": "test-value",
147+
},
148+
},
149+
},
150+
expected: true,
151+
},
152+
{
153+
name: "ProviderID changed",
154+
oldNode: &v1.Node{
155+
ObjectMeta: metav1.ObjectMeta{
156+
Name: "node1",
157+
Labels: map[string]string{
158+
"test-key": "test-value",
159+
},
160+
},
161+
Spec: v1.NodeSpec{
162+
ProviderID: "old-provider-id",
163+
},
164+
},
165+
newNode: &v1.Node{
166+
ObjectMeta: metav1.ObjectMeta{
167+
Name: "node1",
168+
Labels: map[string]string{
169+
"test-key": "test-value",
170+
},
171+
},
172+
Spec: v1.NodeSpec{
173+
ProviderID: "new-provider-id",
174+
},
175+
},
176+
expected: true,
177+
},
178+
}
179+
180+
reconciler := &NodeReconciler{
181+
CtrlConfig: &types.Config{
182+
NodeSelector: map[string]string{
183+
"test-key": "test-value",
184+
},
185+
},
186+
}
187+
188+
for _, tt := range tests {
189+
t.Run(tt.name, func(t *testing.T) {
190+
result := reconciler.PredictNodeUpdate(tt.oldNode, tt.newNode)
191+
if result != tt.expected {
192+
t.Errorf("PredictNodeUpdate() = %v, expected %v", result, tt.expected)
193+
}
194+
})
195+
}
196+
}

0 commit comments

Comments
 (0)