diff --git a/plugin/pkg/scheduler/algorithm/priorities/priorities_test.go b/plugin/pkg/scheduler/algorithm/priorities/priorities_test.go index eb78285256c..6d09c0127e3 100644 --- a/plugin/pkg/scheduler/algorithm/priorities/priorities_test.go +++ b/plugin/pkg/scheduler/algorithm/priorities/priorities_test.go @@ -145,7 +145,18 @@ func TestZeroRequest(t *testing.T) { // This should match the configuration in defaultPriorities() in // plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go if you want // to test what's actually in production. - []algorithm.PriorityConfig{{Function: LeastRequestedPriority, Weight: 1}, {Function: BalancedResourceAllocation, Weight: 1}, {Function: NewSelectorSpreadPriority(algorithm.FakePodLister(test.pods), algorithm.FakeServiceLister([]api.Service{}), algorithm.FakeControllerLister([]api.ReplicationController{}), algorithm.FakeReplicaSetLister([]extensions.ReplicaSet{})), Weight: 1}}, + []algorithm.PriorityConfig{ + {Function: LeastRequestedPriority, Weight: 1}, + {Function: BalancedResourceAllocation, Weight: 1}, + { + Function: NewSelectorSpreadPriority( + algorithm.FakePodLister(test.pods), + algorithm.FakeServiceLister([]api.Service{}), + algorithm.FakeControllerLister([]api.ReplicationController{}), + algorithm.FakeReplicaSetLister([]extensions.ReplicaSet{})), + Weight: 1, + }, + }, algorithm.FakeNodeLister(test.nodes), []algorithm.SchedulerExtender{}) if err != nil { t.Errorf("unexpected error: %v", err) diff --git a/plugin/pkg/scheduler/algorithm/priorities/selector_spreading.go b/plugin/pkg/scheduler/algorithm/priorities/selector_spreading.go index c2331f3607d..14bd4afea37 100644 --- a/plugin/pkg/scheduler/algorithm/priorities/selector_spreading.go +++ b/plugin/pkg/scheduler/algorithm/priorities/selector_spreading.go @@ -45,7 +45,11 @@ type SelectorSpread struct { replicaSetLister algorithm.ReplicaSetLister } -func NewSelectorSpreadPriority(podLister algorithm.PodLister, serviceLister algorithm.ServiceLister, controllerLister algorithm.ControllerLister, replicaSetLister algorithm.ReplicaSetLister) algorithm.PriorityFunction { +func NewSelectorSpreadPriority( + podLister algorithm.PodLister, + serviceLister algorithm.ServiceLister, + controllerLister algorithm.ControllerLister, + replicaSetLister algorithm.ReplicaSetLister) algorithm.PriorityFunction { selectorSpread := &SelectorSpread{ podLister: podLister, serviceLister: serviceLister, diff --git a/plugin/pkg/scheduler/algorithm/priorities/selector_spreading_test.go b/plugin/pkg/scheduler/algorithm/priorities/selector_spreading_test.go index 302a7de11f0..d8a6c25abbf 100644 --- a/plugin/pkg/scheduler/algorithm/priorities/selector_spreading_test.go +++ b/plugin/pkg/scheduler/algorithm/priorities/selector_spreading_test.go @@ -23,13 +23,21 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/unversioned" - wellknownlabels "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm" schedulerapi "k8s.io/kubernetes/plugin/pkg/scheduler/api" "k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache" ) +func controllerRef(kind, name, uid string) []api.OwnerReference { + // TODO: When ControllerRef will be implemented uncomment code below. + return nil + //trueVar := true + //return []api.OwnerReference{ + // {Kind: kind, Name: name, UID: types.UID(uid), Controller: &trueVar}, + //} +} + func TestSelectorSpreadPriority(t *testing.T) { labels1 := map[string]string{ "foo": "bar", @@ -166,11 +174,11 @@ func TestSelectorSpreadPriority(t *testing.T) { test: "service with partial pod label matches", }, { - pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}}, + pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicationController", "name", "abc123")}}, pods: []*api.Pod{ {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels2}}, - {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels1}}, - {Spec: zone2Spec, ObjectMeta: api.ObjectMeta{Labels: labels1}}, + {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicationController", "name", "abc123")}}, + {Spec: zone2Spec, ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicationController", "name", "abc123")}}, }, nodes: []string{"machine1", "machine2"}, services: []api.Service{{Spec: api.ServiceSpec{Selector: map[string]string{"baz": "blah"}}}}, @@ -181,25 +189,25 @@ func TestSelectorSpreadPriority(t *testing.T) { test: "service with partial pod label matches with service and replication controller", }, { - pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}}, + pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicaSet", "name", "abc123")}}, pods: []*api.Pod{ {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels2}}, - {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels1}}, - {Spec: zone2Spec, ObjectMeta: api.ObjectMeta{Labels: labels1}}, + {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicaSet", "name", "abc123")}}, + {Spec: zone2Spec, ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicaSet", "name", "abc123")}}, }, nodes: []string{"machine1", "machine2"}, services: []api.Service{{Spec: api.ServiceSpec{Selector: map[string]string{"baz": "blah"}}}}, rss: []extensions.ReplicaSet{{Spec: extensions.ReplicaSetSpec{Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}}}}, // We use ReplicaSet, instead of ReplicationController. The result should be exactly as above. expectedList: []schedulerapi.HostPriority{{"machine1", 0}, {"machine2", 5}}, - test: "service with partial pod label matches with service and replication controller", + test: "service with partial pod label matches with service and replica set", }, { - pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: map[string]string{"foo": "bar", "bar": "foo"}}}, + pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: map[string]string{"foo": "bar", "bar": "foo"}, OwnerReferences: controllerRef("ReplicationController", "name", "abc123")}}, pods: []*api.Pod{ {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels2}}, - {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels1}}, - {Spec: zone2Spec, ObjectMeta: api.ObjectMeta{Labels: labels1}}, + {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicationController", "name", "abc123")}}, + {Spec: zone2Spec, ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicationController", "name", "abc123")}}, }, nodes: []string{"machine1", "machine2"}, services: []api.Service{{Spec: api.ServiceSpec{Selector: map[string]string{"bar": "foo"}}}}, @@ -209,25 +217,25 @@ func TestSelectorSpreadPriority(t *testing.T) { test: "disjoined service and replication controller should be treated equally", }, { - pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: map[string]string{"foo": "bar", "bar": "foo"}}}, + pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: map[string]string{"foo": "bar", "bar": "foo"}, OwnerReferences: controllerRef("ReplicaSet", "name", "abc123")}}, pods: []*api.Pod{ {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels2}}, - {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels1}}, - {Spec: zone2Spec, ObjectMeta: api.ObjectMeta{Labels: labels1}}, + {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicaSet", "name", "abc123")}}, + {Spec: zone2Spec, ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicaSet", "name", "abc123")}}, }, nodes: []string{"machine1", "machine2"}, services: []api.Service{{Spec: api.ServiceSpec{Selector: map[string]string{"bar": "foo"}}}}, rss: []extensions.ReplicaSet{{Spec: extensions.ReplicaSetSpec{Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}}}}, // We use ReplicaSet, instead of ReplicationController. The result should be exactly as above. expectedList: []schedulerapi.HostPriority{{"machine1", 0}, {"machine2", 5}}, - test: "disjoined service and replication controller should be treated equally", + test: "disjoined service and replica set should be treated equally", }, { - pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}}, + pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicationController", "name", "abc123")}}, pods: []*api.Pod{ {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels2}}, - {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels1}}, - {Spec: zone2Spec, ObjectMeta: api.ObjectMeta{Labels: labels1}}, + {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicationController", "name", "abc123")}}, + {Spec: zone2Spec, ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicationController", "name", "abc123")}}, }, nodes: []string{"machine1", "machine2"}, rcs: []api.ReplicationController{{Spec: api.ReplicationControllerSpec{Selector: map[string]string{"foo": "bar"}}}}, @@ -236,48 +244,53 @@ func TestSelectorSpreadPriority(t *testing.T) { test: "Replication controller with partial pod label matches", }, { - pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}}, + pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicaSet", "name", "abc123")}}, pods: []*api.Pod{ {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels2}}, - {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels1}}, - {Spec: zone2Spec, ObjectMeta: api.ObjectMeta{Labels: labels1}}, + {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicaSet", "name", "abc123")}}, + {Spec: zone2Spec, ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicaSet", "name", "abc123")}}, }, nodes: []string{"machine1", "machine2"}, rss: []extensions.ReplicaSet{{Spec: extensions.ReplicaSetSpec{Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}}}}, // We use ReplicaSet, instead of ReplicationController. The result should be exactly as above. expectedList: []schedulerapi.HostPriority{{"machine1", 0}, {"machine2", 0}}, - test: "Replication controller with partial pod label matches", + test: "Replica set with partial pod label matches", }, { - pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}}, + pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicationController", "name", "abc123")}}, pods: []*api.Pod{ - {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels2}}, - {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels1}}, - {Spec: zone2Spec, ObjectMeta: api.ObjectMeta{Labels: labels1}}, + {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels2, OwnerReferences: controllerRef("ReplicationController", "name", "abc123")}}, + {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicationController", "name", "abc123")}}, + {Spec: zone2Spec, ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicationController", "name", "abc123")}}, }, nodes: []string{"machine1", "machine2"}, rcs: []api.ReplicationController{{Spec: api.ReplicationControllerSpec{Selector: map[string]string{"baz": "blah"}}}}, expectedList: []schedulerapi.HostPriority{{"machine1", 0}, {"machine2", 5}}, - test: "Replication controller with partial pod label matches", + test: "Another replication controller with partial pod label matches", }, { - pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}}, + pod: &api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicaSet", "name", "abc123")}}, pods: []*api.Pod{ - {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels2}}, - {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels1}}, - {Spec: zone2Spec, ObjectMeta: api.ObjectMeta{Labels: labels1}}, + {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels2, OwnerReferences: controllerRef("ReplicaSet", "name", "abc123")}}, + {Spec: zone1Spec, ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicaSet", "name", "abc123")}}, + {Spec: zone2Spec, ObjectMeta: api.ObjectMeta{Labels: labels1, OwnerReferences: controllerRef("ReplicaSet", "name", "abc123")}}, }, nodes: []string{"machine1", "machine2"}, rss: []extensions.ReplicaSet{{Spec: extensions.ReplicaSetSpec{Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"baz": "blah"}}}}}, // We use ReplicaSet, instead of ReplicationController. The result should be exactly as above. expectedList: []schedulerapi.HostPriority{{"machine1", 0}, {"machine2", 5}}, - test: "Replication controller with partial pod label matches", + test: "Another replication set with partial pod label matches", }, } for _, test := range tests { nodeNameToInfo := schedulercache.CreateNodeNameToInfoMap(test.pods, nil) - selectorSpread := SelectorSpread{podLister: algorithm.FakePodLister(test.pods), serviceLister: algorithm.FakeServiceLister(test.services), controllerLister: algorithm.FakeControllerLister(test.rcs), replicaSetLister: algorithm.FakeReplicaSetLister(test.rss)} + selectorSpread := SelectorSpread{ + podLister: algorithm.FakePodLister(test.pods), + serviceLister: algorithm.FakeServiceLister(test.services), + controllerLister: algorithm.FakeControllerLister(test.rcs), + replicaSetLister: algorithm.FakeReplicaSetLister(test.rss), + } list, err := selectorSpread.CalculateSpreadPriority(test.pod, nodeNameToInfo, makeNodeList(test.nodes)) if err != nil { t.Errorf("unexpected error: %v", err) @@ -288,6 +301,13 @@ func TestSelectorSpreadPriority(t *testing.T) { } } +func buildPod(nodeName string, labels map[string]string, ownerRefs []api.OwnerReference) *api.Pod { + return &api.Pod{ + ObjectMeta: api.ObjectMeta{Labels: labels, OwnerReferences: ownerRefs}, + Spec: api.PodSpec{NodeName: nodeName}, + } +} + func TestZoneSelectorSpreadPriority(t *testing.T) { labels1 := map[string]string{ "label1": "l1", @@ -307,7 +327,7 @@ func TestZoneSelectorSpreadPriority(t *testing.T) { buildNodeLabels := func(failureDomain string) map[string]string { labels := map[string]string{ - wellknownlabels.LabelZoneFailureDomain: failureDomain, + unversioned.LabelZoneFailureDomain: failureDomain, } return labels } @@ -320,11 +340,6 @@ func TestZoneSelectorSpreadPriority(t *testing.T) { nodeMachine3Zone3: buildNodeLabels("zone3"), } - buildPod := func(nodeName string, labels map[string]string) *api.Pod { - pod := &api.Pod{Spec: api.PodSpec{NodeName: nodeName}, ObjectMeta: api.ObjectMeta{Labels: labels}} - return pod - } - tests := []struct { pod *api.Pod pods []*api.Pod @@ -348,8 +363,8 @@ func TestZoneSelectorSpreadPriority(t *testing.T) { test: "nothing scheduled", }, { - pod: buildPod("", labels1), - pods: []*api.Pod{buildPod(nodeMachine1Zone1, nil)}, + pod: buildPod("", labels1, nil), + pods: []*api.Pod{buildPod(nodeMachine1Zone1, nil, nil)}, expectedList: []schedulerapi.HostPriority{ {nodeMachine1Zone1, 10}, {nodeMachine1Zone2, 10}, @@ -361,8 +376,8 @@ func TestZoneSelectorSpreadPriority(t *testing.T) { test: "no services", }, { - pod: buildPod("", labels1), - pods: []*api.Pod{buildPod(nodeMachine1Zone1, labels2)}, + pod: buildPod("", labels1, nil), + pods: []*api.Pod{buildPod(nodeMachine1Zone1, labels2, nil)}, services: []api.Service{{Spec: api.ServiceSpec{Selector: map[string]string{"key": "value"}}}}, expectedList: []schedulerapi.HostPriority{ {nodeMachine1Zone1, 10}, @@ -375,10 +390,10 @@ func TestZoneSelectorSpreadPriority(t *testing.T) { test: "different services", }, { - pod: buildPod("", labels1), + pod: buildPod("", labels1, nil), pods: []*api.Pod{ - buildPod(nodeMachine1Zone1, labels2), - buildPod(nodeMachine1Zone2, labels1), + buildPod(nodeMachine1Zone1, labels2, nil), + buildPod(nodeMachine1Zone2, labels1, nil), }, services: []api.Service{{Spec: api.ServiceSpec{Selector: labels1}}}, expectedList: []schedulerapi.HostPriority{ @@ -392,13 +407,13 @@ func TestZoneSelectorSpreadPriority(t *testing.T) { test: "two pods, 1 matching (in z2)", }, { - pod: buildPod("", labels1), + pod: buildPod("", labels1, nil), pods: []*api.Pod{ - buildPod(nodeMachine1Zone1, labels2), - buildPod(nodeMachine1Zone2, labels1), - buildPod(nodeMachine2Zone2, labels1), - buildPod(nodeMachine1Zone3, labels2), - buildPod(nodeMachine2Zone3, labels1), + buildPod(nodeMachine1Zone1, labels2, nil), + buildPod(nodeMachine1Zone2, labels1, nil), + buildPod(nodeMachine2Zone2, labels1, nil), + buildPod(nodeMachine1Zone3, labels2, nil), + buildPod(nodeMachine2Zone3, labels1, nil), }, services: []api.Service{{Spec: api.ServiceSpec{Selector: labels1}}}, expectedList: []schedulerapi.HostPriority{ @@ -412,12 +427,12 @@ func TestZoneSelectorSpreadPriority(t *testing.T) { test: "five pods, 3 matching (z2=2, z3=1)", }, { - pod: buildPod("", labels1), + pod: buildPod("", labels1, nil), pods: []*api.Pod{ - buildPod(nodeMachine1Zone1, labels1), - buildPod(nodeMachine1Zone2, labels1), - buildPod(nodeMachine2Zone2, labels2), - buildPod(nodeMachine1Zone3, labels1), + buildPod(nodeMachine1Zone1, labels1, nil), + buildPod(nodeMachine1Zone2, labels1, nil), + buildPod(nodeMachine2Zone2, labels2, nil), + buildPod(nodeMachine1Zone3, labels1, nil), }, services: []api.Service{{Spec: api.ServiceSpec{Selector: labels1}}}, expectedList: []schedulerapi.HostPriority{ @@ -431,12 +446,12 @@ func TestZoneSelectorSpreadPriority(t *testing.T) { test: "four pods, 3 matching (z1=1, z2=1, z3=1)", }, { - pod: buildPod("", labels1), + pod: buildPod("", labels1, nil), pods: []*api.Pod{ - buildPod(nodeMachine1Zone1, labels1), - buildPod(nodeMachine1Zone2, labels1), - buildPod(nodeMachine1Zone3, labels1), - buildPod(nodeMachine2Zone2, labels2), + buildPod(nodeMachine1Zone1, labels1, nil), + buildPod(nodeMachine1Zone2, labels1, nil), + buildPod(nodeMachine1Zone3, labels1, nil), + buildPod(nodeMachine2Zone2, labels2, nil), }, services: []api.Service{{Spec: api.ServiceSpec{Selector: labels1}}}, expectedList: []schedulerapi.HostPriority{ @@ -450,11 +465,11 @@ func TestZoneSelectorSpreadPriority(t *testing.T) { test: "four pods, 3 matching (z1=1, z2=1, z3=1)", }, { - pod: buildPod("", labels1), + pod: buildPod("", labels1, controllerRef("ReplicationController", "name", "abc123")), pods: []*api.Pod{ - buildPod(nodeMachine1Zone3, labels1), - buildPod(nodeMachine1Zone2, labels1), - buildPod(nodeMachine1Zone3, labels1), + buildPod(nodeMachine1Zone3, labels1, controllerRef("ReplicationController", "name", "abc123")), + buildPod(nodeMachine1Zone2, labels1, controllerRef("ReplicationController", "name", "abc123")), + buildPod(nodeMachine1Zone3, labels1, controllerRef("ReplicationController", "name", "abc123")), }, rcs: []api.ReplicationController{{Spec: api.ReplicationControllerSpec{Selector: labels1}}}, expectedList: []schedulerapi.HostPriority{ @@ -478,7 +493,12 @@ func TestZoneSelectorSpreadPriority(t *testing.T) { for _, test := range tests { nodeNameToInfo := schedulercache.CreateNodeNameToInfoMap(test.pods, nil) - selectorSpread := SelectorSpread{podLister: algorithm.FakePodLister(test.pods), serviceLister: algorithm.FakeServiceLister(test.services), controllerLister: algorithm.FakeControllerLister(test.rcs), replicaSetLister: algorithm.FakeReplicaSetLister(test.rss)} + selectorSpread := SelectorSpread{ + podLister: algorithm.FakePodLister(test.pods), + serviceLister: algorithm.FakeServiceLister(test.services), + controllerLister: algorithm.FakeControllerLister(test.rcs), + replicaSetLister: algorithm.FakeReplicaSetLister(test.rss), + } list, err := selectorSpread.CalculateSpreadPriority(test.pod, nodeNameToInfo, makeLabeledNodeList(labeledNodes)) if err != nil { t.Errorf("unexpected error: %v", err)