diff --git a/pkg/scheduler/generic_scheduler.go b/pkg/scheduler/generic_scheduler.go index 0aa679274ae..7a2542daa0a 100644 --- a/pkg/scheduler/generic_scheduler.go +++ b/pkg/scheduler/generic_scheduler.go @@ -135,6 +135,13 @@ func findNodesThatFit(pod api.Pod, podLister PodLister, predicates map[string]Fi // All scores are finally combined (added) to get the total weighted scores of all minions func prioritizeNodes(pod api.Pod, podLister PodLister, priorityConfigs []PriorityConfig, minionLister MinionLister) (HostPriorityList, error) { result := HostPriorityList{} + + // If no priority configs are provided, then the EqualPriority function is applied + // This is required to generate the priority list in the required format + if len(priorityConfigs) == 0 { + return EqualPriority(pod, podLister, minionLister) + } + combinedScores := map[string]int{} for _, priorityConfig := range priorityConfigs { weight := priorityConfig.Weight diff --git a/plugin/pkg/scheduler/api/latest/latest.go b/plugin/pkg/scheduler/api/latest/latest.go index b2e544253cd..73551248e38 100644 --- a/plugin/pkg/scheduler/api/latest/latest.go +++ b/plugin/pkg/scheduler/api/latest/latest.go @@ -33,6 +33,6 @@ const OldestVersion = "v1" var Versions = []string{"v1"} // Codec is the default codec for serializing input that should use -// the latest supported version. Use this Codec when reading from the file. +// the latest supported version. // This codec can decode any object that Kubernetes is aware of. var Codec = v1.Codec diff --git a/plugin/pkg/scheduler/factory/factory_test.go b/plugin/pkg/scheduler/factory/factory_test.go index f07fe4daf68..c23b8a2b830 100644 --- a/plugin/pkg/scheduler/factory/factory_test.go +++ b/plugin/pkg/scheduler/factory/factory_test.go @@ -30,7 +30,10 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" + algorithm "github.com/GoogleCloudPlatform/kubernetes/pkg/scheduler" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" + schedulerapi "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/api" + latestschedulerapi "github.com/GoogleCloudPlatform/kubernetes/plugin/pkg/scheduler/api/latest" ) func TestCreate(t *testing.T) { @@ -46,6 +49,76 @@ func TestCreate(t *testing.T) { factory.Create() } +func TestCreateFromConfig(t *testing.T) { + var configData []byte + var policy schedulerapi.Policy + + handler := util.FakeHandler{ + StatusCode: 500, + ResponseBody: "", + T: t, + } + server := httptest.NewServer(&handler) + defer server.Close() + client := client.NewOrDie(&client.Config{Host: server.URL, Version: testapi.Version()}) + factory := NewConfigFactory(client) + + // Register the predicate and priority functions + // These would be registered by the DefaultProvider in regular operation + RegisterFitPredicate("PodFitsPorts", algorithm.PodFitsPorts) + RegisterFitPredicate("PodFitsResources", algorithm.NewResourceFitPredicate(MinionLister)) + RegisterFitPredicate("NoDiskConflict", algorithm.NoDiskConflict) + RegisterFitPredicate("MatchNodeSelector", algorithm.NewSelectorMatchPredicate(MinionLister)) + RegisterFitPredicate("HostName", algorithm.PodFitsHost) + RegisterPriorityFunction("LeastRequestedPriority", algorithm.LeastRequestedPriority, 1) + RegisterPriorityFunction("ServiceSpreadingPriority", algorithm.NewServiceSpreadPriority(ServiceLister), 1) + RegisterPriorityFunction("EqualPriority", algorithm.EqualPriority, 0) + + configData = []byte(`{ + "kind" : "Policy", + "apiVersion" : "v1", + "predicates" : [ + {"name" : "TestZoneAffinity", "argument" : {"serviceAffinity" : {"labels" : ["zone"]}}}, + {"name" : "TestRequireZone", "argument" : {"labelsPresence" : {"labels" : ["zone"], "presence" : true}}}, + {"name" : "PodFitsPorts"}, + {"name" : "MatchNodeSelector"} + ], + "priorities" : [ + {"name" : "RackSpread", "weight" : 2, "argument" : {"serviceAntiAffinity" : {"label" : "rack"}}}, + {"name" : "ServiceSpreadingPriority", "weight" : 1} + ] + }`) + err := latestschedulerapi.Codec.DecodeInto(configData, &policy) + if err != nil { + t.Errorf("Invalid configuration: %v", err) + } + + factory.CreateFromConfig(policy) +} + +func TestCreateFromEmptyConfig(t *testing.T) { + var configData []byte + var policy schedulerapi.Policy + + handler := util.FakeHandler{ + StatusCode: 500, + ResponseBody: "", + T: t, + } + server := httptest.NewServer(&handler) + defer server.Close() + client := client.NewOrDie(&client.Config{Host: server.URL, Version: testapi.Version()}) + factory := NewConfigFactory(client) + + configData = []byte(`{}`) + err := latestschedulerapi.Codec.DecodeInto(configData, &policy) + if err != nil { + t.Errorf("Invalid configuration: %v", err) + } + + factory.CreateFromConfig(policy) +} + func TestPollMinions(t *testing.T) { table := []struct { minions []api.Node