1
16
17 package podutils
18
19 import (
20 "sort"
21 "testing"
22 "time"
23
24 corev1 "k8s.io/api/core/v1"
25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26 )
27
28 func TestActivePods(t *testing.T) {
29 time1 := metav1.Now()
30 time2 := metav1.NewTime(time1.Add(1 * time.Second))
31 time3 := metav1.NewTime(time1.Add(2 * time.Second))
32
33 tests := []struct {
34 name string
35 pod1 *corev1.Pod
36 pod2 *corev1.Pod
37 }{
38 {
39 name: "unassigned pod should sort before assigned pod",
40 pod1: &corev1.Pod{
41 ObjectMeta: metav1.ObjectMeta{
42 Name: "unassignedPod",
43 Namespace: "default",
44 },
45 },
46 pod2: &corev1.Pod{
47 ObjectMeta: metav1.ObjectMeta{
48 Name: "assignedPod",
49 Namespace: "default",
50 },
51 Spec: corev1.PodSpec{
52 NodeName: "node1",
53 },
54 },
55 },
56 {
57 name: "pending pod should sort before unknown pod",
58 pod1: &corev1.Pod{
59 ObjectMeta: metav1.ObjectMeta{
60 Name: "pendingPod",
61 Namespace: "default",
62 },
63 Spec: corev1.PodSpec{
64 NodeName: "node1",
65 },
66 Status: corev1.PodStatus{
67 Phase: corev1.PodPending,
68 },
69 },
70 pod2: &corev1.Pod{
71 ObjectMeta: metav1.ObjectMeta{
72 Name: "unknownPod",
73 Namespace: "default",
74 CreationTimestamp: time1,
75 },
76 Spec: corev1.PodSpec{
77 NodeName: "node1",
78 },
79 Status: corev1.PodStatus{
80 Phase: corev1.PodUnknown,
81 },
82 },
83 },
84 {
85 name: "unknown pod should sort before running pod",
86 pod1: &corev1.Pod{
87 ObjectMeta: metav1.ObjectMeta{
88 Name: "unknownPod",
89 Namespace: "default",
90 CreationTimestamp: time1,
91 },
92 Spec: corev1.PodSpec{
93 NodeName: "node1",
94 },
95 Status: corev1.PodStatus{
96 Phase: corev1.PodUnknown,
97 },
98 },
99 pod2: &corev1.Pod{
100 ObjectMeta: metav1.ObjectMeta{
101 Name: "runningPod",
102 Namespace: "default",
103 CreationTimestamp: time1,
104 },
105 Spec: corev1.PodSpec{
106 NodeName: "node1",
107 },
108 Status: corev1.PodStatus{
109 Phase: corev1.PodRunning,
110 },
111 },
112 },
113 {
114 name: "unready pod should sort before ready pod",
115 pod1: &corev1.Pod{
116 ObjectMeta: metav1.ObjectMeta{
117 Name: "unreadyPod",
118 Namespace: "default",
119 },
120 Spec: corev1.PodSpec{
121 NodeName: "node1",
122 },
123 Status: corev1.PodStatus{
124 Phase: corev1.PodRunning,
125 },
126 },
127 pod2: &corev1.Pod{
128 ObjectMeta: metav1.ObjectMeta{
129 Name: "readyPod",
130 Namespace: "default",
131 },
132 Spec: corev1.PodSpec{
133 NodeName: "node1",
134 },
135 Status: corev1.PodStatus{
136 Phase: corev1.PodRunning,
137 Conditions: []corev1.PodCondition{
138 {
139 Type: corev1.PodReady,
140 Status: corev1.ConditionTrue,
141 LastTransitionTime: time1,
142 },
143 },
144 },
145 },
146 },
147 {
148 name: "pod with deletion timestamp should sort before pod without deletion timestamp",
149 pod1: &corev1.Pod{
150 ObjectMeta: metav1.ObjectMeta{
151 Name: "readyPodDeleting",
152 Namespace: "default",
153 DeletionTimestamp: &time2,
154 },
155 Spec: corev1.PodSpec{
156 NodeName: "node1",
157 },
158 Status: corev1.PodStatus{
159 Phase: corev1.PodRunning,
160 Conditions: []corev1.PodCondition{
161 {
162 Type: corev1.PodReady,
163 Status: corev1.ConditionTrue,
164 LastTransitionTime: time1,
165 },
166 },
167 },
168 },
169 pod2: &corev1.Pod{
170 ObjectMeta: metav1.ObjectMeta{
171 Name: "readyPod",
172 Namespace: "default",
173 },
174 Spec: corev1.PodSpec{
175 NodeName: "node1",
176 },
177 Status: corev1.PodStatus{
178 Phase: corev1.PodRunning,
179 Conditions: []corev1.PodCondition{
180 {
181 Type: corev1.PodReady,
182 Status: corev1.ConditionTrue,
183 LastTransitionTime: time1,
184 },
185 },
186 },
187 },
188 },
189 {
190 name: "older deletion timestamp should sort before newer deletion timestamp",
191 pod1: &corev1.Pod{
192 ObjectMeta: metav1.ObjectMeta{
193 Name: "readyPodDeletingOlder",
194 Namespace: "default",
195 DeletionTimestamp: &time2,
196 },
197 Spec: corev1.PodSpec{
198 NodeName: "node1",
199 },
200 Status: corev1.PodStatus{
201 Phase: corev1.PodRunning,
202 Conditions: []corev1.PodCondition{
203 {
204 Type: corev1.PodReady,
205 Status: corev1.ConditionTrue,
206 LastTransitionTime: time1,
207 },
208 },
209 },
210 },
211 pod2: &corev1.Pod{
212 ObjectMeta: metav1.ObjectMeta{
213 Name: "readyPodDeletingNewer",
214 Namespace: "default",
215 DeletionTimestamp: &time3,
216 },
217 Spec: corev1.PodSpec{
218 NodeName: "node1",
219 },
220 Status: corev1.PodStatus{
221 Phase: corev1.PodRunning,
222 Conditions: []corev1.PodCondition{
223 {
224 Type: corev1.PodReady,
225 Status: corev1.ConditionTrue,
226 LastTransitionTime: time1,
227 },
228 },
229 },
230 },
231 },
232 {
233 name: "newer ready timestamp should sort before older ready timestamp",
234 pod1: &corev1.Pod{
235 ObjectMeta: metav1.ObjectMeta{
236 Name: "newerReadyPod",
237 Namespace: "default",
238 },
239 Spec: corev1.PodSpec{
240 NodeName: "node1",
241 },
242 Status: corev1.PodStatus{
243 Phase: corev1.PodRunning,
244 Conditions: []corev1.PodCondition{
245 {
246 Type: corev1.PodReady,
247 Status: corev1.ConditionTrue,
248 LastTransitionTime: time3,
249 },
250 },
251 },
252 },
253 pod2: &corev1.Pod{
254 ObjectMeta: metav1.ObjectMeta{
255 Name: "olderReadyPod",
256 Namespace: "default",
257 },
258 Spec: corev1.PodSpec{
259 NodeName: "node1",
260 },
261 Status: corev1.PodStatus{
262 Phase: corev1.PodRunning,
263 Conditions: []corev1.PodCondition{
264 {
265 Type: corev1.PodReady,
266 Status: corev1.ConditionTrue,
267 LastTransitionTime: time2,
268 },
269 },
270 },
271 },
272 },
273 {
274 name: "higher restart count should sort before lower restart count",
275 pod1: &corev1.Pod{
276 ObjectMeta: metav1.ObjectMeta{
277 Name: "podWithMoreRestarts",
278 Namespace: "default",
279 },
280 Spec: corev1.PodSpec{
281 NodeName: "node1",
282 },
283 Status: corev1.PodStatus{
284 Phase: corev1.PodRunning,
285 Conditions: []corev1.PodCondition{
286 {
287 Type: corev1.PodReady,
288 Status: corev1.ConditionTrue,
289 LastTransitionTime: time1,
290 },
291 },
292 ContainerStatuses: []corev1.ContainerStatus{
293 {
294 RestartCount: 3,
295 },
296 },
297 },
298 },
299 pod2: &corev1.Pod{
300 ObjectMeta: metav1.ObjectMeta{
301 Name: "podWithLessRestarts",
302 Namespace: "default",
303 },
304 Spec: corev1.PodSpec{
305 NodeName: "node1",
306 },
307 Status: corev1.PodStatus{
308 Phase: corev1.PodRunning,
309 Conditions: []corev1.PodCondition{
310 {
311 Type: corev1.PodReady,
312 Status: corev1.ConditionTrue,
313 LastTransitionTime: time1,
314 },
315 },
316 ContainerStatuses: []corev1.ContainerStatus{
317 {
318 RestartCount: 2,
319 },
320 },
321 },
322 },
323 },
324 {
325 name: "newer creation timestamp should sort before older creation timestamp",
326 pod1: &corev1.Pod{
327 ObjectMeta: metav1.ObjectMeta{
328 Name: "newerCreationPod",
329 Namespace: "default",
330 CreationTimestamp: time3,
331 },
332 Spec: corev1.PodSpec{
333 NodeName: "node1",
334 },
335 Status: corev1.PodStatus{
336 Phase: corev1.PodRunning,
337 Conditions: []corev1.PodCondition{
338 {
339 Type: corev1.PodReady,
340 Status: corev1.ConditionTrue,
341 LastTransitionTime: time1,
342 },
343 },
344 },
345 },
346 pod2: &corev1.Pod{
347 ObjectMeta: metav1.ObjectMeta{
348 Name: "olderCreationPod",
349 Namespace: "default",
350 CreationTimestamp: time2,
351 },
352 Spec: corev1.PodSpec{
353 NodeName: "node1",
354 },
355 Status: corev1.PodStatus{
356 Phase: corev1.PodRunning,
357 Conditions: []corev1.PodCondition{
358 {
359 Type: corev1.PodReady,
360 Status: corev1.ConditionTrue,
361 LastTransitionTime: time1,
362 },
363 },
364 },
365 },
366 },
367 }
368 for _, tt := range tests {
369 t.Run(tt.name, func(t *testing.T) {
370
371 pods := ActivePods{tt.pod1, tt.pod2}
372 sort.Sort(pods)
373 if pods[0] != tt.pod1 || pods[1] != tt.pod2 {
374 t.Errorf("Incorrect ActivePods sorting, expected pod1 to be first")
375 }
376
377
378 pods = ActivePods{tt.pod2, tt.pod1}
379 sort.Sort(pods)
380 if pods[0] != tt.pod1 || pods[1] != tt.pod2 {
381 t.Errorf("Incorrect ActivePods sorting, expected pod1 to be first")
382 }
383 })
384 }
385 }
386
View as plain text