Skip to content
This repository was archived by the owner on Jan 29, 2025. It is now read-only.

Commit a451073

Browse files
togashidmuniemimu
authored andcommitted
Add unit test cases for unlabelling nodes
When a deschedule policy is deleted the violating nodes that were labeled as "violating" need to be removed. New unit test cases are created to test the issue and also testt the capability of the node being relabelled, after policy deletion.
1 parent b81ccd7 commit a451073

File tree

4 files changed

+157
-6
lines changed

4 files changed

+157
-6
lines changed

telemetry-aware-scheduling/pkg/strategies/core/enforcer.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func (e *MetricEnforcer) RemoveStrategy(str Interface, strategyType string) {
7474
if enf, ok := str.(Enforceable); ok {
7575
err := enf.Cleanup(e, str.GetPolicyName())
7676
if err != nil {
77-
msg := fmt.Sprintf("cleaning up the strategy failed: %v", err)
77+
msg := fmt.Sprintf("Failed to remove strategy: %v", err)
7878
klog.V(2).InfoS(msg, "component", "controller")
7979
}
8080
}
@@ -121,7 +121,7 @@ func (e *MetricEnforcer) enforceStrategy(strategyType string, cache cache.Reader
121121
if enf, ok := str.(Enforceable); ok {
122122
_, err := enf.Enforce(e, cache)
123123
if err != nil {
124-
msg := fmt.Sprintf("Enforce the strategy failed: %v", err)
124+
msg := fmt.Sprintf("Strategy was not enforceable: %v", err)
125125
klog.V(2).InfoS(msg, "component", "controller")
126126
}
127127
}

telemetry-aware-scheduling/pkg/strategies/core/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type Interface interface {
1616
GetPolicyName() string
1717
SetPolicyName(string)
1818
}
19+
1920
//Enforceable enforce strategies and clean up after strategies are removed
2021
type Enforceable interface {
2122
Enforce(enforcer *MetricEnforcer, cache cache.Reader) (int, error)
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package deschedule
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"testing"
7+
8+
"k8s.io/klog/v2"
9+
10+
strategy "github.com/intel/platform-aware-scheduling/telemetry-aware-scheduling/pkg/strategies/core"
11+
v1 "k8s.io/api/core/v1"
12+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13+
testclient "k8s.io/client-go/kubernetes/fake"
14+
_ "k8s.io/client-go/plugin/pkg/client/auth"
15+
)
16+
17+
type args struct {
18+
enforcer *strategy.MetricEnforcer
19+
}
20+
21+
type testItemStruct struct {
22+
name string
23+
d *Strategy
24+
nodes []*v1.Node
25+
args args
26+
want []string
27+
}
28+
29+
type testStruc []testItemStruct
30+
31+
func TestDeschedule_Cleanup(t *testing.T) {
32+
var tests = testStruc{
33+
//This test labels node-1 as 'violating'. The labels should be removed after policy deletion.
34+
{name: "one node as 'violating'",
35+
d: &Strategy{PolicyName: "deschedule-test"},
36+
nodes: []*v1.Node{nodeSpec("deschedule-test", "node-1", "violating"),
37+
nodeSpec("deschedule-test", "node-2", "null")},
38+
args: args{enforcer: strategy.NewEnforcer(testclient.NewSimpleClientset())},
39+
want: []string{}},
40+
//This test labels node-1 and node-2 as 'violating'. The labels should be removed after policy deletion.
41+
{name: "multiple nodes as 'violating'",
42+
d: &Strategy{PolicyName: "deschedule-test"},
43+
nodes: []*v1.Node{nodeSpec("deschedule-test", "node-1", "violating"),
44+
nodeSpec("deschedule-test", "node-2", "violating")},
45+
args: args{enforcer: strategy.NewEnforcer(testclient.NewSimpleClientset())},
46+
want: []string{}},
47+
//In this test node-1 and node-2 are unlabeled. No labels should be added after policy deletion.
48+
{name: "multiple nodes",
49+
d: &Strategy{PolicyName: "deschedule-test"},
50+
nodes: []*v1.Node{nodeSpec("deschedule-test", "node-1", ""),
51+
nodeSpec("deschedule-test", "node-2", "")},
52+
args: args{enforcer: strategy.NewEnforcer(testclient.NewSimpleClientset())},
53+
want: []string{}},
54+
}
55+
for _, tt := range tests {
56+
nodeAction(t, tt, "create")
57+
t.Run(tt.name, func(t *testing.T) {
58+
err := tt.d.Cleanup(tt.args.enforcer, tt.d.PolicyName) //testing Cleanup()
59+
if err != nil {
60+
klog.InfoS(err.Error(), "component", "testing")
61+
}
62+
nodys, _ := tt.args.enforcer.KubeClient.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{LabelSelector: "deschedule-test=violating"})
63+
msg := fmt.Sprint(nodys.Items)
64+
klog.InfoS(msg, "component", "testing")
65+
if len(nodys.Items) != len(tt.want) {
66+
t.Errorf("Number of labelled nodes: %v. Expected %v - Test failed", len(nodys.Items), len(tt.want))
67+
}
68+
})
69+
nodeAction(t, tt, "delete")
70+
}
71+
}
72+
73+
func TestDeschedule_Relabel_nodes(t *testing.T) {
74+
var tests = testStruc{
75+
//This test will relabel node-1 as 'violating' after being removed by policy deletion.
76+
{name: "one node as 'violating'",
77+
d: &Strategy{PolicyName: "deschedule-test"},
78+
nodes: []*v1.Node{nodeSpec("deschedule-test", "node-1", "violating"),
79+
nodeSpec("deschedule-test", "node-2", "null")},
80+
args: args{enforcer: strategy.NewEnforcer(testclient.NewSimpleClientset())},
81+
want: []string{"violating"}},
82+
//This test will relabel node-1 and node-2 as 'violating' after being removed by policy deletion.
83+
{name: "multiple nodes as 'violating'",
84+
d: &Strategy{PolicyName: "deschedule-test"},
85+
nodes: []*v1.Node{nodeSpec("deschedule-test", "node-1", "violating"),
86+
nodeSpec("deschedule-test", "node-2", "violating")},
87+
args: args{enforcer: strategy.NewEnforcer(testclient.NewSimpleClientset())},
88+
want: []string{"violating", "violating"}},
89+
}
90+
for _, tt := range tests {
91+
nodeAction(t, tt, "create")
92+
t.Run(tt.name, func(t *testing.T) {
93+
err := tt.d.Cleanup(tt.args.enforcer, tt.d.PolicyName) //testing Cleanup()
94+
if err != nil {
95+
klog.InfoS(err.Error(), "component", "testing")
96+
}
97+
nodeAction(t, tt, "update")
98+
nodys, _ := tt.args.enforcer.KubeClient.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{LabelSelector: "deschedule-test=violating"})
99+
msg := fmt.Sprint(nodys.Items)
100+
klog.InfoS(msg, "component", "testing")
101+
if len(nodys.Items) != len(tt.want) {
102+
t.Errorf("Number of labelled nodes: %v. Expected %v - Test failed", len(nodys.Items), len(tt.want))
103+
}
104+
for n := range tt.want {
105+
label := nodys.Items[n].Labels[tt.d.PolicyName]
106+
if label != tt.want[n] {
107+
t.Errorf("Wrong label: %v. Expected %v - Test failed", len(nodys.Items), tt.want[n])
108+
}
109+
}
110+
})
111+
nodeAction(t, tt, "delete")
112+
}
113+
}
114+
115+
func nodeSpec(policyName string, name string, value string) *v1.Node {
116+
return &v1.Node{ObjectMeta: metav1.ObjectMeta{
117+
Name: name,
118+
Labels: map[string]string{policyName: value}}}
119+
}
120+
121+
func nodeAction(t *testing.T, testItem testItemStruct, action string) {
122+
for n := range testItem.nodes {
123+
switch action {
124+
case "create":
125+
_, err := testItem.args.enforcer.KubeClient.CoreV1().Nodes().Create(context.TODO(), testItem.nodes[n], metav1.CreateOptions{})
126+
if err != nil {
127+
t.Errorf("Cannot %v nodes correctly: %v", action, err)
128+
}
129+
msg := fmt.Sprintf("Labelling %v with %v", testItem.nodes[n].Name, testItem.nodes[n].Labels[testItem.d.PolicyName])
130+
klog.InfoS(msg, "component", "testing")
131+
case "update":
132+
_, err := testItem.args.enforcer.KubeClient.CoreV1().Nodes().Update(context.TODO(), testItem.nodes[n], metav1.UpdateOptions{})
133+
if err != nil {
134+
t.Errorf("Cannot %v nodes correctly: %v", action, err)
135+
}
136+
msg := fmt.Sprintf("Labelling %v with %v", testItem.nodes[n].Name, testItem.nodes[n].Labels[testItem.d.PolicyName])
137+
klog.InfoS(msg, "component", "testing")
138+
case "delete":
139+
err := testItem.args.enforcer.KubeClient.CoreV1().Nodes().Delete(context.TODO(), testItem.nodes[n].Name, metav1.DeleteOptions{})
140+
if err != nil {
141+
t.Errorf("Cannot %v nodes correctly: %v", action, err)
142+
}
143+
klog.InfoS("Nodes deleted", "component", "testing")
144+
default:
145+
klog.Fatal("not right action for node request")
146+
}
147+
}
148+
}

