
Fix conversion errors Changed the order update update fix manaul coversions keep the global parameter for backward compatibility Address Wei's comments Fix an error Fix issues Add unit tests for validation Fix a comment Address comments Update comments fix verifiation errors Add tests for scheme_test.go Convert percentageOfNodesToScore to pointer Fix errors Resolve conflicts Fix testing errors Address Wei's comments Revert IntPtr to Int changes Address comments Not overrite percentageOfNodesToScore Fix a bug Fix a bug change errs to err Fix a nit Remove duplication Address comments Fix lint warning Fix an issue Update comments Clean up Address comments Revert changes to defaults fix unit test error Update Fix tests Use default PluginConfigs
770 lines
25 KiB
Go
770 lines
25 KiB
Go
/*
|
|
Copyright 2022 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package v1
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
|
|
v1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
|
"k8s.io/apiserver/pkg/util/feature"
|
|
componentbaseconfig "k8s.io/component-base/config/v1alpha1"
|
|
"k8s.io/component-base/featuregate"
|
|
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
|
configv1 "k8s.io/kube-scheduler/config/v1"
|
|
"k8s.io/kubernetes/pkg/features"
|
|
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
|
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/names"
|
|
"k8s.io/utils/pointer"
|
|
)
|
|
|
|
var pluginConfigs = []configv1.PluginConfig{
|
|
{
|
|
Name: "DefaultPreemption",
|
|
Args: runtime.RawExtension{
|
|
Object: &configv1.DefaultPreemptionArgs{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "DefaultPreemptionArgs",
|
|
APIVersion: "kubescheduler.config.k8s.io/v1",
|
|
},
|
|
MinCandidateNodesPercentage: pointer.Int32Ptr(10),
|
|
MinCandidateNodesAbsolute: pointer.Int32Ptr(100),
|
|
}},
|
|
},
|
|
{
|
|
Name: "InterPodAffinity",
|
|
Args: runtime.RawExtension{
|
|
Object: &configv1.InterPodAffinityArgs{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "InterPodAffinityArgs",
|
|
APIVersion: "kubescheduler.config.k8s.io/v1",
|
|
},
|
|
HardPodAffinityWeight: pointer.Int32Ptr(1),
|
|
}},
|
|
},
|
|
{
|
|
Name: "NodeAffinity",
|
|
Args: runtime.RawExtension{Object: &configv1.NodeAffinityArgs{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "NodeAffinityArgs",
|
|
APIVersion: "kubescheduler.config.k8s.io/v1",
|
|
},
|
|
}},
|
|
},
|
|
{
|
|
Name: "NodeResourcesBalancedAllocation",
|
|
Args: runtime.RawExtension{Object: &configv1.NodeResourcesBalancedAllocationArgs{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "NodeResourcesBalancedAllocationArgs",
|
|
APIVersion: "kubescheduler.config.k8s.io/v1",
|
|
},
|
|
Resources: []configv1.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
}},
|
|
},
|
|
{
|
|
Name: "NodeResourcesFit",
|
|
Args: runtime.RawExtension{Object: &configv1.NodeResourcesFitArgs{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "NodeResourcesFitArgs",
|
|
APIVersion: "kubescheduler.config.k8s.io/v1",
|
|
},
|
|
ScoringStrategy: &configv1.ScoringStrategy{
|
|
Type: configv1.LeastAllocated,
|
|
Resources: []configv1.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
},
|
|
}},
|
|
},
|
|
{
|
|
Name: "PodTopologySpread",
|
|
Args: runtime.RawExtension{Object: &configv1.PodTopologySpreadArgs{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "PodTopologySpreadArgs",
|
|
APIVersion: "kubescheduler.config.k8s.io/v1",
|
|
},
|
|
DefaultingType: configv1.SystemDefaulting,
|
|
}},
|
|
},
|
|
{
|
|
Name: "VolumeBinding",
|
|
Args: runtime.RawExtension{Object: &configv1.VolumeBindingArgs{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "VolumeBindingArgs",
|
|
APIVersion: "kubescheduler.config.k8s.io/v1",
|
|
},
|
|
BindTimeoutSeconds: pointer.Int64Ptr(600),
|
|
}},
|
|
},
|
|
}
|
|
|
|
func TestSchedulerDefaults(t *testing.T) {
|
|
enable := true
|
|
tests := []struct {
|
|
name string
|
|
config *configv1.KubeSchedulerConfiguration
|
|
expected *configv1.KubeSchedulerConfiguration
|
|
}{
|
|
{
|
|
name: "empty config",
|
|
config: &configv1.KubeSchedulerConfiguration{},
|
|
expected: &configv1.KubeSchedulerConfiguration{
|
|
Parallelism: pointer.Int32Ptr(16),
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: &enable,
|
|
EnableContentionProfiling: &enable,
|
|
},
|
|
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
|
|
LeaderElect: pointer.BoolPtr(true),
|
|
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
|
|
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
|
|
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
ResourceLock: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
|
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
|
|
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
|
|
Profiles: []configv1.KubeSchedulerProfile{
|
|
{
|
|
Plugins: getDefaultPlugins(),
|
|
PluginConfig: pluginConfigs,
|
|
SchedulerName: pointer.StringPtr("default-scheduler"),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "no scheduler name",
|
|
config: &configv1.KubeSchedulerConfiguration{
|
|
Profiles: []configv1.KubeSchedulerProfile{{}},
|
|
},
|
|
expected: &configv1.KubeSchedulerConfiguration{
|
|
Parallelism: pointer.Int32Ptr(16),
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: &enable,
|
|
EnableContentionProfiling: &enable,
|
|
},
|
|
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
|
|
LeaderElect: pointer.BoolPtr(true),
|
|
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
|
|
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
|
|
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
ResourceLock: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
|
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
|
|
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
|
|
Profiles: []configv1.KubeSchedulerProfile{
|
|
{
|
|
SchedulerName: pointer.StringPtr("default-scheduler"),
|
|
Plugins: getDefaultPlugins(),
|
|
PluginConfig: pluginConfigs},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "two profiles",
|
|
config: &configv1.KubeSchedulerConfiguration{
|
|
Parallelism: pointer.Int32Ptr(16),
|
|
Profiles: []configv1.KubeSchedulerProfile{
|
|
{
|
|
PluginConfig: []configv1.PluginConfig{
|
|
{Name: "FooPlugin"},
|
|
},
|
|
},
|
|
{
|
|
SchedulerName: pointer.StringPtr("custom-scheduler"),
|
|
Plugins: &configv1.Plugins{
|
|
Bind: configv1.PluginSet{
|
|
Enabled: []configv1.Plugin{
|
|
{Name: "BarPlugin"},
|
|
},
|
|
Disabled: []configv1.Plugin{
|
|
{Name: names.DefaultBinder},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expected: &configv1.KubeSchedulerConfiguration{
|
|
Parallelism: pointer.Int32Ptr(16),
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: &enable,
|
|
EnableContentionProfiling: &enable,
|
|
},
|
|
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
|
|
LeaderElect: pointer.BoolPtr(true),
|
|
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
|
|
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
|
|
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
ResourceLock: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
|
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
|
|
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
|
|
Profiles: []configv1.KubeSchedulerProfile{
|
|
{
|
|
Plugins: getDefaultPlugins(),
|
|
PluginConfig: []configv1.PluginConfig{
|
|
{Name: "FooPlugin"},
|
|
{
|
|
Name: "DefaultPreemption",
|
|
Args: runtime.RawExtension{
|
|
Object: &configv1.DefaultPreemptionArgs{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "DefaultPreemptionArgs",
|
|
APIVersion: "kubescheduler.config.k8s.io/v1",
|
|
},
|
|
MinCandidateNodesPercentage: pointer.Int32Ptr(10),
|
|
MinCandidateNodesAbsolute: pointer.Int32Ptr(100),
|
|
}},
|
|
},
|
|
{
|
|
Name: "InterPodAffinity",
|
|
Args: runtime.RawExtension{
|
|
Object: &configv1.InterPodAffinityArgs{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "InterPodAffinityArgs",
|
|
APIVersion: "kubescheduler.config.k8s.io/v1",
|
|
},
|
|
HardPodAffinityWeight: pointer.Int32Ptr(1),
|
|
}},
|
|
},
|
|
{
|
|
Name: "NodeAffinity",
|
|
Args: runtime.RawExtension{Object: &configv1.NodeAffinityArgs{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "NodeAffinityArgs",
|
|
APIVersion: "kubescheduler.config.k8s.io/v1",
|
|
},
|
|
}},
|
|
},
|
|
{
|
|
Name: "NodeResourcesBalancedAllocation",
|
|
Args: runtime.RawExtension{Object: &configv1.NodeResourcesBalancedAllocationArgs{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "NodeResourcesBalancedAllocationArgs",
|
|
APIVersion: "kubescheduler.config.k8s.io/v1",
|
|
},
|
|
Resources: []configv1.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
}},
|
|
},
|
|
{
|
|
Name: "NodeResourcesFit",
|
|
Args: runtime.RawExtension{Object: &configv1.NodeResourcesFitArgs{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "NodeResourcesFitArgs",
|
|
APIVersion: "kubescheduler.config.k8s.io/v1",
|
|
},
|
|
ScoringStrategy: &configv1.ScoringStrategy{
|
|
Type: configv1.LeastAllocated,
|
|
Resources: []configv1.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
|
},
|
|
}},
|
|
},
|
|
{
|
|
Name: "PodTopologySpread",
|
|
Args: runtime.RawExtension{Object: &configv1.PodTopologySpreadArgs{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "PodTopologySpreadArgs",
|
|
APIVersion: "kubescheduler.config.k8s.io/v1",
|
|
},
|
|
DefaultingType: configv1.SystemDefaulting,
|
|
}},
|
|
},
|
|
{
|
|
Name: "VolumeBinding",
|
|
Args: runtime.RawExtension{Object: &configv1.VolumeBindingArgs{
|
|
TypeMeta: metav1.TypeMeta{
|
|
Kind: "VolumeBindingArgs",
|
|
APIVersion: "kubescheduler.config.k8s.io/v1",
|
|
},
|
|
BindTimeoutSeconds: pointer.Int64Ptr(600),
|
|
}},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
SchedulerName: pointer.StringPtr("custom-scheduler"),
|
|
Plugins: &configv1.Plugins{
|
|
MultiPoint: configv1.PluginSet{
|
|
Enabled: []configv1.Plugin{
|
|
{Name: names.PrioritySort},
|
|
{Name: names.NodeUnschedulable},
|
|
{Name: names.NodeName},
|
|
{Name: names.TaintToleration, Weight: pointer.Int32(3)},
|
|
{Name: names.NodeAffinity, Weight: pointer.Int32(2)},
|
|
{Name: names.NodePorts},
|
|
{Name: names.NodeResourcesFit, Weight: pointer.Int32(1)},
|
|
{Name: names.VolumeRestrictions},
|
|
{Name: names.EBSLimits},
|
|
{Name: names.GCEPDLimits},
|
|
{Name: names.NodeVolumeLimits},
|
|
{Name: names.AzureDiskLimits},
|
|
{Name: names.VolumeBinding},
|
|
{Name: names.VolumeZone},
|
|
{Name: names.PodTopologySpread, Weight: pointer.Int32(2)},
|
|
{Name: names.InterPodAffinity, Weight: pointer.Int32(2)},
|
|
{Name: names.DefaultPreemption},
|
|
{Name: names.NodeResourcesBalancedAllocation, Weight: pointer.Int32(1)},
|
|
{Name: names.ImageLocality, Weight: pointer.Int32(1)},
|
|
{Name: names.DefaultBinder},
|
|
},
|
|
},
|
|
Bind: configv1.PluginSet{
|
|
Enabled: []configv1.Plugin{
|
|
{Name: "BarPlugin"},
|
|
},
|
|
Disabled: []configv1.Plugin{
|
|
{Name: names.DefaultBinder},
|
|
},
|
|
},
|
|
},
|
|
PluginConfig: pluginConfigs,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "Prallelism with no port",
|
|
config: &configv1.KubeSchedulerConfiguration{
|
|
Parallelism: pointer.Int32Ptr(16),
|
|
},
|
|
expected: &configv1.KubeSchedulerConfiguration{
|
|
Parallelism: pointer.Int32Ptr(16),
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: &enable,
|
|
EnableContentionProfiling: &enable,
|
|
},
|
|
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
|
|
LeaderElect: pointer.BoolPtr(true),
|
|
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
|
|
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
|
|
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
ResourceLock: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
|
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
|
|
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
|
|
Profiles: []configv1.KubeSchedulerProfile{
|
|
{
|
|
Plugins: getDefaultPlugins(),
|
|
PluginConfig: pluginConfigs,
|
|
SchedulerName: pointer.StringPtr("default-scheduler"),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "set non default parallelism",
|
|
config: &configv1.KubeSchedulerConfiguration{
|
|
Parallelism: pointer.Int32Ptr(8),
|
|
},
|
|
expected: &configv1.KubeSchedulerConfiguration{
|
|
Parallelism: pointer.Int32Ptr(8),
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: &enable,
|
|
EnableContentionProfiling: &enable,
|
|
},
|
|
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
|
|
LeaderElect: pointer.BoolPtr(true),
|
|
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
|
|
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
|
|
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
ResourceLock: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
|
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
|
|
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
|
|
Profiles: []configv1.KubeSchedulerProfile{
|
|
{
|
|
Plugins: getDefaultPlugins(),
|
|
PluginConfig: pluginConfigs,
|
|
SchedulerName: pointer.StringPtr("default-scheduler"),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "set non default global percentageOfNodesToScore",
|
|
config: &configv1.KubeSchedulerConfiguration{
|
|
PercentageOfNodesToScore: pointer.Int32Ptr(50),
|
|
},
|
|
expected: &configv1.KubeSchedulerConfiguration{
|
|
Parallelism: pointer.Int32Ptr(16),
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: &enable,
|
|
EnableContentionProfiling: &enable,
|
|
},
|
|
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
|
|
LeaderElect: pointer.BoolPtr(true),
|
|
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
|
|
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
|
|
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
ResourceLock: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: pointer.Int32Ptr(50),
|
|
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
|
|
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
|
|
Profiles: []configv1.KubeSchedulerProfile{
|
|
{
|
|
Plugins: getDefaultPlugins(),
|
|
PluginConfig: pluginConfigs,
|
|
SchedulerName: pointer.StringPtr("default-scheduler"),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "set non default profile percentageOfNodesToScore",
|
|
config: &configv1.KubeSchedulerConfiguration{
|
|
Profiles: []configv1.KubeSchedulerProfile{
|
|
{
|
|
PercentageOfNodesToScore: pointer.Int32Ptr(50),
|
|
},
|
|
},
|
|
},
|
|
expected: &configv1.KubeSchedulerConfiguration{
|
|
Parallelism: pointer.Int32Ptr(16),
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: &enable,
|
|
EnableContentionProfiling: &enable,
|
|
},
|
|
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
|
|
LeaderElect: pointer.BoolPtr(true),
|
|
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
|
|
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
|
|
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
ResourceLock: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: pointer.Int32(config.DefaultPercentageOfNodesToScore),
|
|
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
|
|
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
|
|
Profiles: []configv1.KubeSchedulerProfile{
|
|
{
|
|
Plugins: getDefaultPlugins(),
|
|
PluginConfig: pluginConfigs,
|
|
SchedulerName: pointer.StringPtr("default-scheduler"),
|
|
PercentageOfNodesToScore: pointer.Int32Ptr(50),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "set non default global and profile percentageOfNodesToScore",
|
|
config: &configv1.KubeSchedulerConfiguration{
|
|
PercentageOfNodesToScore: pointer.Int32Ptr(10),
|
|
Profiles: []configv1.KubeSchedulerProfile{
|
|
{
|
|
PercentageOfNodesToScore: pointer.Int32Ptr(50),
|
|
},
|
|
},
|
|
},
|
|
expected: &configv1.KubeSchedulerConfiguration{
|
|
Parallelism: pointer.Int32Ptr(16),
|
|
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
|
EnableProfiling: &enable,
|
|
EnableContentionProfiling: &enable,
|
|
},
|
|
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
|
|
LeaderElect: pointer.BoolPtr(true),
|
|
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
|
|
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
|
|
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
|
|
ResourceLock: "leases",
|
|
ResourceNamespace: "kube-system",
|
|
ResourceName: "kube-scheduler",
|
|
},
|
|
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
|
QPS: 50,
|
|
Burst: 100,
|
|
ContentType: "application/vnd.kubernetes.protobuf",
|
|
},
|
|
PercentageOfNodesToScore: pointer.Int32Ptr(10),
|
|
PodInitialBackoffSeconds: pointer.Int64Ptr(1),
|
|
PodMaxBackoffSeconds: pointer.Int64Ptr(10),
|
|
Profiles: []configv1.KubeSchedulerProfile{
|
|
{
|
|
Plugins: getDefaultPlugins(),
|
|
PluginConfig: pluginConfigs,
|
|
SchedulerName: pointer.StringPtr("default-scheduler"),
|
|
PercentageOfNodesToScore: pointer.Int32Ptr(50),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
SetDefaults_KubeSchedulerConfiguration(tc.config)
|
|
if diff := cmp.Diff(tc.expected, tc.config); diff != "" {
|
|
t.Errorf("Got unexpected defaults (-want, +got):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPluginArgsDefaults(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
features map[featuregate.Feature]bool
|
|
in runtime.Object
|
|
want runtime.Object
|
|
}{
|
|
{
|
|
name: "DefaultPreemptionArgs empty",
|
|
in: &configv1.DefaultPreemptionArgs{},
|
|
want: &configv1.DefaultPreemptionArgs{
|
|
MinCandidateNodesPercentage: pointer.Int32Ptr(10),
|
|
MinCandidateNodesAbsolute: pointer.Int32Ptr(100),
|
|
},
|
|
},
|
|
{
|
|
name: "DefaultPreemptionArgs with value",
|
|
in: &configv1.DefaultPreemptionArgs{
|
|
MinCandidateNodesPercentage: pointer.Int32Ptr(50),
|
|
},
|
|
want: &configv1.DefaultPreemptionArgs{
|
|
MinCandidateNodesPercentage: pointer.Int32Ptr(50),
|
|
MinCandidateNodesAbsolute: pointer.Int32Ptr(100),
|
|
},
|
|
},
|
|
{
|
|
name: "InterPodAffinityArgs empty",
|
|
in: &configv1.InterPodAffinityArgs{},
|
|
want: &configv1.InterPodAffinityArgs{
|
|
HardPodAffinityWeight: pointer.Int32Ptr(1),
|
|
},
|
|
},
|
|
{
|
|
name: "InterPodAffinityArgs explicit 0",
|
|
in: &configv1.InterPodAffinityArgs{
|
|
HardPodAffinityWeight: pointer.Int32Ptr(0),
|
|
},
|
|
want: &configv1.InterPodAffinityArgs{
|
|
HardPodAffinityWeight: pointer.Int32Ptr(0),
|
|
},
|
|
},
|
|
{
|
|
name: "InterPodAffinityArgs with value",
|
|
in: &configv1.InterPodAffinityArgs{
|
|
HardPodAffinityWeight: pointer.Int32Ptr(5),
|
|
},
|
|
want: &configv1.InterPodAffinityArgs{
|
|
HardPodAffinityWeight: pointer.Int32Ptr(5),
|
|
},
|
|
},
|
|
{
|
|
name: "NodeResourcesBalancedAllocationArgs resources empty",
|
|
in: &configv1.NodeResourcesBalancedAllocationArgs{},
|
|
want: &configv1.NodeResourcesBalancedAllocationArgs{
|
|
Resources: []configv1.ResourceSpec{
|
|
{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "NodeResourcesBalancedAllocationArgs with scalar resource",
|
|
in: &configv1.NodeResourcesBalancedAllocationArgs{
|
|
Resources: []configv1.ResourceSpec{
|
|
{Name: "scalar.io/scalar1", Weight: 1},
|
|
},
|
|
},
|
|
want: &configv1.NodeResourcesBalancedAllocationArgs{
|
|
Resources: []configv1.ResourceSpec{
|
|
{Name: "scalar.io/scalar1", Weight: 1},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "NodeResourcesBalancedAllocationArgs with mixed resources",
|
|
in: &configv1.NodeResourcesBalancedAllocationArgs{
|
|
Resources: []configv1.ResourceSpec{
|
|
{Name: string(v1.ResourceCPU), Weight: 1},
|
|
{Name: "scalar.io/scalar1", Weight: 1},
|
|
},
|
|
},
|
|
want: &configv1.NodeResourcesBalancedAllocationArgs{
|
|
Resources: []configv1.ResourceSpec{
|
|
{Name: string(v1.ResourceCPU), Weight: 1},
|
|
{Name: "scalar.io/scalar1", Weight: 1},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "NodeResourcesBalancedAllocationArgs have resource no weight",
|
|
in: &configv1.NodeResourcesBalancedAllocationArgs{
|
|
Resources: []configv1.ResourceSpec{
|
|
{Name: string(v1.ResourceCPU)},
|
|
{Name: "scalar.io/scalar0"},
|
|
{Name: "scalar.io/scalar1", Weight: 1},
|
|
},
|
|
},
|
|
want: &configv1.NodeResourcesBalancedAllocationArgs{
|
|
Resources: []configv1.ResourceSpec{
|
|
{Name: string(v1.ResourceCPU), Weight: 1},
|
|
{Name: "scalar.io/scalar0", Weight: 1},
|
|
{Name: "scalar.io/scalar1", Weight: 1},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "PodTopologySpreadArgs resources empty",
|
|
in: &configv1.PodTopologySpreadArgs{},
|
|
want: &configv1.PodTopologySpreadArgs{
|
|
DefaultingType: configv1.SystemDefaulting,
|
|
},
|
|
},
|
|
{
|
|
name: "PodTopologySpreadArgs resources with value",
|
|
in: &configv1.PodTopologySpreadArgs{
|
|
DefaultConstraints: []v1.TopologySpreadConstraint{
|
|
{
|
|
TopologyKey: "planet",
|
|
WhenUnsatisfiable: v1.DoNotSchedule,
|
|
MaxSkew: 2,
|
|
},
|
|
},
|
|
},
|
|
want: &configv1.PodTopologySpreadArgs{
|
|
DefaultConstraints: []v1.TopologySpreadConstraint{
|
|
{
|
|
TopologyKey: "planet",
|
|
WhenUnsatisfiable: v1.DoNotSchedule,
|
|
MaxSkew: 2,
|
|
},
|
|
},
|
|
DefaultingType: configv1.SystemDefaulting,
|
|
},
|
|
},
|
|
{
|
|
name: "NodeResourcesFitArgs not set",
|
|
in: &configv1.NodeResourcesFitArgs{},
|
|
want: &configv1.NodeResourcesFitArgs{
|
|
ScoringStrategy: &configv1.ScoringStrategy{
|
|
Type: configv1.LeastAllocated,
|
|
Resources: defaultResourceSpec,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "NodeResourcesFitArgs Resources empty",
|
|
in: &configv1.NodeResourcesFitArgs{
|
|
ScoringStrategy: &configv1.ScoringStrategy{
|
|
Type: configv1.MostAllocated,
|
|
},
|
|
},
|
|
want: &configv1.NodeResourcesFitArgs{
|
|
ScoringStrategy: &configv1.ScoringStrategy{
|
|
Type: configv1.MostAllocated,
|
|
Resources: defaultResourceSpec,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "VolumeBindingArgs empty, VolumeCapacityPriority disabled",
|
|
features: map[featuregate.Feature]bool{
|
|
features.VolumeCapacityPriority: false,
|
|
},
|
|
in: &configv1.VolumeBindingArgs{},
|
|
want: &configv1.VolumeBindingArgs{
|
|
BindTimeoutSeconds: pointer.Int64Ptr(600),
|
|
},
|
|
},
|
|
{
|
|
name: "VolumeBindingArgs empty, VolumeCapacityPriority enabled",
|
|
features: map[featuregate.Feature]bool{
|
|
features.VolumeCapacityPriority: true,
|
|
},
|
|
in: &configv1.VolumeBindingArgs{},
|
|
want: &configv1.VolumeBindingArgs{
|
|
BindTimeoutSeconds: pointer.Int64Ptr(600),
|
|
Shape: []configv1.UtilizationShapePoint{
|
|
{Utilization: 0, Score: 0},
|
|
{Utilization: 100, Score: 10},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range tests {
|
|
scheme := runtime.NewScheme()
|
|
utilruntime.Must(AddToScheme(scheme))
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
for k, v := range tc.features {
|
|
defer featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, k, v)()
|
|
}
|
|
scheme.Default(tc.in)
|
|
if diff := cmp.Diff(tc.in, tc.want); diff != "" {
|
|
t.Errorf("Got unexpected defaults (-want, +got):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|