@@ -24,7 +24,11 @@ import (
24
24
corev1 "k8s.io/api/core/v1"
25
25
"k8s.io/apimachinery/pkg/runtime"
26
26
"k8s.io/apimachinery/pkg/runtime/schema"
27
+ "k8s.io/apiserver/pkg/util/feature"
28
+ "k8s.io/component-base/featuregate"
29
+ featuregatetesting "k8s.io/component-base/featuregate/testing"
27
30
"k8s.io/kube-scheduler/config/v1beta1"
31
+ "k8s.io/kubernetes/pkg/features"
28
32
"k8s.io/kubernetes/pkg/scheduler/apis/config"
29
33
"k8s.io/utils/pointer"
30
34
"sigs.k8s.io/yaml"
@@ -34,6 +38,7 @@ func TestCodecsDecodePluginConfig(t *testing.T) {
34
38
testCases := []struct {
35
39
name string
36
40
data []byte
41
+ feature featuregate.Feature
37
42
wantErr string
38
43
wantProfiles []config.KubeSchedulerProfile
39
44
}{
@@ -257,6 +262,7 @@ profiles:
257
262
args:
258
263
- name: VolumeBinding
259
264
args:
265
+ - name: PodTopologySpread
260
266
` ),
261
267
wantProfiles : []config.KubeSchedulerProfile {
262
268
{
@@ -291,6 +297,73 @@ profiles:
291
297
BindTimeoutSeconds : 600 ,
292
298
},
293
299
},
300
+ {
301
+ Name : "PodTopologySpread" ,
302
+ Args : & config.PodTopologySpreadArgs {},
303
+ },
304
+ },
305
+ },
306
+ },
307
+ },
308
+ {
309
+ name : "empty PodTopologySpread, feature DefaultPodTopologySpread enabled" ,
310
+ data : []byte (`
311
+ apiVersion: kubescheduler.config.k8s.io/v1beta1
312
+ kind: KubeSchedulerConfiguration
313
+ profiles:
314
+ - pluginConfig:
315
+ - name: PodTopologySpread
316
+ args:
317
+ defaultConstraints:
318
+ ` ),
319
+ feature : features .DefaultPodTopologySpread ,
320
+ wantProfiles : []config.KubeSchedulerProfile {
321
+ {
322
+ SchedulerName : "default-scheduler" ,
323
+ PluginConfig : []config.PluginConfig {
324
+ {
325
+ Name : "PodTopologySpread" ,
326
+ Args : & config.PodTopologySpreadArgs {
327
+ DefaultConstraints : []corev1.TopologySpreadConstraint {
328
+ {
329
+ MaxSkew : 3 ,
330
+ TopologyKey : corev1 .LabelHostname ,
331
+ WhenUnsatisfiable : corev1 .ScheduleAnyway ,
332
+ },
333
+ {
334
+ MaxSkew : 5 ,
335
+ TopologyKey : corev1 .LabelZoneFailureDomainStable ,
336
+ WhenUnsatisfiable : corev1 .ScheduleAnyway ,
337
+ },
338
+ },
339
+ },
340
+ },
341
+ },
342
+ },
343
+ },
344
+ },
345
+ {
346
+ name : "empty array PodTopologySpread, feature DefaultPodTopologySpread enabled" ,
347
+ data : []byte (`
348
+ apiVersion: kubescheduler.config.k8s.io/v1beta1
349
+ kind: KubeSchedulerConfiguration
350
+ profiles:
351
+ - pluginConfig:
352
+ - name: PodTopologySpread
353
+ args:
354
+ defaultConstraints: []
355
+ ` ),
356
+ feature : features .DefaultPodTopologySpread ,
357
+ wantProfiles : []config.KubeSchedulerProfile {
358
+ {
359
+ SchedulerName : "default-scheduler" ,
360
+ PluginConfig : []config.PluginConfig {
361
+ {
362
+ Name : "PodTopologySpread" ,
363
+ Args : & config.PodTopologySpreadArgs {
364
+ DefaultConstraints : []corev1.TopologySpreadConstraint {},
365
+ },
366
+ },
294
367
},
295
368
},
296
369
},
@@ -299,6 +372,9 @@ profiles:
299
372
decoder := Codecs .UniversalDecoder ()
300
373
for _ , tt := range testCases {
301
374
t .Run (tt .name , func (t * testing.T ) {
375
+ if tt .feature != "" {
376
+ defer featuregatetesting .SetFeatureGateDuringTest (t , feature .DefaultFeatureGate , tt .feature , true )()
377
+ }
302
378
obj , gvk , err := decoder .Decode (tt .data , nil , nil )
303
379
if err != nil {
304
380
if tt .wantErr != err .Error () {
@@ -373,6 +449,14 @@ func TestCodecsEncodePluginConfig(t *testing.T) {
373
449
},
374
450
},
375
451
},
452
+ {
453
+ Name : "PodTopologySpread" ,
454
+ Args : runtime.RawExtension {
455
+ Object : & v1beta1.PodTopologySpreadArgs {
456
+ DefaultConstraints : []corev1.TopologySpreadConstraint {},
457
+ },
458
+ },
459
+ },
376
460
{
377
461
Name : "OutOfTreePlugin" ,
378
462
Args : runtime.RawExtension {
@@ -428,6 +512,11 @@ profiles:
428
512
- name: mem
429
513
weight: 2
430
514
name: NodeResourcesLeastAllocated
515
+ - args:
516
+ apiVersion: kubescheduler.config.k8s.io/v1beta1
517
+ defaultConstraints: []
518
+ kind: PodTopologySpreadArgs
519
+ name: PodTopologySpread
431
520
- args:
432
521
foo: bar
433
522
name: OutOfTreePlugin
@@ -458,6 +547,10 @@ profiles:
458
547
BindTimeoutSeconds : 300 ,
459
548
},
460
549
},
550
+ {
551
+ Name : "PodTopologySpread" ,
552
+ Args : & config.PodTopologySpreadArgs {},
553
+ },
461
554
{
462
555
Name : "OutOfTreePlugin" ,
463
556
Args : & runtime.Unknown {
@@ -510,6 +603,11 @@ profiles:
510
603
bindTimeoutSeconds: 300
511
604
kind: VolumeBindingArgs
512
605
name: VolumeBinding
606
+ - args:
607
+ apiVersion: kubescheduler.config.k8s.io/v1beta1
608
+ defaultConstraints: null
609
+ kind: PodTopologySpreadArgs
610
+ name: PodTopologySpread
513
611
- args:
514
612
foo: bar
515
613
name: OutOfTreePlugin
0 commit comments