@@ -57,27 +57,27 @@ import (
57
57
58
58
func TestSchedulingGates (t * testing.T ) {
59
59
tests := []struct {
60
- name string
61
- pods []* v1.Pod
62
- want []string
63
- rmPodsSchedulingGates [] int
64
- wantPostGatesRemoval []string
60
+ name string
61
+ pods []* v1.Pod
62
+ schedule []string
63
+ delete [] string
64
+ rmGates []string
65
65
}{
66
66
{
67
67
name : "regular pods" ,
68
68
pods : []* v1.Pod {
69
69
st .MakePod ().Name ("p1" ).Container ("pause" ).Obj (),
70
70
st .MakePod ().Name ("p2" ).Container ("pause" ).Obj (),
71
71
},
72
- want : []string {"p1" , "p2" },
72
+ schedule : []string {"p1" , "p2" },
73
73
},
74
74
{
75
75
name : "one pod carrying scheduling gates" ,
76
76
pods : []* v1.Pod {
77
77
st .MakePod ().Name ("p1" ).SchedulingGates ([]string {"foo" }).Container ("pause" ).Obj (),
78
78
st .MakePod ().Name ("p2" ).Container ("pause" ).Obj (),
79
79
},
80
- want : []string {"p2" },
80
+ schedule : []string {"p2" },
81
81
},
82
82
{
83
83
name : "two pod carrying scheduling gates, and remove gates of one pod" ,
@@ -86,9 +86,18 @@ func TestSchedulingGates(t *testing.T) {
86
86
st .MakePod ().Name ("p2" ).SchedulingGates ([]string {"bar" }).Container ("pause" ).Obj (),
87
87
st .MakePod ().Name ("p3" ).Container ("pause" ).Obj (),
88
88
},
89
- want : []string {"p3" },
90
- rmPodsSchedulingGates : []int {1 }, // remove gates of 'p2'
91
- wantPostGatesRemoval : []string {"p2" },
89
+ schedule : []string {"p3" },
90
+ rmGates : []string {"p2" },
91
+ },
92
+ {
93
+ name : "gated pod schedulable after deleting the scheduled pod and removing gate" ,
94
+ pods : []* v1.Pod {
95
+ st .MakePod ().Name ("p1" ).SchedulingGates ([]string {"foo" }).Container ("pause" ).Obj (),
96
+ st .MakePod ().Name ("p2" ).Container ("pause" ).Obj (),
97
+ },
98
+ schedule : []string {"p2" },
99
+ delete : []string {"p2" },
100
+ rmGates : []string {"p1" },
92
101
},
93
102
}
94
103
@@ -107,6 +116,15 @@ func TestSchedulingGates(t *testing.T) {
107
116
testutils .SyncSchedulerInformerFactory (testCtx )
108
117
109
118
cs , ns , ctx := testCtx .ClientSet , testCtx .NS .Name , testCtx .Ctx
119
+
120
+ // Create node, so we can schedule pods.
121
+ node := st .MakeNode ().Name ("node" ).Obj ()
122
+ if _ , err := cs .CoreV1 ().Nodes ().Create (ctx , node , metav1.CreateOptions {}); err != nil {
123
+ t .Fatal ("Failed to create node" )
124
+
125
+ }
126
+
127
+ // Create pods.
110
128
for _ , p := range tt .pods {
111
129
p .Namespace = ns
112
130
if _ , err := cs .CoreV1 ().Pods (ns ).Create (ctx , p , metav1.CreateOptions {}); err != nil {
@@ -122,30 +140,42 @@ func TestSchedulingGates(t *testing.T) {
122
140
t .Fatal (err )
123
141
}
124
142
125
- // Pop the expected pods out. They should be de-queueable.
126
- for _ , wantPod := range tt .want {
127
- podInfo := testutils .NextPodOrDie (t , testCtx )
128
- if got := podInfo .Pod .Name ; got != wantPod {
129
- t .Errorf ("Want %v to be popped out, but got %v" , wantPod , got )
143
+ // Schedule pods.
144
+ for _ , podName := range tt .schedule {
145
+ testCtx .Scheduler .ScheduleOne (testCtx .Ctx )
146
+ if err := wait .PollUntilContextTimeout (ctx , time .Millisecond * 200 , wait .ForeverTestTimeout , false , testutils .PodScheduled (cs , ns , podName )); err != nil {
147
+ t .Fatalf ("Failed to schedule %s" , podName )
148
+ }
149
+ }
150
+
151
+ // Delete pods, which triggers AssignedPodDelete event in the scheduling queue.
152
+ for _ , podName := range tt .delete {
153
+ if err := cs .CoreV1 ().Pods (ns ).Delete (ctx , podName , metav1.DeleteOptions {}); err != nil {
154
+ t .Fatalf ("Error calling Delete on %s" , podName )
155
+ }
156
+ if err := wait .PollUntilContextTimeout (ctx , time .Millisecond * 200 , wait .ForeverTestTimeout , false , testutils .PodDeleted (ctx , cs , ns , podName )); err != nil {
157
+ t .Fatalf ("Failed to delete %s" , podName )
130
158
}
131
159
}
132
160
133
- if len (tt .rmPodsSchedulingGates ) == 0 {
134
- return
161
+ // Ensure gated pods are not in ActiveQ
162
+ if len (testCtx .Scheduler .SchedulingQueue .PodsInActiveQ ()) > 0 {
163
+ t .Fatal ("Expected no schedulable pods" )
135
164
}
165
+
136
166
// Remove scheduling gates from the pod spec.
137
- for _ , idx := range tt .rmPodsSchedulingGates {
167
+ for _ , podName := range tt .rmGates {
138
168
patch := `{"spec": {"schedulingGates": null}}`
139
- podName := tt .pods [idx ].Name
140
169
if _ , err := cs .CoreV1 ().Pods (ns ).Patch (ctx , podName , types .StrategicMergePatchType , []byte (patch ), metav1.PatchOptions {}); err != nil {
141
170
t .Fatalf ("Failed to patch pod %v: %v" , podName , err )
142
171
}
143
172
}
144
- // Pop the expected pods out. They should be de-queueable.
145
- for _ , wantPod := range tt .wantPostGatesRemoval {
146
- podInfo := testutils .NextPodOrDie (t , testCtx )
147
- if got := podInfo .Pod .Name ; got != wantPod {
148
- t .Errorf ("Want %v to be popped out, but got %v" , wantPod , got )
173
+
174
+ // Schedule pods which no longer have gates.
175
+ for _ , podName := range tt .rmGates {
176
+ testCtx .Scheduler .ScheduleOne (testCtx .Ctx )
177
+ if err := wait .PollUntilContextTimeout (ctx , time .Millisecond * 200 , wait .ForeverTestTimeout , false , testutils .PodScheduled (cs , ns , podName )); err != nil {
178
+ t .Fatalf ("Failed to schedule %s" , podName )
149
179
}
150
180
}
151
181
})
0 commit comments