Made multi-scheduler graduated to Beta and then v1.
This commit is contained in:
parent
60489f837b
commit
c8c4b81963
@ -366,6 +366,7 @@ func TestEncodePtr(t *testing.T) {
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
}
|
||||
obj := runtime.Object(pod)
|
||||
|
@ -134,6 +134,9 @@ func FuzzerFor(t *testing.T, version schema.GroupVersion, src rand.Source) *fuzz
|
||||
if s.Affinity == nil {
|
||||
s.Affinity = new(api.Affinity)
|
||||
}
|
||||
if s.SchedulerName == "" {
|
||||
s.SchedulerName = api.DefaultSchedulerName
|
||||
}
|
||||
},
|
||||
func(j *api.PodPhase, c fuzz.Continue) {
|
||||
statuses := []api.PodPhase{api.PodPending, api.PodRunning, api.PodFailed, api.PodUnknown}
|
||||
|
@ -29,6 +29,7 @@ func DeepEqualSafePodSpec() api.PodSpec {
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1856,6 +1856,10 @@ type PodSpec struct {
|
||||
// If specified, the pod's scheduling constraints
|
||||
// +optional
|
||||
Affinity *Affinity
|
||||
// If specified, the pod will be dispatched by specified scheduler.
|
||||
// If not specified, the pod will be dispatched by default scheduler.
|
||||
// +optional
|
||||
SchedulerName string
|
||||
}
|
||||
|
||||
// Sysctl defines a kernel parameter to be set
|
||||
|
@ -174,6 +174,9 @@ func SetDefaults_PodSpec(obj *PodSpec) {
|
||||
period := int64(DefaultTerminationGracePeriodSeconds)
|
||||
obj.TerminationGracePeriodSeconds = &period
|
||||
}
|
||||
if obj.SchedulerName == "" {
|
||||
obj.SchedulerName = DefaultSchedulerName
|
||||
}
|
||||
}
|
||||
func SetDefaults_Probe(obj *Probe) {
|
||||
if obj.TimeoutSeconds == 0 {
|
||||
|
@ -807,3 +807,12 @@ func TestSetDefaultProbe(t *testing.T) {
|
||||
t.Errorf("Expected probe: %+v\ngot: %+v\n", expectedProbe, actualProbe)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetDefaultSchedulerName(t *testing.T) {
|
||||
pod := &v1.Pod{}
|
||||
|
||||
output := roundTrip(t, runtime.Object(pod)).(*v1.Pod)
|
||||
if output.Spec.SchedulerName != v1.DefaultSchedulerName {
|
||||
t.Errorf("Expected scheduler name: %+v\ngot: %+v\n", v1.DefaultSchedulerName, output.Spec.SchedulerName)
|
||||
}
|
||||
}
|
||||
|
@ -2140,6 +2140,10 @@ type PodSpec struct {
|
||||
// If specified, the pod's scheduling constraints
|
||||
// +optional
|
||||
Affinity *Affinity `json:"affinity,omitempty" protobuf:"bytes,18,opt,name=affinity"`
|
||||
// If specified, the pod will be dispatched by specified scheduler.
|
||||
// If not specified, the pod will be dispatched by default scheduler.
|
||||
// +optional
|
||||
SchedulerName string `json:"schedulername,omitempty" protobuf:"bytes,19,opt,name=schedulername"`
|
||||
}
|
||||
|
||||
// PodSecurityContext holds pod-level security attributes and common container settings.
|
||||
|
@ -561,8 +561,7 @@ type KubeSchedulerConfiguration struct {
|
||||
// kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver.
|
||||
KubeAPIBurst int32
|
||||
// schedulerName is name of the scheduler, used to select which pods
|
||||
// will be processed by this scheduler, based on pod's annotation with
|
||||
// key 'scheduler.alpha.kubernetes.io/name'.
|
||||
// will be processed by this scheduler, based on pod's "spec.SchedulerName".
|
||||
SchedulerName string
|
||||
// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule
|
||||
// corresponding to every RequiredDuringScheduling affinity rule.
|
||||
|
@ -122,8 +122,7 @@ type KubeSchedulerConfiguration struct {
|
||||
// kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver.
|
||||
KubeAPIBurst int `json:"kubeAPIBurst"`
|
||||
// schedulerName is name of the scheduler, used to select which pods
|
||||
// will be processed by this scheduler, based on pod's annotation with
|
||||
// key 'scheduler.alpha.kubernetes.io/name'.
|
||||
// will be processed by this scheduler, based on pod's "spec.SchedulerName".
|
||||
SchedulerName string `json:"schedulerName"`
|
||||
// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule
|
||||
// corresponding to every RequiredDuringScheduling affinity rule.
|
||||
|
@ -40,6 +40,7 @@ func TestSetDefaultDaemonSet(t *testing.T) {
|
||||
RestartPolicy: v1.RestartPolicyAlways,
|
||||
SecurityContext: &v1.PodSecurityContext{},
|
||||
TerminationGracePeriodSeconds: &period,
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: defaultLabels,
|
||||
@ -51,6 +52,7 @@ func TestSetDefaultDaemonSet(t *testing.T) {
|
||||
RestartPolicy: v1.RestartPolicyAlways,
|
||||
SecurityContext: &v1.PodSecurityContext{},
|
||||
TerminationGracePeriodSeconds: &period,
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
}
|
||||
tests := []struct {
|
||||
@ -155,6 +157,7 @@ func TestSetDefaultDeployment(t *testing.T) {
|
||||
RestartPolicy: v1.RestartPolicyAlways,
|
||||
SecurityContext: &v1.PodSecurityContext{},
|
||||
TerminationGracePeriodSeconds: &period,
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
}
|
||||
tests := []struct {
|
||||
|
@ -131,6 +131,7 @@ func TestMerge(t *testing.T) {
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -53,6 +53,7 @@ func TestDecodeSinglePod(t *testing.T) {
|
||||
SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(),
|
||||
}},
|
||||
SecurityContext: &v1.PodSecurityContext{},
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
}
|
||||
json, err := runtime.Encode(testapi.Default.Codec(), pod)
|
||||
@ -113,6 +114,7 @@ func TestDecodePodList(t *testing.T) {
|
||||
SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(),
|
||||
}},
|
||||
SecurityContext: &v1.PodSecurityContext{},
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
}
|
||||
podList := &v1.PodList{
|
||||
|
@ -188,6 +188,7 @@ func getTestCases(hostname types.NodeName) []*testCase {
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{{Name: "image", Image: "test/image", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}},
|
||||
SecurityContext: &v1.PodSecurityContext{},
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodPending,
|
||||
@ -213,6 +214,7 @@ func getTestCases(hostname types.NodeName) []*testCase {
|
||||
ImagePullPolicy: "Always",
|
||||
SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}},
|
||||
SecurityContext: &v1.PodSecurityContext{},
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodPending,
|
||||
|
@ -147,6 +147,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
|
||||
NodeName: string(nodeName),
|
||||
Containers: []v1.Container{{Name: "1", Image: "foo", ImagePullPolicy: v1.PullAlways}},
|
||||
SecurityContext: &v1.PodSecurityContext{},
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodPending,
|
||||
@ -168,6 +169,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
|
||||
DNSPolicy: v1.DNSClusterFirst,
|
||||
SecurityContext: &v1.PodSecurityContext{},
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
|
||||
Containers: []v1.Container{{
|
||||
Name: "1",
|
||||
@ -198,6 +200,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
|
||||
NodeName: nodeName,
|
||||
Containers: []v1.Container{{Name: "1", Image: "foo", ImagePullPolicy: v1.PullAlways}},
|
||||
SecurityContext: &v1.PodSecurityContext{},
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodPending,
|
||||
@ -212,6 +215,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
|
||||
NodeName: nodeName,
|
||||
Containers: []v1.Container{{Name: "2", Image: "bar:bartag", ImagePullPolicy: ""}},
|
||||
SecurityContext: &v1.PodSecurityContext{},
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
Phase: v1.PodPending,
|
||||
@ -235,6 +239,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
|
||||
DNSPolicy: v1.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
SecurityContext: &v1.PodSecurityContext{},
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
|
||||
Containers: []v1.Container{{
|
||||
Name: "1",
|
||||
@ -261,6 +266,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
|
||||
DNSPolicy: v1.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
SecurityContext: &v1.PodSecurityContext{},
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
|
||||
Containers: []v1.Container{{
|
||||
Name: "2",
|
||||
|
@ -73,6 +73,7 @@ func validNewPod() *api.Pod {
|
||||
},
|
||||
},
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -659,6 +660,7 @@ func TestEtcdUpdateScheduled(t *testing.T) {
|
||||
},
|
||||
},
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
}, nil, 1)
|
||||
if err != nil {
|
||||
@ -687,6 +689,7 @@ func TestEtcdUpdateScheduled(t *testing.T) {
|
||||
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
}
|
||||
_, _, err = storage.Update(ctx, podIn.Name, rest.DefaultUpdatedObjectInfo(&podIn, api.Scheme))
|
||||
@ -727,6 +730,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
|
||||
},
|
||||
},
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
}
|
||||
err := storage.Storage.Create(ctx, key, &podStart, nil, 0)
|
||||
@ -751,6 +755,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
|
||||
},
|
||||
},
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
SchedulerName: api.DefaultSchedulerName,
|
||||
},
|
||||
Status: api.PodStatus{
|
||||
Phase: api.PodRunning,
|
||||
|
@ -66,7 +66,7 @@ func (s *SchedulerServer) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "Content type of requests sent to apiserver.")
|
||||
fs.Float32Var(&s.KubeAPIQPS, "kube-api-qps", s.KubeAPIQPS, "QPS to use while talking with kubernetes apiserver")
|
||||
fs.Int32Var(&s.KubeAPIBurst, "kube-api-burst", s.KubeAPIBurst, "Burst to use while talking with kubernetes apiserver")
|
||||
fs.StringVar(&s.SchedulerName, "scheduler-name", s.SchedulerName, "Name of the scheduler, used to select which pods will be processed by this scheduler, based on pod's annotation with key 'scheduler.alpha.kubernetes.io/name'")
|
||||
fs.StringVar(&s.SchedulerName, "scheduler-name", s.SchedulerName, "Name of the scheduler, used to select which pods will be processed by this scheduler, based on pod's \"spec.SchedulerName\".")
|
||||
fs.IntVar(&s.HardPodAffinitySymmetricWeight, "hard-pod-affinity-symmetric-weight", api.DefaultHardPodAffinitySymmetricWeight,
|
||||
"RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule corresponding "+
|
||||
"to every RequiredDuringScheduling affinity rule. --hard-pod-affinity-symmetric-weight represents the weight of implicit PreferredDuringScheduling affinity rule.")
|
||||
|
@ -48,9 +48,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
SchedulerAnnotationKey = "scheduler.alpha.kubernetes.io/name"
|
||||
initialGetBackoff = 100 * time.Millisecond
|
||||
maximalGetBackoff = time.Minute
|
||||
initialGetBackoff = 100 * time.Millisecond
|
||||
maximalGetBackoff = time.Minute
|
||||
)
|
||||
|
||||
// ConfigFactory is the default implementation of the scheduler.Configurator interface.
|
||||
@ -90,8 +89,7 @@ type ConfigFactory struct {
|
||||
schedulerCache schedulercache.Cache
|
||||
|
||||
// SchedulerName of a scheduler is used to select which pods will be
|
||||
// processed by this scheduler, based on pods's annotation key:
|
||||
// 'scheduler.alpha.kubernetes.io/name'
|
||||
// processed by this scheduler, based on pods's "spec.SchedulerName".
|
||||
schedulerName string
|
||||
|
||||
// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule
|
||||
@ -514,11 +512,7 @@ func (f *ConfigFactory) getNextPod() *v1.Pod {
|
||||
}
|
||||
|
||||
func (f *ConfigFactory) ResponsibleForPod(pod *v1.Pod) bool {
|
||||
if f.schedulerName == v1.DefaultSchedulerName {
|
||||
return pod.Annotations[SchedulerAnnotationKey] == f.schedulerName || pod.Annotations[SchedulerAnnotationKey] == ""
|
||||
} else {
|
||||
return pod.Annotations[SchedulerAnnotationKey] == f.schedulerName
|
||||
}
|
||||
return f.schedulerName == pod.Spec.SchedulerName
|
||||
}
|
||||
|
||||
func getNodeConditionPredicate() cache.NodeConditionPredicate {
|
||||
|
@ -251,39 +251,33 @@ func TestResponsibleForPod(t *testing.T) {
|
||||
// factory of "foo-scheduler"
|
||||
factoryFooScheduler := NewConfigFactory(client, "foo-scheduler", v1.DefaultHardPodAffinitySymmetricWeight, v1.DefaultFailureDomains)
|
||||
// scheduler annotations to be tested
|
||||
schedulerAnnotationFitsDefault := map[string]string{"scheduler.alpha.kubernetes.io/name": "default-scheduler"}
|
||||
schedulerAnnotationFitsFoo := map[string]string{"scheduler.alpha.kubernetes.io/name": "foo-scheduler"}
|
||||
schedulerAnnotationFitsNone := map[string]string{"scheduler.alpha.kubernetes.io/name": "bar-scheduler"}
|
||||
schedulerFitsDefault := "default-scheduler"
|
||||
schedulerFitsFoo := "foo-scheduler"
|
||||
schedulerFitsNone := "bar-scheduler"
|
||||
|
||||
tests := []struct {
|
||||
pod *v1.Pod
|
||||
pickedByDefault bool
|
||||
pickedByFoo bool
|
||||
}{
|
||||
{
|
||||
// pod with no annotation "scheduler.alpha.kubernetes.io/name=<scheduler-name>" should be
|
||||
// picked by the default scheduler, NOT by the one of name "foo-scheduler"
|
||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}},
|
||||
pickedByDefault: true,
|
||||
pickedByFoo: false,
|
||||
},
|
||||
{
|
||||
// pod with annotation "scheduler.alpha.kubernetes.io/name=default-scheduler" should be picked
|
||||
// pod with "spec.Schedulername=default-scheduler" should be picked
|
||||
// by the scheduler of name "default-scheduler", NOT by the one of name "foo-scheduler"
|
||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar", Annotations: schedulerAnnotationFitsDefault}},
|
||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, Spec: v1.PodSpec{SchedulerName: schedulerFitsDefault}},
|
||||
pickedByDefault: true,
|
||||
pickedByFoo: false,
|
||||
},
|
||||
{
|
||||
// pod with annotataion "scheduler.alpha.kubernetes.io/name=foo-scheduler" should be NOT
|
||||
// pod with "spec.SchedulerName=foo-scheduler" should be NOT
|
||||
// be picked by the scheduler of name "default-scheduler", but by the one of name "foo-scheduler"
|
||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar", Annotations: schedulerAnnotationFitsFoo}},
|
||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, Spec: v1.PodSpec{SchedulerName: schedulerFitsFoo}},
|
||||
pickedByDefault: false,
|
||||
pickedByFoo: true,
|
||||
},
|
||||
{
|
||||
// pod with annotataion "scheduler.alpha.kubernetes.io/name=foo-scheduler" should be NOT
|
||||
// pod with "spec.SchedulerName=foo-scheduler" should be NOT
|
||||
// be picked by niether the scheduler of name "default-scheduler" nor the one of name "foo-scheduler"
|
||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar", Annotations: schedulerAnnotationFitsNone}},
|
||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, Spec: v1.PodSpec{SchedulerName: schedulerFitsNone}},
|
||||
pickedByDefault: false,
|
||||
pickedByFoo: false,
|
||||
},
|
||||
|
@ -561,8 +561,7 @@ type KubeSchedulerConfiguration struct {
|
||||
// kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver.
|
||||
KubeAPIBurst int32
|
||||
// schedulerName is name of the scheduler, used to select which pods
|
||||
// will be processed by this scheduler, based on pod's annotation with
|
||||
// key 'scheduler.alpha.kubernetes.io/name'.
|
||||
// will be processed by this scheduler, based on pod's "spec.SchedulerName".
|
||||
SchedulerName string
|
||||
// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule
|
||||
// corresponding to every RequiredDuringScheduling affinity rule.
|
||||
|
@ -122,8 +122,7 @@ type KubeSchedulerConfiguration struct {
|
||||
// kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver.
|
||||
KubeAPIBurst int `json:"kubeAPIBurst"`
|
||||
// schedulerName is name of the scheduler, used to select which pods
|
||||
// will be processed by this scheduler, based on pod's annotation with
|
||||
// key 'scheduler.alpha.kubernetes.io/name'.
|
||||
// will be processed by this scheduler, based on pod's "spec.SchedulerName".
|
||||
SchedulerName string `json:"schedulerName"`
|
||||
// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule
|
||||
// corresponding to every RequiredDuringScheduling affinity rule.
|
||||
|
@ -84,9 +84,6 @@ func createTerminatingPod(f *framework.Framework) (*v1.Pod, error) {
|
||||
pod := &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: string(uuid),
|
||||
Annotations: map[string]string{
|
||||
"scheduler.alpha.kubernetes.io/name": "please don't schedule my pods",
|
||||
},
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{
|
||||
@ -95,6 +92,7 @@ func createTerminatingPod(f *framework.Framework) (*v1.Pod, error) {
|
||||
Image: "gcr.io/google_containers/busybox:1.24",
|
||||
},
|
||||
},
|
||||
SchedulerName: "please don't schedule my pods",
|
||||
},
|
||||
}
|
||||
return f.ClientSet.Core().Pods(f.Namespace.Name).Create(pod)
|
||||
|
@ -352,48 +352,48 @@ func TestMultiScheduler(t *testing.T) {
|
||||
clientSet.Core().Nodes().Create(node)
|
||||
|
||||
// 3. create 3 pods for testing
|
||||
podWithNoAnnotation := createPod(clientSet, "pod-with-no-annotation", nil)
|
||||
testPodNoAnnotation, err := clientSet.Core().Pods(ns.Name).Create(podWithNoAnnotation)
|
||||
podWithoutSchedulerName := createPod(clientSet, "pod-without-scheduler-name", "")
|
||||
testPod, err := clientSet.Core().Pods(ns.Name).Create(podWithoutSchedulerName)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create pod: %v", err)
|
||||
}
|
||||
|
||||
schedulerAnnotationFitsDefault := map[string]string{"scheduler.alpha.kubernetes.io/name": "default-scheduler"}
|
||||
podWithAnnotationFitsDefault := createPod(clientSet, "pod-with-annotation-fits-default", schedulerAnnotationFitsDefault)
|
||||
testPodWithAnnotationFitsDefault, err := clientSet.Core().Pods(ns.Name).Create(podWithAnnotationFitsDefault)
|
||||
schedulerFitsDefault := "default-scheduler"
|
||||
podFitsDefault := createPod(clientSet, "pod-fits-default", schedulerFitsDefault)
|
||||
testPodFitsDefault, err := clientSet.Core().Pods(ns.Name).Create(podFitsDefault)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create pod: %v", err)
|
||||
}
|
||||
|
||||
schedulerAnnotationFitsFoo := map[string]string{"scheduler.alpha.kubernetes.io/name": "foo-scheduler"}
|
||||
podWithAnnotationFitsFoo := createPod(clientSet, "pod-with-annotation-fits-foo", schedulerAnnotationFitsFoo)
|
||||
testPodWithAnnotationFitsFoo, err := clientSet.Core().Pods(ns.Name).Create(podWithAnnotationFitsFoo)
|
||||
schedulerFitsFoo := "foo-scheduler"
|
||||
podFitsFoo := createPod(clientSet, "pod-fits-foo", schedulerFitsFoo)
|
||||
testPodFitsFoo, err := clientSet.Core().Pods(ns.Name).Create(podFitsFoo)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create pod: %v", err)
|
||||
}
|
||||
|
||||
// 4. **check point-1**:
|
||||
// - testPodNoAnnotation, testPodWithAnnotationFitsDefault should be scheduled
|
||||
// - testPodWithAnnotationFitsFoo should NOT be scheduled
|
||||
err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodNoAnnotation.Namespace, testPodNoAnnotation.Name))
|
||||
// - testPod, testPodFitsDefault should be scheduled
|
||||
// - testPodFitsFoo should NOT be scheduled
|
||||
err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPod.Namespace, testPod.Name))
|
||||
if err != nil {
|
||||
t.Errorf("Test MultiScheduler: %s Pod not scheduled: %v", testPodNoAnnotation.Name, err)
|
||||
t.Errorf("Test MultiScheduler: %s Pod not scheduled: %v", testPod.Name, err)
|
||||
} else {
|
||||
t.Logf("Test MultiScheduler: %s Pod scheduled", testPodNoAnnotation.Name)
|
||||
t.Logf("Test MultiScheduler: %s Pod scheduled", testPod.Name)
|
||||
}
|
||||
|
||||
err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodWithAnnotationFitsDefault.Namespace, testPodWithAnnotationFitsDefault.Name))
|
||||
err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodFitsDefault.Namespace, testPodFitsDefault.Name))
|
||||
if err != nil {
|
||||
t.Errorf("Test MultiScheduler: %s Pod not scheduled: %v", testPodWithAnnotationFitsDefault.Name, err)
|
||||
t.Errorf("Test MultiScheduler: %s Pod not scheduled: %v", testPodFitsDefault.Name, err)
|
||||
} else {
|
||||
t.Logf("Test MultiScheduler: %s Pod scheduled", testPodWithAnnotationFitsDefault.Name)
|
||||
t.Logf("Test MultiScheduler: %s Pod scheduled", testPodFitsDefault.Name)
|
||||
}
|
||||
|
||||
err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodWithAnnotationFitsFoo.Namespace, testPodWithAnnotationFitsFoo.Name))
|
||||
err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodFitsFoo.Namespace, testPodFitsFoo.Name))
|
||||
if err == nil {
|
||||
t.Errorf("Test MultiScheduler: %s Pod got scheduled, %v", testPodWithAnnotationFitsFoo.Name, err)
|
||||
t.Errorf("Test MultiScheduler: %s Pod got scheduled, %v", testPodFitsFoo.Name, err)
|
||||
} else {
|
||||
t.Logf("Test MultiScheduler: %s Pod not scheduled", testPodWithAnnotationFitsFoo.Name)
|
||||
t.Logf("Test MultiScheduler: %s Pod not scheduled", testPodFitsFoo.Name)
|
||||
}
|
||||
|
||||
// 5. create and start a scheduler with name "foo-scheduler"
|
||||
@ -413,19 +413,19 @@ func TestMultiScheduler(t *testing.T) {
|
||||
|
||||
// 6. **check point-2**:
|
||||
// - testPodWithAnnotationFitsFoo should be scheduled
|
||||
err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodWithAnnotationFitsFoo.Namespace, testPodWithAnnotationFitsFoo.Name))
|
||||
err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodFitsFoo.Namespace, testPodFitsFoo.Name))
|
||||
if err != nil {
|
||||
t.Errorf("Test MultiScheduler: %s Pod not scheduled, %v", testPodWithAnnotationFitsFoo.Name, err)
|
||||
t.Errorf("Test MultiScheduler: %s Pod not scheduled, %v", testPodFitsFoo.Name, err)
|
||||
} else {
|
||||
t.Logf("Test MultiScheduler: %s Pod scheduled", testPodWithAnnotationFitsFoo.Name)
|
||||
t.Logf("Test MultiScheduler: %s Pod scheduled", testPodFitsFoo.Name)
|
||||
}
|
||||
|
||||
// 7. delete the pods that were scheduled by the default scheduler, and stop the default scheduler
|
||||
err = clientSet.Core().Pods(ns.Name).Delete(testPodNoAnnotation.Name, v1.NewDeleteOptions(0))
|
||||
err = clientSet.Core().Pods(ns.Name).Delete(testPod.Name, v1.NewDeleteOptions(0))
|
||||
if err != nil {
|
||||
t.Errorf("Failed to delete pod: %v", err)
|
||||
}
|
||||
err = clientSet.Core().Pods(ns.Name).Delete(testPodWithAnnotationFitsDefault.Name, v1.NewDeleteOptions(0))
|
||||
err = clientSet.Core().Pods(ns.Name).Delete(testPodFitsDefault.Name, v1.NewDeleteOptions(0))
|
||||
if err != nil {
|
||||
t.Errorf("Failed to delete pod: %v", err)
|
||||
}
|
||||
@ -469,11 +469,12 @@ func TestMultiScheduler(t *testing.T) {
|
||||
*/
|
||||
}
|
||||
|
||||
func createPod(client clientset.Interface, name string, annotation map[string]string) *v1.Pod {
|
||||
func createPod(client clientset.Interface, name string, scheduler string) *v1.Pod {
|
||||
return &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: name, Annotations: annotation},
|
||||
ObjectMeta: metav1.ObjectMeta{Name: name},
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{{Name: "container", Image: e2e.GetPauseImageName(client)}},
|
||||
Containers: []v1.Container{{Name: "container", Image: e2e.GetPauseImageName(client)}},
|
||||
SchedulerName: scheduler,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user