@@ -26,7 +26,10 @@ import (
26
26
27
27
v1 "k8s.io/api/core/v1"
28
28
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29
+ utilfeature "k8s.io/apiserver/pkg/util/feature"
30
+ featuregatetesting "k8s.io/component-base/featuregate/testing"
29
31
"k8s.io/klog/v2/ktesting"
32
+ "k8s.io/kubernetes/pkg/features"
30
33
"k8s.io/kubernetes/pkg/scheduler/backend/cache"
31
34
"k8s.io/kubernetes/pkg/scheduler/framework"
32
35
"k8s.io/kubernetes/pkg/scheduler/framework/runtime"
@@ -92,6 +95,24 @@ func TestImageLocalityPriority(t *testing.T) {
92
95
},
93
96
}
94
97
98
+ testImageVolume := v1.PodSpec {
99
+ Containers : []v1.Container {
100
+ {
101
+ Image : "gcr.io/30" ,
102
+ },
103
+ },
104
+ Volumes : []v1.Volume {
105
+ {
106
+ Name : "imageVolume" ,
107
+ VolumeSource : v1.VolumeSource {
108
+ Image : & v1.ImageVolumeSource {
109
+ Reference : "gcr.io/300" ,
110
+ },
111
+ },
112
+ },
113
+ },
114
+ }
115
+
95
116
test30Init300 := v1.PodSpec {
96
117
Containers : []v1.Container {
97
118
{
@@ -236,11 +257,12 @@ func TestImageLocalityPriority(t *testing.T) {
236
257
nodeWithNoImages := v1.NodeStatus {}
237
258
238
259
tests := []struct {
239
- pod * v1.Pod
240
- pods []* v1.Pod
241
- nodes []* v1.Node
242
- expectedList framework.NodeScoreList
243
- name string
260
+ featureEnabled bool
261
+ pod * v1.Pod
262
+ pods []* v1.Pod
263
+ nodes []* v1.Node
264
+ expectedList framework.NodeScoreList
265
+ name string
244
266
}{
245
267
{
246
268
// Pod: gcr.io/40 gcr.io/250
@@ -252,10 +274,11 @@ func TestImageLocalityPriority(t *testing.T) {
252
274
// Node2
253
275
// Image: gcr.io/250:latest 250MB
254
276
// Score: 100 * (250M/2 - 23M)/(1000M * 2 - 23M) = 5
255
- pod : & v1.Pod {Spec : test40250 },
256
- nodes : []* v1.Node {makeImageNode ("node1" , node403002000 ), makeImageNode ("node2" , node25010 )},
257
- expectedList : []framework.NodeScore {{Name : "node1" , Score : 0 }, {Name : "node2" , Score : 5 }},
258
- name : "two images spread on two nodes, prefer the larger image one" ,
277
+ featureEnabled : false ,
278
+ pod : & v1.Pod {Spec : test40250 },
279
+ nodes : []* v1.Node {makeImageNode ("node1" , node403002000 ), makeImageNode ("node2" , node25010 )},
280
+ expectedList : []framework.NodeScore {{Name : "node1" , Score : 0 }, {Name : "node2" , Score : 5 }},
281
+ name : "two images spread on two nodes, prefer the larger image one" ,
259
282
},
260
283
{
261
284
// Pod: gcr.io/40 gcr.io/300
@@ -267,10 +290,11 @@ func TestImageLocalityPriority(t *testing.T) {
267
290
// Node2
268
291
// Image: not present
269
292
// Score: 0
270
- pod : & v1.Pod {Spec : test40300 },
271
- nodes : []* v1.Node {makeImageNode ("node1" , node403002000 ), makeImageNode ("node2" , node25010 )},
272
- expectedList : []framework.NodeScore {{Name : "node1" , Score : 7 }, {Name : "node2" , Score : 0 }},
273
- name : "two images on one node, prefer this node" ,
293
+ featureEnabled : false ,
294
+ pod : & v1.Pod {Spec : test40300 },
295
+ nodes : []* v1.Node {makeImageNode ("node1" , node403002000 ), makeImageNode ("node2" , node25010 )},
296
+ expectedList : []framework.NodeScore {{Name : "node1" , Score : 7 }, {Name : "node2" , Score : 0 }},
297
+ name : "two images on one node, prefer this node" ,
274
298
},
275
299
{
276
300
// Pod: gcr.io/4000 gcr.io/10
@@ -282,10 +306,11 @@ func TestImageLocalityPriority(t *testing.T) {
282
306
// Node2
283
307
// Image: gcr.io/10:latest 10MB
284
308
// Score: 0 (10M/2 < 23M, min-threshold)
285
- pod : & v1.Pod {Spec : testMinMax },
286
- nodes : []* v1.Node {makeImageNode ("node1" , node400030 ), makeImageNode ("node2" , node25010 )},
287
- expectedList : []framework.NodeScore {{Name : "node1" , Score : framework .MaxNodeScore }, {Name : "node2" , Score : 0 }},
288
- name : "if exceed limit, use limit" ,
309
+ featureEnabled : false ,
310
+ pod : & v1.Pod {Spec : testMinMax },
311
+ nodes : []* v1.Node {makeImageNode ("node1" , node400030 ), makeImageNode ("node2" , node25010 )},
312
+ expectedList : []framework.NodeScore {{Name : "node1" , Score : framework .MaxNodeScore }, {Name : "node2" , Score : 0 }},
313
+ name : "if exceed limit, use limit" ,
289
314
},
290
315
{
291
316
// Pod: gcr.io/4000 gcr.io/10
@@ -301,10 +326,11 @@ func TestImageLocalityPriority(t *testing.T) {
301
326
// Node3
302
327
// Image:
303
328
// Score: 0
304
- pod : & v1.Pod {Spec : testMinMax },
305
- nodes : []* v1.Node {makeImageNode ("node1" , node400030 ), makeImageNode ("node2" , node25010 ), makeImageNode ("node3" , nodeWithNoImages )},
306
- expectedList : []framework.NodeScore {{Name : "node1" , Score : 66 }, {Name : "node2" , Score : 0 }, {Name : "node3" , Score : 0 }},
307
- name : "if exceed limit, use limit (with node which has no images present)" ,
329
+ featureEnabled : false ,
330
+ pod : & v1.Pod {Spec : testMinMax },
331
+ nodes : []* v1.Node {makeImageNode ("node1" , node400030 ), makeImageNode ("node2" , node25010 ), makeImageNode ("node3" , nodeWithNoImages )},
332
+ expectedList : []framework.NodeScore {{Name : "node1" , Score : 66 }, {Name : "node2" , Score : 0 }, {Name : "node3" , Score : 0 }},
333
+ name : "if exceed limit, use limit (with node which has no images present)" ,
308
334
},
309
335
{
310
336
// Pod: gcr.io/300 gcr.io/600 gcr.io/900
@@ -320,10 +346,11 @@ func TestImageLocalityPriority(t *testing.T) {
320
346
// Node3
321
347
// Image:
322
348
// Score: 0
323
- pod : & v1.Pod {Spec : test300600900 },
324
- nodes : []* v1.Node {makeImageNode ("node1" , node60040900 ), makeImageNode ("node2" , node300600900 ), makeImageNode ("node3" , nodeWithNoImages )},
325
- expectedList : []framework.NodeScore {{Name : "node1" , Score : 32 }, {Name : "node2" , Score : 36 }, {Name : "node3" , Score : 0 }},
326
- name : "pod with multiple large images, node2 is preferred" ,
349
+ featureEnabled : false ,
350
+ pod : & v1.Pod {Spec : test300600900 },
351
+ nodes : []* v1.Node {makeImageNode ("node1" , node60040900 ), makeImageNode ("node2" , node300600900 ), makeImageNode ("node3" , nodeWithNoImages )},
352
+ expectedList : []framework.NodeScore {{Name : "node1" , Score : 32 }, {Name : "node2" , Score : 36 }, {Name : "node3" , Score : 0 }},
353
+ name : "pod with multiple large images, node2 is preferred" ,
327
354
},
328
355
{
329
356
// Pod: gcr.io/30 gcr.io/40
@@ -335,10 +362,27 @@ func TestImageLocalityPriority(t *testing.T) {
335
362
// Node2
336
363
// Image: 100 * (30M - 23M) / (1000M * 2 - 23M) = 0
337
364
// Score: 0
338
- pod : & v1.Pod {Spec : test3040 },
339
- nodes : []* v1.Node {makeImageNode ("node1" , node203040 ), makeImageNode ("node2" , node400030 )},
340
- expectedList : []framework.NodeScore {{Name : "node1" , Score : 1 }, {Name : "node2" , Score : 0 }},
341
- name : "pod with multiple small images" ,
365
+ featureEnabled : false ,
366
+ pod : & v1.Pod {Spec : test3040 },
367
+ nodes : []* v1.Node {makeImageNode ("node1" , node203040 ), makeImageNode ("node2" , node400030 )},
368
+ expectedList : []framework.NodeScore {{Name : "node1" , Score : 1 }, {Name : "node2" , Score : 0 }},
369
+ name : "pod with multiple small images" ,
370
+ },
371
+ {
372
+ // Pod: gcr.io/300 gcr.io/30
373
+
374
+ // Node1
375
+ // Image: gcr.io/300:latest 300MB
376
+ // Score: 100 * (300M * 1/2 - 23M) / (1000M - 23M) = 12
377
+
378
+ // Node2
379
+ // Image: gcr.io/30:latest 30MB
380
+ // Score: 100 * (30M - 23M) / (1000M - 23M) = 0
381
+ featureEnabled : true ,
382
+ pod : & v1.Pod {Spec : testImageVolume },
383
+ nodes : []* v1.Node {makeImageNode ("node1" , node300600900 ), makeImageNode ("node2" , node400030 )},
384
+ expectedList : []framework.NodeScore {{Name : "node1" , Score : 12 }, {Name : "node2" , Score : 0 }},
385
+ name : "pod with ImageVolume" ,
342
386
},
343
387
{
344
388
// Pod: gcr.io/30 InitContainers: gcr.io/300
@@ -350,10 +394,11 @@ func TestImageLocalityPriority(t *testing.T) {
350
394
// Node2
351
395
// Image: gcr.io/20:latest 20MB, gcr.io/30:latest 30MB, gcr.io/40:latest 40MB
352
396
// Score: 100 * (30M * 1/2 - 23M) / (1000M * 2 - 23M) = 0
353
- pod : & v1.Pod {Spec : test30Init300 },
354
- nodes : []* v1.Node {makeImageNode ("node1" , node403002000 ), makeImageNode ("node2" , node203040 )},
355
- expectedList : []framework.NodeScore {{Name : "node1" , Score : 6 }, {Name : "node2" , Score : 0 }},
356
- name : "include InitContainers: two images spread on two nodes, prefer the larger image one" ,
397
+ featureEnabled : false ,
398
+ pod : & v1.Pod {Spec : test30Init300 },
399
+ nodes : []* v1.Node {makeImageNode ("node1" , node403002000 ), makeImageNode ("node2" , node203040 )},
400
+ expectedList : []framework.NodeScore {{Name : "node1" , Score : 6 }, {Name : "node2" , Score : 0 }},
401
+ name : "include InitContainers: two images spread on two nodes, prefer the larger image one" ,
357
402
},
358
403
}
359
404
@@ -362,6 +407,7 @@ func TestImageLocalityPriority(t *testing.T) {
362
407
_ , ctx := ktesting .NewTestContext (t )
363
408
ctx , cancel := context .WithCancel (ctx )
364
409
defer cancel ()
410
+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .ImageVolume , test .featureEnabled )
365
411
366
412
snapshot := cache .NewSnapshot (nil , test .nodes )
367
413
state := framework .NewCycleState ()
0 commit comments