@@ -11,122 +11,209 @@ import (
11
11
v1 "k8s.io/api/core/v1"
12
12
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13
13
"k8s.io/apimachinery/pkg/labels"
14
+ "k8s.io/apimachinery/pkg/runtime"
15
+ "k8s.io/apimachinery/pkg/util/sets"
14
16
"k8s.io/apimachinery/pkg/util/wait"
15
17
clientset "k8s.io/client-go/kubernetes"
16
18
componentbaseconfig "k8s.io/component-base/config"
17
19
utilptr "k8s.io/utils/ptr"
18
20
21
+ "sigs.k8s.io/descheduler/pkg/api"
22
+ apiv1alpha2 "sigs.k8s.io/descheduler/pkg/api/v1alpha2"
19
23
"sigs.k8s.io/descheduler/pkg/descheduler/client"
20
- "sigs.k8s.io/descheduler/pkg/descheduler/evictions"
21
- eutils "sigs.k8s.io/descheduler/pkg/descheduler/evictions/utils"
22
24
"sigs.k8s.io/descheduler/pkg/framework/plugins/defaultevictor"
23
25
"sigs.k8s.io/descheduler/pkg/framework/plugins/removefailedpods"
24
- frameworktesting "sigs.k8s.io/descheduler/pkg/framework/testing"
25
- frameworktypes "sigs.k8s.io/descheduler/pkg/framework/types"
26
26
)
27
27
28
- var oneHourPodLifetimeSeconds uint = 3600
28
+ var (
29
+ oneHourPodLifetimeSeconds uint = 3600
30
+ oneSecondPodLifetimeSeconds uint = 1
31
+ )
32
+
33
+ func removeFailedPodsPolicy (removeFailedPodsArgs * removefailedpods.RemoveFailedPodsArgs , evictorArgs * defaultevictor.DefaultEvictorArgs ) * apiv1alpha2.DeschedulerPolicy {
34
+ return & apiv1alpha2.DeschedulerPolicy {
35
+ Profiles : []apiv1alpha2.DeschedulerProfile {
36
+ {
37
+ Name : removefailedpods .PluginName + "Profile" ,
38
+ PluginConfigs : []apiv1alpha2.PluginConfig {
39
+ {
40
+ Name : removefailedpods .PluginName ,
41
+ Args : runtime.RawExtension {
42
+ Object : removeFailedPodsArgs ,
43
+ },
44
+ },
45
+ {
46
+ Name : defaultevictor .PluginName ,
47
+ Args : runtime.RawExtension {
48
+ Object : evictorArgs ,
49
+ },
50
+ },
51
+ },
52
+ Plugins : apiv1alpha2.Plugins {
53
+ Filter : apiv1alpha2.PluginSet {
54
+ Enabled : []string {
55
+ defaultevictor .PluginName ,
56
+ },
57
+ },
58
+ Deschedule : apiv1alpha2.PluginSet {
59
+ Enabled : []string {
60
+ removefailedpods .PluginName ,
61
+ },
62
+ },
63
+ },
64
+ },
65
+ },
66
+ }
67
+ }
29
68
30
69
func TestFailedPods (t * testing.T ) {
31
70
ctx := context .Background ()
32
71
33
72
clientSet , err := client .CreateClient (componentbaseconfig.ClientConnectionConfiguration {Kubeconfig : os .Getenv ("KUBECONFIG" )}, "" )
34
73
if err != nil {
35
- t .Errorf ("Error during client creation with %v" , err )
74
+ t .Errorf ("Error during kubernetes client creation with %v" , err )
36
75
}
37
76
38
- nodeList , err := clientSet .CoreV1 ().Nodes ().List (ctx , metav1.ListOptions {})
39
- if err != nil {
40
- t .Errorf ("Error listing node with %v" , err )
41
- }
42
- nodes , _ := splitNodesAndWorkerNodes (nodeList .Items )
43
77
t .Log ("Creating testing namespace" )
44
78
testNamespace := & v1.Namespace {ObjectMeta : metav1.ObjectMeta {Name : "e2e-" + strings .ToLower (t .Name ())}}
45
79
if _ , err := clientSet .CoreV1 ().Namespaces ().Create (ctx , testNamespace , metav1.CreateOptions {}); err != nil {
46
80
t .Fatalf ("Unable to create ns %v" , testNamespace .Name )
47
81
}
48
82
defer clientSet .CoreV1 ().Namespaces ().Delete (ctx , testNamespace .Name , metav1.DeleteOptions {})
49
- testCases := map [string ]struct {
50
- expectedEvictedCount uint
51
- args * removefailedpods.RemoveFailedPodsArgs
83
+
84
+ tests := []struct {
85
+ name string
86
+ expectedEvictedPodCount int
87
+ removeFailedPodsArgs * removefailedpods.RemoveFailedPodsArgs
52
88
}{
53
- "test-failed-pods-default-args" : {
54
- expectedEvictedCount : 1 ,
55
- args : & removefailedpods.RemoveFailedPodsArgs {},
89
+ {
90
+ name : "test-failed-pods-default-args" ,
91
+ expectedEvictedPodCount : 1 ,
92
+ removeFailedPodsArgs : & removefailedpods.RemoveFailedPodsArgs {
93
+ MinPodLifetimeSeconds : & oneSecondPodLifetimeSeconds ,
94
+ },
56
95
},
57
- "test-failed-pods-reason-unmatched" : {
58
- expectedEvictedCount : 0 ,
59
- args : & removefailedpods.RemoveFailedPodsArgs {
60
- Reasons : []string {"ReasonDoesNotMatch" },
96
+ {
97
+ name : "test-failed-pods-reason-unmatched" ,
98
+ expectedEvictedPodCount : 0 ,
99
+ removeFailedPodsArgs : & removefailedpods.RemoveFailedPodsArgs {
100
+ Reasons : []string {"ReasonDoesNotMatch" },
101
+ MinPodLifetimeSeconds : & oneSecondPodLifetimeSeconds ,
61
102
},
62
103
},
63
- "test-failed-pods-min-age-unmet" : {
64
- expectedEvictedCount : 0 ,
65
- args : & removefailedpods.RemoveFailedPodsArgs {
104
+ {
105
+ name : "test-failed-pods-min-age-unmet" ,
106
+ expectedEvictedPodCount : 0 ,
107
+ removeFailedPodsArgs : & removefailedpods.RemoveFailedPodsArgs {
66
108
MinPodLifetimeSeconds : & oneHourPodLifetimeSeconds ,
67
109
},
68
110
},
69
- "test-failed-pods-exclude-job-kind" : {
70
- expectedEvictedCount : 0 ,
71
- args : & removefailedpods.RemoveFailedPodsArgs {
72
- ExcludeOwnerKinds : []string {"Job" },
111
+ {
112
+ name : "test-failed-pods-exclude-job-kind" ,
113
+ expectedEvictedPodCount : 0 ,
114
+ removeFailedPodsArgs : & removefailedpods.RemoveFailedPodsArgs {
115
+ ExcludeOwnerKinds : []string {"Job" },
116
+ MinPodLifetimeSeconds : & oneSecondPodLifetimeSeconds ,
73
117
},
74
118
},
75
119
}
76
- for name , tc := range testCases {
77
- t .Run (name , func (t * testing.T ) {
78
- job := initFailedJob (name , testNamespace .Namespace )
120
+ for _ , tc := range tests {
121
+ t .Run (tc . name , func (t * testing.T ) {
122
+ job := initFailedJob (tc . name , testNamespace .Namespace )
79
123
t .Logf ("Creating job %s in %s namespace" , job .Name , job .Namespace )
80
124
jobClient := clientSet .BatchV1 ().Jobs (testNamespace .Name )
81
125
if _ , err := jobClient .Create (ctx , job , metav1.CreateOptions {}); err != nil {
82
- t .Fatalf ("Error creating Job %s: %v" , name , err )
126
+ t .Fatalf ("Error creating Job %s: %v" , tc . name , err )
83
127
}
84
128
deletePropagationPolicy := metav1 .DeletePropagationForeground
85
- defer jobClient .Delete (ctx , job .Name , metav1.DeleteOptions {PropagationPolicy : & deletePropagationPolicy })
129
+ defer func () {
130
+ jobClient .Delete (ctx , job .Name , metav1.DeleteOptions {PropagationPolicy : & deletePropagationPolicy })
131
+ waitForPodsToDisappear (ctx , t , clientSet , job .Labels , job .Namespace )
132
+ }()
86
133
waitForJobPodPhase (ctx , t , clientSet , job , v1 .PodFailed )
87
134
88
- evictionPolicyGroupVersion , err := eutils .SupportEviction (clientSet )
89
- if err != nil || len (evictionPolicyGroupVersion ) == 0 {
90
- t .Fatalf ("Error detecting eviction policy group: %v" , err )
135
+ preRunNames := sets .NewString (getCurrentPodNames (ctx , clientSet , testNamespace .Name , t )... )
136
+
137
+ // Deploy the descheduler with the configured policy
138
+ evictorArgs := & defaultevictor.DefaultEvictorArgs {
139
+ EvictLocalStoragePods : true ,
140
+ EvictSystemCriticalPods : false ,
141
+ IgnorePvcPods : false ,
142
+ EvictFailedBarePods : false ,
143
+ }
144
+ tc .removeFailedPodsArgs .Namespaces = & api.Namespaces {
145
+ Include : []string {testNamespace .Name },
91
146
}
92
147
93
- handle , podEvictor , err := frameworktesting .InitFrameworkHandle (
94
- ctx ,
95
- clientSet ,
96
- evictions .NewOptions ().
97
- WithPolicyGroupVersion (evictionPolicyGroupVersion ),
98
- defaultevictor.DefaultEvictorArgs {
99
- EvictLocalStoragePods : true ,
100
- },
101
- nil ,
102
- )
148
+ deschedulerPolicyConfigMapObj , err := deschedulerPolicyConfigMap (removeFailedPodsPolicy (tc .removeFailedPodsArgs , evictorArgs ))
103
149
if err != nil {
104
- t .Fatalf ("Unable to initialize a framework handle : %v" , err )
150
+ t .Fatalf ("Error creating %q CM : %v" , deschedulerPolicyConfigMapObj . Name , err )
105
151
}
106
152
107
- t .Logf ("Running RemoveFailedPods strategy for %s" , name )
153
+ t .Logf ("Creating %q policy CM with RemoveDuplicates configured..." , deschedulerPolicyConfigMapObj .Name )
154
+ _ , err = clientSet .CoreV1 ().ConfigMaps (deschedulerPolicyConfigMapObj .Namespace ).Create (ctx , deschedulerPolicyConfigMapObj , metav1.CreateOptions {})
155
+ if err != nil {
156
+ t .Fatalf ("Error creating %q CM: %v" , deschedulerPolicyConfigMapObj .Name , err )
157
+ }
108
158
109
- plugin , err := removefailedpods .New (& removefailedpods.RemoveFailedPodsArgs {
110
- Reasons : tc .args .Reasons ,
111
- MinPodLifetimeSeconds : tc .args .MinPodLifetimeSeconds ,
112
- IncludingInitContainers : tc .args .IncludingInitContainers ,
113
- ExcludeOwnerKinds : tc .args .ExcludeOwnerKinds ,
114
- LabelSelector : tc .args .LabelSelector ,
115
- Namespaces : tc .args .Namespaces ,
116
- },
117
- handle ,
118
- )
159
+ defer func () {
160
+ t .Logf ("Deleting %q CM..." , deschedulerPolicyConfigMapObj .Name )
161
+ err = clientSet .CoreV1 ().ConfigMaps (deschedulerPolicyConfigMapObj .Namespace ).Delete (ctx , deschedulerPolicyConfigMapObj .Name , metav1.DeleteOptions {})
162
+ if err != nil {
163
+ t .Fatalf ("Unable to delete %q CM: %v" , deschedulerPolicyConfigMapObj .Name , err )
164
+ }
165
+ }()
166
+
167
+ deschedulerDeploymentObj := deschedulerDeployment (testNamespace .Name )
168
+ t .Logf ("Creating descheduler deployment %v" , deschedulerDeploymentObj .Name )
169
+ _ , err = clientSet .AppsV1 ().Deployments (deschedulerDeploymentObj .Namespace ).Create (ctx , deschedulerDeploymentObj , metav1.CreateOptions {})
119
170
if err != nil {
120
- t .Fatalf ("Unable to initialize the plugin : %v" , err )
171
+ t .Fatalf ("Error creating %q deployment : %v" , deschedulerDeploymentObj . Name , err )
121
172
}
122
173
123
- plugin .(frameworktypes.DeschedulePlugin ).Deschedule (ctx , nodes )
124
- t .Logf ("Finished RemoveFailedPods strategy for %s" , name )
174
+ deschedulerPodName := ""
175
+ defer func () {
176
+ if deschedulerPodName != "" {
177
+ printPodLogs (ctx , t , clientSet , deschedulerPodName )
178
+ }
179
+
180
+ t .Logf ("Deleting %q deployment..." , deschedulerDeploymentObj .Name )
181
+ err = clientSet .AppsV1 ().Deployments (deschedulerDeploymentObj .Namespace ).Delete (ctx , deschedulerDeploymentObj .Name , metav1.DeleteOptions {})
182
+ if err != nil {
183
+ t .Fatalf ("Unable to delete %q deployment: %v" , deschedulerDeploymentObj .Name , err )
184
+ }
185
+
186
+ waitForPodsToDisappear (ctx , t , clientSet , deschedulerDeploymentObj .Labels , deschedulerDeploymentObj .Namespace )
187
+ }()
188
+
189
+ t .Logf ("Waiting for the descheduler pod running" )
190
+ deschedulerPods := waitForPodsRunning (ctx , t , clientSet , deschedulerDeploymentObj .Labels , 1 , deschedulerDeploymentObj .Namespace )
191
+ if len (deschedulerPods ) != 0 {
192
+ deschedulerPodName = deschedulerPods [0 ].Name
193
+ }
194
+
195
+ // Run RemoveDuplicates strategy
196
+ var meetsExpectations bool
197
+ var actualEvictedPodCount int
198
+ if err := wait .PollUntilContextTimeout (ctx , 5 * time .Second , 60 * time .Second , true , func (ctx context.Context ) (bool , error ) {
199
+ currentRunNames := sets .NewString (getCurrentPodNames (ctx , clientSet , testNamespace .Name , t )... )
200
+ actualEvictedPod := preRunNames .Difference (currentRunNames )
201
+ actualEvictedPodCount = actualEvictedPod .Len ()
202
+ t .Logf ("preRunNames: %v, currentRunNames: %v, actualEvictedPodCount: %v\n " , preRunNames .List (), currentRunNames .List (), actualEvictedPodCount )
203
+ if actualEvictedPodCount != tc .expectedEvictedPodCount {
204
+ t .Logf ("Expecting %v number of pods evicted, got %v instead" , tc .expectedEvictedPodCount , actualEvictedPodCount )
205
+ return false , nil
206
+ }
207
+ meetsExpectations = true
208
+ return true , nil
209
+ }); err != nil {
210
+ t .Errorf ("Error waiting for descheduler running: %v" , err )
211
+ }
125
212
126
- if actualEvictedCount := podEvictor . TotalEvicted (); actualEvictedCount == tc . expectedEvictedCount {
127
- t .Logf ( "Total of %d Pods were evicted for %s " , actualEvictedCount , name )
213
+ if ! meetsExpectations {
214
+ t .Errorf ( "Unexpected number of pods have been evicted, got %v, expected %v " , actualEvictedPodCount , tc . expectedEvictedPodCount )
128
215
} else {
129
- t .Errorf ( "Unexpected number of pods have been evicted, got %v, expected %v " , actualEvictedCount , tc .expectedEvictedCount )
216
+ t .Logf ( "Total of %d Pods were evicted for %s " , actualEvictedPodCount , tc .name )
130
217
}
131
218
})
132
219
}
0 commit comments