telemetry-aware-scheduling/pkg/strategies/deschedule/enforce.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66
"errors"
77
"fmt"
8+
89
"k8s.io/apimachinery/pkg/labels"
910

1011
"github.com/intel/platform-aware-scheduling/telemetry-aware-scheduling/pkg/cache"
@@ -22,6 +23,7 @@ type patchValue struct {
2223
Path string `json:"path"`
2324
Value string `json:"value"`
2425
}
26+
2527
//Cleanup remove node labels for violating when policy is deleted
2628
func (d *Strategy) Cleanup(enforcer *strategy.MetricEnforcer, policyName string) error {
2729
lbls := metav1.LabelSelector{MatchLabels: map[string]string{policyName: "violating"}}
@@ -41,11 +43,11 @@ func (d *Strategy) Cleanup(enforcer *strategy.MetricEnforcer, policyName string)
4143
})
4244
}
4345
err := d.patchNode(node.Name, enforcer, payload)
44-
if err != nil {
45-
klog.V(2).InfoS(err.Error(), "component", "controller")
46-
}
46+
if err != nil {
47+
klog.V(2).InfoS(err.Error(), "component", "controller")
48+
}
4749
}
48-
klog.V(2).InfoS(fmt.Sprintf("Unlabel node that was violating the policy %v", policyName),"component", "controller")
50+
klog.V(2).InfoS(fmt.Sprintf("Remove the node label on policy %v deletion", policyName), "component", "controller")
4951
return nil
5052
}
5153

0 commit comments

Comments
 (0)