@@ -17,6 +17,7 @@ and limitations under the License.
17
17
package kubernetes
18
18
19
19
import (
20
+ "reflect"
20
21
"testing"
21
22
"time"
22
23
@@ -79,84 +80,181 @@ func TestCordon(t *testing.T) {
79
80
cases := []struct {
80
81
name string
81
82
node * core.Node
83
+ mutators []nodeMutatorFn
84
+ expected * core.Node
82
85
reactions []reactor
83
86
}{
84
87
{
85
88
name : "CordonSchedulableNode" ,
86
89
node : & core.Node {ObjectMeta : meta.ObjectMeta {Name : nodeName }},
87
- reactions : []reactor {
88
- reactor {
89
- verb : "get" ,
90
- resource : "nodes" ,
91
- ret : & core.Node {
92
- ObjectMeta : meta.ObjectMeta {Name : nodeName },
93
- Spec : core.NodeSpec {Unschedulable : false },
94
- },
95
- },
96
- reactor {
97
- verb : "update" ,
98
- resource : "nodes" ,
99
- ret : & core.Node {
100
- ObjectMeta : meta.ObjectMeta {Name : nodeName },
101
- Spec : core.NodeSpec {Unschedulable : true },
102
- },
103
- },
90
+ expected : & core.Node {
91
+ ObjectMeta : meta.ObjectMeta {Name : nodeName },
92
+ Spec : core.NodeSpec {Unschedulable : true },
104
93
},
105
94
},
106
95
{
107
96
name : "CordonUnschedulableNode" ,
108
- node : & core.Node {ObjectMeta : meta.ObjectMeta {Name : nodeName }},
109
- reactions : []reactor {
110
- reactor {
111
- verb : "get" ,
112
- resource : "nodes" ,
113
- ret : & core.Node {
114
- ObjectMeta : meta.ObjectMeta {Name : nodeName },
115
- Spec : core.NodeSpec {Unschedulable : true },
116
- },
117
- },
97
+ node : & core.Node {
98
+ ObjectMeta : meta.ObjectMeta {Name : nodeName },
99
+ Spec : core.NodeSpec {Unschedulable : true },
100
+ },
101
+ expected : & core.Node {
102
+ ObjectMeta : meta.ObjectMeta {Name : nodeName },
103
+ Spec : core.NodeSpec {Unschedulable : true },
118
104
},
119
105
},
120
106
{
121
107
name : "CordonNonExistentNode" ,
122
108
node : & core.Node {ObjectMeta : meta.ObjectMeta {Name : nodeName }},
123
109
reactions : []reactor {
124
- reactor {verb : "get" , resource : "nodes" , err : errors .New ("nope" )},
110
+ {verb : "get" , resource : "nodes" , err : errors .New ("nope" )},
125
111
},
126
112
},
127
113
{
128
114
name : "ErrorCordoningSchedulableNode" ,
129
115
node : & core.Node {ObjectMeta : meta.ObjectMeta {Name : nodeName }},
130
116
reactions : []reactor {
131
- reactor {
132
- verb : "get" ,
133
- resource : "nodes" ,
134
- ret : & core.Node {
135
- ObjectMeta : meta.ObjectMeta {Name : nodeName },
136
- Spec : core.NodeSpec {Unschedulable : false },
137
- },
138
- },
139
- reactor {verb : "update" , resource : "nodes" , err : errors .New ("nope" )},
117
+ {verb : "update" , resource : "nodes" , err : errors .New ("nope" )},
118
+ },
119
+ },
120
+ {
121
+ name : "CordonSchedulableNodeWithMutator" ,
122
+ node : & core.Node {ObjectMeta : meta.ObjectMeta {Name : nodeName }},
123
+ mutators : []nodeMutatorFn {func (n * core.Node ) {
124
+ n .Annotations = map [string ]string {"foo" : "1" }
125
+ }},
126
+ expected : & core.Node {
127
+ ObjectMeta : meta.ObjectMeta {Name : nodeName , Annotations : map [string ]string {"foo" : "1" }},
128
+ Spec : core.NodeSpec {Unschedulable : true },
129
+ },
130
+ },
131
+ {
132
+ name : "CordonUnschedulableNodeWithMutator" ,
133
+ node : & core.Node {
134
+ ObjectMeta : meta.ObjectMeta {Name : nodeName },
135
+ Spec : core.NodeSpec {Unschedulable : true },
136
+ },
137
+ mutators : []nodeMutatorFn {func (n * core.Node ) {
138
+ n .Annotations = map [string ]string {"foo" : "1" }
139
+ }},
140
+ expected : & core.Node {
141
+ ObjectMeta : meta.ObjectMeta {Name : nodeName },
142
+ Spec : core.NodeSpec {Unschedulable : true },
140
143
},
141
144
},
142
145
}
143
146
144
147
for _ , tc := range cases {
145
148
t .Run (tc .name , func (t * testing.T ) {
146
- c := & fake.Clientset {}
149
+ c := fake .NewSimpleClientset ( tc . node )
147
150
for _ , r := range tc .reactions {
148
- c .AddReactor (r .verb , r .resource , r .Fn ())
151
+ c .PrependReactor (r .verb , r .resource , r .Fn ())
149
152
}
150
-
151
153
d := NewAPICordonDrainer (c )
152
- if err := d .Cordon (tc .node ); err != nil {
154
+ if err := d .Cordon (tc .node , tc . mutators ... ); err != nil {
153
155
for _ , r := range tc .reactions {
154
156
if errors .Cause (err ) == r .err {
155
157
return
156
158
}
157
159
}
158
160
t .Errorf ("d.Cordon(%v): %v" , tc .node .Name , err )
159
161
}
162
+ {
163
+ n , err := c .CoreV1 ().Nodes ().Get (tc .node .GetName (), meta.GetOptions {})
164
+ if err != nil {
165
+ t .Errorf ("node.Get(%v): %v" , tc .node .Name , err )
166
+ }
167
+ if ! reflect .DeepEqual (tc .expected , n ) {
168
+ t .Errorf ("node.Get(%v): want %#v, got %#v" , tc .node .Name , tc .expected , n )
169
+ }
170
+ }
171
+ })
172
+ }
173
+ }
174
+
175
+ func TestUncordon (t * testing.T ) {
176
+ cases := []struct {
177
+ name string
178
+ node * core.Node
179
+ mutators []nodeMutatorFn
180
+ expected * core.Node
181
+ reactions []reactor
182
+ }{
183
+ {
184
+ name : "UncordonSchedulableNode" ,
185
+ node : & core.Node {ObjectMeta : meta.ObjectMeta {Name : nodeName }},
186
+ expected : & core.Node {ObjectMeta : meta.ObjectMeta {Name : nodeName }},
187
+ },
188
+ {
189
+ name : "UncordonUnschedulableNode" ,
190
+ node : & core.Node {
191
+ ObjectMeta : meta.ObjectMeta {Name : nodeName },
192
+ Spec : core.NodeSpec {Unschedulable : true },
193
+ },
194
+ expected : & core.Node {ObjectMeta : meta.ObjectMeta {Name : nodeName }},
195
+ },
196
+ {
197
+ name : "UncordonNonExistentNode" ,
198
+ node : & core.Node {ObjectMeta : meta.ObjectMeta {Name : nodeName }},
199
+ reactions : []reactor {
200
+ {verb : "get" , resource : "nodes" , err : errors .New ("nope" )},
201
+ },
202
+ },
203
+ {
204
+ name : "ErrorUncordoningUnschedulableNode" ,
205
+ node : & core.Node {
206
+ ObjectMeta : meta.ObjectMeta {Name : nodeName },
207
+ Spec : core.NodeSpec {Unschedulable : true },
208
+ },
209
+ reactions : []reactor {
210
+ {verb : "update" , resource : "nodes" , err : errors .New ("nope" )},
211
+ },
212
+ },
213
+ {
214
+ name : "UncordonSchedulableNodeWithMutator" ,
215
+ node : & core.Node {ObjectMeta : meta.ObjectMeta {Name : nodeName }},
216
+ mutators : []nodeMutatorFn {func (n * core.Node ) {
217
+ n .Annotations = map [string ]string {"foo" : "1" }
218
+ }},
219
+ expected : & core.Node {ObjectMeta : meta.ObjectMeta {Name : nodeName }},
220
+ },
221
+ {
222
+ name : "UncordonUnschedulableNodeWithMutator" ,
223
+ node : & core.Node {
224
+ ObjectMeta : meta.ObjectMeta {Name : nodeName },
225
+ Spec : core.NodeSpec {Unschedulable : true },
226
+ },
227
+ mutators : []nodeMutatorFn {func (n * core.Node ) {
228
+ n .Annotations = map [string ]string {"foo" : "1" }
229
+ }},
230
+ expected : & core.Node {ObjectMeta : meta.ObjectMeta {Name : nodeName , Annotations : map [string ]string {"foo" : "1" }}},
231
+ },
232
+ }
233
+
234
+ for _ , tc := range cases {
235
+ t .Run (tc .name , func (t * testing.T ) {
236
+ c := fake .NewSimpleClientset (tc .node )
237
+ for _ , r := range tc .reactions {
238
+ c .PrependReactor (r .verb , r .resource , r .Fn ())
239
+ }
240
+ d := NewAPICordonDrainer (c )
241
+ if err := d .Uncordon (tc .node , tc .mutators ... ); err != nil {
242
+ for _ , r := range tc .reactions {
243
+ if errors .Cause (err ) == r .err {
244
+ return
245
+ }
246
+ }
247
+ t .Errorf ("d.Uncordon(%v): %v" , tc .node .Name , err )
248
+ }
249
+ {
250
+ n , err := c .CoreV1 ().Nodes ().Get (tc .node .GetName (), meta.GetOptions {})
251
+ if err != nil {
252
+ t .Errorf ("node.Get(%v): %v" , tc .node .Name , err )
253
+ }
254
+ if ! reflect .DeepEqual (tc .expected , n ) {
255
+ t .Errorf ("node.Get(%v): want %#v, got %#v" , tc .node .Name , tc .expected , n )
256
+ }
257
+ }
160
258
})
161
259
}
162
260
}
0 commit comments