From bc8f3198d535f5bc3ef0730fe04d9f7d01b17059 Mon Sep 17 00:00:00 2001 From: Yibo Zhuang Date: Thu, 5 May 2022 10:48:55 -0700 Subject: [PATCH] cleanup: move scheduler plugin tests to use PodWrapper Move scheduler plugin unit tests use testing PodWrapper where applicable to reduce duplicating pod creation code and shorten number of lines. Signed-off-by: Yibo Zhuang --- .../defaultbinder/default_binder_test.go | 5 +- .../framework/plugins/helper/spread_test.go | 16 +- .../imagelocality/image_locality_test.go | 26 +- .../interpodaffinity/filtering_test.go | 1350 +++-------------- .../plugins/interpodaffinity/scoring_test.go | 368 ++--- .../nodeaffinity/node_affinity_test.go | 105 +- .../plugins/nodename/node_name_test.go | 26 +- .../plugins/nodeports/node_ports_test.go | 104 +- .../noderesources/balanced_allocation_test.go | 117 +- .../noderesources/least_allocated_test.go | 8 +- .../noderesources/most_allocated_test.go | 6 +- .../requested_to_capacity_ratio_test.go | 127 +- .../plugins/nodevolumelimits/csi_test.go | 236 +-- .../plugins/nodevolumelimits/non_csi_test.go | 661 +------- .../plugins/queuesort/priority_sort_test.go | 53 +- .../selectorspread/selector_spread_test.go | 276 ++-- .../volume_restrictions_test.go | 187 +-- .../plugins/volumezone/volume_zone_test.go | 21 +- 18 files changed, 862 insertions(+), 2830 deletions(-) diff --git a/pkg/scheduler/framework/plugins/defaultbinder/default_binder_test.go b/pkg/scheduler/framework/plugins/defaultbinder/default_binder_test.go index 0ef47239c7d..44d7b83d19f 100644 --- a/pkg/scheduler/framework/plugins/defaultbinder/default_binder_test.go +++ b/pkg/scheduler/framework/plugins/defaultbinder/default_binder_test.go @@ -28,12 +28,11 @@ import ( "k8s.io/client-go/kubernetes/fake" clienttesting "k8s.io/client-go/testing" frameworkruntime "k8s.io/kubernetes/pkg/scheduler/framework/runtime" + st "k8s.io/kubernetes/pkg/scheduler/testing" ) func TestDefaultBinder(t *testing.T) { - testPod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "ns"}, - } + testPod := st.MakePod().Name("foo").Namespace("ns").Obj() testNode := "foohost.kubernetes.mydomain.com" tests := []struct { name string diff --git a/pkg/scheduler/framework/plugins/helper/spread_test.go b/pkg/scheduler/framework/plugins/helper/spread_test.go index fa5aaa0df11..b320d8a75a7 100644 --- a/pkg/scheduler/framework/plugins/helper/spread_test.go +++ b/pkg/scheduler/framework/plugins/helper/spread_test.go @@ -26,6 +26,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes/fake" + st "k8s.io/kubernetes/pkg/scheduler/testing" ) func TestGetPodServices(t *testing.T) { @@ -48,16 +49,11 @@ func TestGetPodServices(t *testing.T) { } var pods []*v1.Pod for i := 0; i < 5; i++ { - pod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "test", - Name: fmt.Sprintf("test-pod-%d", i), - Labels: map[string]string{ - "app": fmt.Sprintf("test-%d", i), - "label": fmt.Sprintf("label-%d", i), - }, - }, - } + pod := st.MakePod().Name(fmt.Sprintf("test-pod-%d", i)). + Namespace("test"). + Label("app", fmt.Sprintf("test-%d", i)). + Label("label", fmt.Sprintf("label-%d", i)). + Obj() pods = append(pods, pod) } diff --git a/pkg/scheduler/framework/plugins/imagelocality/image_locality_test.go b/pkg/scheduler/framework/plugins/imagelocality/image_locality_test.go index 6f7446f9a64..72e5feae55b 100644 --- a/pkg/scheduler/framework/plugins/imagelocality/image_locality_test.go +++ b/pkg/scheduler/framework/plugins/imagelocality/image_locality_test.go @@ -240,8 +240,8 @@ func TestImageLocalityPriority(t *testing.T) { // Image: gcr.io/250:latest 250MB // Score: 100 * (250M/2 - 23M)/(1000M * 2 - 23M) = 5 pod: &v1.Pod{Spec: test40250}, - nodes: []*v1.Node{makeImageNode("machine1", node403002000), makeImageNode("machine2", node25010)}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 5}}, + nodes: []*v1.Node{makeImageNode("node1", node403002000), makeImageNode("node2", node25010)}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 5}}, name: "two images spread on two nodes, prefer the larger image one", }, { @@ -255,8 +255,8 @@ func TestImageLocalityPriority(t *testing.T) { // Image: not present // Score: 0 pod: &v1.Pod{Spec: test40300}, - nodes: []*v1.Node{makeImageNode("machine1", node403002000), makeImageNode("machine2", node25010)}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 7}, {Name: "machine2", Score: 0}}, + nodes: []*v1.Node{makeImageNode("node1", node403002000), makeImageNode("node2", node25010)}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 7}, {Name: "node2", Score: 0}}, name: "two images on one node, prefer this node", }, { @@ -270,8 +270,8 @@ func TestImageLocalityPriority(t *testing.T) { // Image: gcr.io/10:latest 10MB // Score: 0 (10M/2 < 23M, min-threshold) pod: &v1.Pod{Spec: testMinMax}, - nodes: []*v1.Node{makeImageNode("machine1", node400030), makeImageNode("machine2", node25010)}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: 0}}, + nodes: []*v1.Node{makeImageNode("node1", node400030), makeImageNode("node2", node25010)}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: 0}}, name: "if exceed limit, use limit", }, { @@ -289,8 +289,8 @@ func TestImageLocalityPriority(t *testing.T) { // Image: // Score: 0 pod: &v1.Pod{Spec: testMinMax}, - nodes: []*v1.Node{makeImageNode("machine1", node400030), makeImageNode("machine2", node25010), makeImageNode("machine3", nodeWithNoImages)}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 66}, {Name: "machine2", Score: 0}, {Name: "machine3", Score: 0}}, + nodes: []*v1.Node{makeImageNode("node1", node400030), makeImageNode("node2", node25010), makeImageNode("node3", nodeWithNoImages)}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 66}, {Name: "node2", Score: 0}, {Name: "node3", Score: 0}}, name: "if exceed limit, use limit (with node which has no images present)", }, { @@ -308,9 +308,9 @@ func TestImageLocalityPriority(t *testing.T) { // Image: // Score: 0 pod: &v1.Pod{Spec: test300600900}, - nodes: []*v1.Node{makeImageNode("machine1", node60040900), makeImageNode("machine2", node300600900), makeImageNode("machine3", nodeWithNoImages)}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 32}, {Name: "machine2", Score: 36}, {Name: "machine3", Score: 0}}, - name: "pod with multiple large images, machine2 is preferred", + nodes: []*v1.Node{makeImageNode("node1", node60040900), makeImageNode("node2", node300600900), makeImageNode("node3", nodeWithNoImages)}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 32}, {Name: "node2", Score: 36}, {Name: "node3", Score: 0}}, + name: "pod with multiple large images, node2 is preferred", }, { // Pod: gcr.io/30 gcr.io/40 @@ -323,8 +323,8 @@ func TestImageLocalityPriority(t *testing.T) { // Image: 100 * (30M - 23M) / (1000M * 2 - 23M) = 0 // Score: 0 pod: &v1.Pod{Spec: test3040}, - nodes: []*v1.Node{makeImageNode("machine1", node203040), makeImageNode("machine2", node400030)}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 1}, {Name: "machine2", Score: 0}}, + nodes: []*v1.Node{makeImageNode("node1", node203040), makeImageNode("node2", node400030)}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 1}, {Name: "node2", Score: 0}}, name: "pod with multiple small images", }, } diff --git a/pkg/scheduler/framework/plugins/interpodaffinity/filtering_test.go b/pkg/scheduler/framework/plugins/interpodaffinity/filtering_test.go index cb45a132f7e..ce0aa6b6bed 100644 --- a/pkg/scheduler/framework/plugins/interpodaffinity/filtering_test.go +++ b/pkg/scheduler/framework/plugins/interpodaffinity/filtering_test.go @@ -30,6 +30,7 @@ import ( "k8s.io/kubernetes/pkg/scheduler/framework" plugintesting "k8s.io/kubernetes/pkg/scheduler/framework/plugins/testing" "k8s.io/kubernetes/pkg/scheduler/internal/cache" + st "k8s.io/kubernetes/pkg/scheduler/testing" ) var ( @@ -54,17 +55,19 @@ func createPodWithAffinityTerms(namespace, nodeName string, labels map[string]st }, }, } - } func TestRequiredAffinitySingleNode(t *testing.T) { podLabel := map[string]string{"service": "securityscan"} + pod := st.MakePod().Labels(podLabel).Node("node1").Obj() + labels1 := map[string]string{ "region": "r1", "zone": "z11", } podLabel2 := map[string]string{"security": "S1"} - node1 := v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labels1}} + node1 := v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labels1}} + tests := []struct { pod *v1.Pod pods []*v1.Pod @@ -79,42 +82,14 @@ func TestRequiredAffinitySingleNode(t *testing.T) { }, { name: "satisfies with requiredDuringSchedulingIgnoredDuringExecution in PodAffinity using In operator that matches the existing pod", - pod: createPodWithAffinityTerms(defaultNamespace, "", podLabel2, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"securityscan", "value2"}, - }, - }, - }, - TopologyKey: "region", - }, - }, nil), - pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabel}}}, + pod: st.MakePod().Namespace(defaultNamespace).Labels(podLabel2).PodAffinityIn("service", "region", []string{"securityscan", "value2"}, st.PodAffinityWithRequiredReq).Obj(), + pods: []*v1.Pod{pod}, node: &node1, }, { name: "satisfies the pod with requiredDuringSchedulingIgnoredDuringExecution in PodAffinity using not in operator in labelSelector that matches the existing pod", - pod: createPodWithAffinityTerms(defaultNamespace, "", podLabel2, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpNotIn, - Values: []string{"securityscan3", "value3"}, - }, - }, - }, - TopologyKey: "region", - }, - }, nil), - pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabel}}}, + pod: st.MakePod().Namespace(defaultNamespace).Labels(podLabel2).PodAffinityNotIn("service", "region", []string{"securityscan3", "value3"}, st.PodAffinityWithRequiredReq).Obj(), + pods: []*v1.Pod{pod}, node: &node1, }, { @@ -134,7 +109,7 @@ func TestRequiredAffinitySingleNode(t *testing.T) { Namespaces: []string{"DiffNameSpace"}, }, }, nil), - pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabel, Namespace: "ns"}}}, + pods: []*v1.Pod{st.MakePod().Namespace("ns").Label("service", "securityscan").Node("node1").Obj()}, node: &node1, wantStatus: framework.NewStatus( framework.UnschedulableAndUnresolvable, @@ -143,21 +118,8 @@ func TestRequiredAffinitySingleNode(t *testing.T) { }, { name: "Doesn't satisfy the PodAffinity because of unmatching labelSelector with the existing pod", - pod: createPodWithAffinityTerms(defaultNamespace, "", podLabel, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"antivirusscan", "value2"}, - }, - }, - }, - }, - }, nil), - pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabel}}}, + pod: st.MakePod().Namespace(defaultNamespace).Labels(podLabel).PodAffinityIn("service", "", []string{"antivirusscan", "value2"}, st.PodAffinityWithRequiredReq).Obj(), + pods: []*v1.Pod{pod}, node: &node1, wantStatus: framework.NewStatus( framework.UnschedulableAndUnresolvable, @@ -198,7 +160,7 @@ func TestRequiredAffinitySingleNode(t *testing.T) { TopologyKey: "region", }, }, nil), - pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabel}}}, + pods: []*v1.Pod{pod}, node: &node1, }, { @@ -235,7 +197,7 @@ func TestRequiredAffinitySingleNode(t *testing.T) { TopologyKey: "region", }, }, nil), - pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabel}}}, + pods: []*v1.Pod{pod}, node: &node1, wantStatus: framework.NewStatus( framework.UnschedulableAndUnresolvable, @@ -244,120 +206,29 @@ func TestRequiredAffinitySingleNode(t *testing.T) { }, { name: "satisfies the PodAffinity and PodAntiAffinity with the existing pod", - pod: createPodWithAffinityTerms(defaultNamespace, "", podLabel2, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"securityscan", "value2"}, - }, - }, - }, - TopologyKey: "region", - }, - }, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"antivirusscan", "value2"}, - }, - }, - }, - TopologyKey: "node", - }, - }), - pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabel}}}, + pod: st.MakePod().Namespace(defaultNamespace).Labels(podLabel2). + PodAffinityIn("service", "region", []string{"securityscan", "value2"}, st.PodAffinityWithRequiredReq). + PodAntiAffinityIn("service", "node", []string{"antivirusscan", "value2"}, st.PodAntiAffinityWithRequiredReq).Obj(), + pods: []*v1.Pod{pod}, node: &node1, }, { name: "satisfies the PodAffinity and PodAntiAffinity and PodAntiAffinity symmetry with the existing pod", - pod: createPodWithAffinityTerms(defaultNamespace, "", podLabel2, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"securityscan", "value2"}, - }, - }, - }, - TopologyKey: "region", - }, - }, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"antivirusscan", "value2"}, - }, - }, - }, - TopologyKey: "node", - }, - }), + pod: st.MakePod().Namespace(defaultNamespace).Labels(podLabel2). + PodAffinityIn("service", "region", []string{"securityscan", "value2"}, st.PodAffinityWithRequiredReq). + PodAntiAffinityIn("service", "node", []string{"antivirusscan", "value2"}, st.PodAntiAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - createPodWithAffinityTerms(defaultNamespace, "machine1", podLabel, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"antivirusscan", "value2"}, - }, - }, - }, - TopologyKey: "node", - }, - }), + st.MakePod().Namespace(defaultNamespace).Node("node1").Labels(podLabel). + PodAntiAffinityIn("service", "node", []string{"antivirusscan", "value2"}, st.PodAntiAffinityWithRequiredReq).Obj(), }, node: &node1, }, { name: "satisfies the PodAffinity but doesn't satisfy the PodAntiAffinity with the existing pod", - pod: createPodWithAffinityTerms(defaultNamespace, "", podLabel2, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"securityscan", "value2"}, - }, - }, - }, - TopologyKey: "region", - }, - }, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"securityscan", "value2"}, - }, - }, - }, - TopologyKey: "zone", - }, - }), - pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabel}}}, + pod: st.MakePod().Namespace(defaultNamespace).Labels(podLabel2). + PodAffinityIn("service", "region", []string{"securityscan", "value2"}, st.PodAffinityWithRequiredReq). + PodAntiAffinityIn("service", "zone", []string{"securityscan", "value2"}, st.PodAntiAffinityWithRequiredReq).Obj(), + pods: []*v1.Pod{pod}, node: &node1, wantStatus: framework.NewStatus( framework.Unschedulable, @@ -366,51 +237,11 @@ func TestRequiredAffinitySingleNode(t *testing.T) { }, { name: "satisfies the PodAffinity and PodAntiAffinity but doesn't satisfy PodAntiAffinity symmetry with the existing pod", - pod: createPodWithAffinityTerms(defaultNamespace, "", podLabel, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"securityscan", "value2"}, - }, - }, - }, - TopologyKey: "region", - }, - }, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"antivirusscan", "value2"}, - }, - }, - }, - TopologyKey: "node", - }, - }), + pod: st.MakePod().Namespace(defaultNamespace).Labels(podLabel). + PodAffinityIn("service", "region", []string{"securityscan", "value2"}, st.PodAffinityWithRequiredReq). + PodAntiAffinityIn("service", "node", []string{"antivirusscan", "value2"}, st.PodAntiAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - createPodWithAffinityTerms(defaultNamespace, "machine1", podLabel, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"securityscan", "value2"}, - }, - }, - }, - TopologyKey: "zone", - }, - }), + st.MakePod().Namespace(defaultNamespace).Labels(podLabel).Node("node1").PodAntiAffinityIn("service", "zone", []string{"securityscan", "value2"}, st.PodAntiAffinityWithRequiredReq).Obj(), }, node: &node1, wantStatus: framework.NewStatus( @@ -420,22 +251,9 @@ func TestRequiredAffinitySingleNode(t *testing.T) { }, { name: "pod matches its own Label in PodAffinity and that matches the existing pod Labels", - pod: createPodWithAffinityTerms(defaultNamespace, "", podLabel, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpNotIn, - Values: []string{"securityscan", "value2"}, - }, - }, - }, - TopologyKey: "region", - }, - }, nil), - pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabel}}}, + pod: st.MakePod().Namespace(defaultNamespace).Labels(podLabel). + PodAffinityNotIn("service", "region", []string{"securityscan", "value2"}, st.PodAffinityWithRequiredReq).Obj(), + pods: []*v1.Pod{st.MakePod().Label("service", "securityscan").Node("node2").Obj()}, node: &node1, wantStatus: framework.NewStatus( framework.UnschedulableAndUnresolvable, @@ -444,27 +262,10 @@ func TestRequiredAffinitySingleNode(t *testing.T) { }, { name: "verify that PodAntiAffinity from existing pod is respected when pod has no AntiAffinity constraints. doesn't satisfy PodAntiAffinity symmetry with the existing pod", - pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Labels: podLabel, - }, - }, + pod: st.MakePod().Labels(podLabel).Obj(), pods: []*v1.Pod{ - createPodWithAffinityTerms(defaultNamespace, "machine1", podLabel, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"securityscan", "value2"}, - }, - }, - }, - TopologyKey: "zone", - }, - }), + st.MakePod().Namespace(defaultNamespace).Node("node1").Labels(podLabel). + PodAntiAffinityIn("service", "zone", []string{"securityscan", "value2"}, st.PodAntiAffinityWithRequiredReq).Obj(), }, node: &node1, wantStatus: framework.NewStatus( @@ -474,72 +275,21 @@ func TestRequiredAffinitySingleNode(t *testing.T) { }, { name: "verify that PodAntiAffinity from existing pod is respected when pod has no AntiAffinity constraints. satisfy PodAntiAffinity symmetry with the existing pod", - pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Labels: podLabel, - }, - }, + pod: st.MakePod().Labels(podLabel).Obj(), pods: []*v1.Pod{ - createPodWithAffinityTerms(defaultNamespace, "machine1", podLabel, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpNotIn, - Values: []string{"securityscan", "value2"}, - }, - }, - }, - TopologyKey: "zone", - }, - }), + st.MakePod().Namespace(defaultNamespace).Node("node1").Labels(podLabel). + PodAntiAffinityNotIn("service", "zone", []string{"securityscan", "value2"}, st.PodAntiAffinityWithRequiredReq).Obj(), }, node: &node1, }, { name: "satisfies the PodAntiAffinity with existing pod but doesn't satisfy PodAntiAffinity symmetry with incoming pod", - pod: createPodWithAffinityTerms(defaultNamespace, "", podLabel, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "region", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "security", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "region", - }, - }), + pod: st.MakePod().Namespace(defaultNamespace).Labels(podLabel). + PodAntiAffinityExists("service", "region", st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityExists("security", "region", st.PodAntiAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - createPodWithAffinityTerms(defaultNamespace, "machine1", podLabel2, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "security", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }), + st.MakePod().Namespace(defaultNamespace).Node("node1").Labels(podLabel2). + PodAntiAffinityExists("security", "zone", st.PodAntiAffinityWithRequiredReq).Obj(), }, node: &node1, wantStatus: framework.NewStatus( @@ -549,46 +299,12 @@ func TestRequiredAffinitySingleNode(t *testing.T) { }, { name: "PodAntiAffinity symmetry check a1: incoming pod and existing pod partially match each other on AffinityTerms", - pod: createPodWithAffinityTerms(defaultNamespace, "", podLabel, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "security", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }), + pod: st.MakePod().Namespace(defaultNamespace).Labels(podLabel). + PodAntiAffinityExists("service", "zone", st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityExists("security", "zone", st.PodAntiAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - createPodWithAffinityTerms(defaultNamespace, "machine1", podLabel2, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "security", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }), + st.MakePod().Namespace(defaultNamespace).Node("node1").Labels(podLabel2). + PodAntiAffinityExists("security", "zone", st.PodAntiAffinityWithRequiredReq).Obj(), }, node: &node1, wantStatus: framework.NewStatus( @@ -598,46 +314,12 @@ func TestRequiredAffinitySingleNode(t *testing.T) { }, { name: "PodAntiAffinity symmetry check a2: incoming pod and existing pod partially match each other on AffinityTerms", - pod: createPodWithAffinityTerms(defaultNamespace, "", podLabel2, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "security", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }), + pod: st.MakePod().Namespace(defaultNamespace).Labels(podLabel2). + PodAntiAffinityExists("security", "zone", st.PodAntiAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - createPodWithAffinityTerms(defaultNamespace, "machine1", podLabel, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "security", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }), + st.MakePod().Namespace(defaultNamespace).Node("node1").Labels(podLabel). + PodAntiAffinityExists("service", "zone", st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityExists("security", "zone", st.PodAntiAffinityWithRequiredReq).Obj(), }, node: &node1, wantStatus: framework.NewStatus( @@ -647,57 +329,13 @@ func TestRequiredAffinitySingleNode(t *testing.T) { }, { name: "PodAntiAffinity symmetry check b1: incoming pod and existing pod partially match each other on AffinityTerms", - pod: createPodWithAffinityTerms(defaultNamespace, "", map[string]string{"abc": "", "xyz": ""}, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "abc", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "def", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }), + pod: st.MakePod().Namespace(defaultNamespace).Labels(map[string]string{"abc": "", "xyz": ""}). + PodAntiAffinityExists("abc", "zone", st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityExists("def", "zone", st.PodAntiAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - createPodWithAffinityTerms(defaultNamespace, "machine1", map[string]string{"def": "", "xyz": ""}, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "abc", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "def", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }), + st.MakePod().Namespace(defaultNamespace).Node("node1").Labels(map[string]string{"def": "", "xyz": ""}). + PodAntiAffinityExists("abc", "zone", st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityExists("def", "zone", st.PodAntiAffinityWithRequiredReq).Obj(), }, node: &node1, wantStatus: framework.NewStatus( @@ -707,57 +345,13 @@ func TestRequiredAffinitySingleNode(t *testing.T) { }, { name: "PodAntiAffinity symmetry check b2: incoming pod and existing pod partially match each other on AffinityTerms", - pod: createPodWithAffinityTerms(defaultNamespace, "", map[string]string{"def": "", "xyz": ""}, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "abc", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "def", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }), + pod: st.MakePod().Namespace(defaultNamespace).Labels(map[string]string{"def": "", "xyz": ""}). + PodAntiAffinityExists("abc", "zone", st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityExists("def", "zone", st.PodAntiAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - createPodWithAffinityTerms(defaultNamespace, "machine1", map[string]string{"abc": "", "xyz": ""}, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "abc", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "def", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }), + st.MakePod().Namespace(defaultNamespace).Node("node1").Labels(map[string]string{"abc": "", "xyz": ""}). + PodAntiAffinityExists("abc", "zone", st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityExists("def", "zone", st.PodAntiAffinityWithRequiredReq).Obj(), }, node: &node1, wantStatus: framework.NewStatus( @@ -767,35 +361,9 @@ func TestRequiredAffinitySingleNode(t *testing.T) { }, { name: "PodAffinity fails PreFilter with an invalid affinity label syntax", - pod: createPodWithAffinityTerms(defaultNamespace, "", podLabel, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"{{.bad-value.}}"}, - }, - }, - }, - TopologyKey: "region", - }, - }, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"antivirusscan", "value2"}, - }, - }, - }, - TopologyKey: "node", - }, - }), + pod: st.MakePod().Namespace(defaultNamespace).Labels(podLabel). + PodAffinityIn("service", "region", []string{"{{.bad-value.}}"}, st.PodAffinityWithRequiredReq). + PodAffinityIn("service", "node", []string{"antivirusscan", "value2"}, st.PodAffinityWithRequiredReq).Obj(), node: &node1, wantStatus: framework.NewStatus( framework.UnschedulableAndUnresolvable, @@ -804,35 +372,9 @@ func TestRequiredAffinitySingleNode(t *testing.T) { }, { name: "PodAntiAffinity fails PreFilter with an invalid antiaffinity label syntax", - pod: createPodWithAffinityTerms(defaultNamespace, "", podLabel, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"foo"}, - }, - }, - }, - TopologyKey: "region", - }, - }, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"{{.bad-value.}}"}, - }, - }, - }, - TopologyKey: "node", - }, - }), + pod: st.MakePod().Namespace(defaultNamespace).Labels(podLabel). + PodAffinityIn("service", "region", []string{"foo"}, st.PodAffinityWithRequiredReq). + PodAffinityIn("service", "node", []string{"{{.bad-value.}}"}, st.PodAffinityWithRequiredReq).Obj(), node: &node1, wantStatus: framework.NewStatus( framework.UnschedulableAndUnresolvable, @@ -865,7 +407,7 @@ func TestRequiredAffinitySingleNode(t *testing.T) { TopologyKey: "region", }, }, nil), - pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabel}}}, + pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabel}}}, node: &node1, }, { @@ -894,7 +436,7 @@ func TestRequiredAffinitySingleNode(t *testing.T) { TopologyKey: "region", }, }, nil), - pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team2", Labels: podLabel}}}, + pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team2", Labels: podLabel}}}, node: &node1, wantStatus: framework.NewStatus( framework.UnschedulableAndUnresolvable, @@ -927,7 +469,7 @@ func TestRequiredAffinitySingleNode(t *testing.T) { TopologyKey: "zone", }, }), - pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team1", Labels: podLabel}}}, + pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team1", Labels: podLabel}}}, node: &node1, wantStatus: framework.NewStatus( framework.Unschedulable, @@ -952,7 +494,7 @@ func TestRequiredAffinitySingleNode(t *testing.T) { TopologyKey: "zone", }, }), - pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team1", Labels: podLabel}}}, + pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team1", Labels: podLabel}}}, node: &node1, wantStatus: framework.NewStatus( framework.Unschedulable, @@ -985,7 +527,7 @@ func TestRequiredAffinitySingleNode(t *testing.T) { TopologyKey: "zone", }, }), - pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team2", Labels: podLabel}}}, + pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team2", Labels: podLabel}}}, node: &node1, }, } @@ -1036,28 +578,14 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { name string }{ { - pod: createPodWithAffinityTerms(defaultNamespace, "", nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"bar"}, - }, - }, - }, - TopologyKey: "region", - }, - }, nil), + pod: st.MakePod().Namespace(defaultNamespace).PodAffinityIn("foo", "region", []string{"bar"}, st.PodAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Name: "p1", Labels: podLabelA}}, + st.MakePod().Name("p1").Node("node1").Labels(podLabelA).Obj(), }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgChinaAzAz1}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgChinaAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelRgIndia}}, }, wantStatuses: []*framework.Status{ nil, @@ -1070,34 +598,12 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { name: "A pod can be scheduled onto all the nodes that have the same topology key & label value with one of them has an existing pod that matches the affinity rules", }, { - pod: createPodWithAffinityTerms(defaultNamespace, "", map[string]string{"foo": "bar", "service": "securityscan"}, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"bar"}, - }, - }, - }, - TopologyKey: "zone", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"securityscan"}, - }, - }, - }, - TopologyKey: "zone", - }, - }, nil), - pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "nodeA"}, ObjectMeta: metav1.ObjectMeta{Name: "p1", Labels: map[string]string{"foo": "bar"}}}}, + pod: st.MakePod().Namespace(defaultNamespace).Labels(map[string]string{"foo": "bar", "service": "securityscan"}). + PodAffinityIn("foo", "zone", []string{"bar"}, st.PodAffinityWithRequiredReq). + PodAffinityIn("service", "zone", []string{"securityscan"}, st.PodAffinityWithRequiredReq).Obj(), + pods: []*v1.Pod{ + st.MakePod().Name("p1").Node("nodeA").Labels(map[string]string{"foo": "bar"}).Obj(), + }, nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: map[string]string{"zone": "az1", "hostname": "h1"}}}, {ObjectMeta: metav1.ObjectMeta{Name: "nodeB", Labels: map[string]string{"zone": "az2", "hostname": "h2"}}}, @@ -1107,34 +613,12 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { "should not be blocked from being scheduled onto any node, even there's no existing pod that matches the rule anywhere.", }, { - pod: createPodWithAffinityTerms(defaultNamespace, "", map[string]string{"foo": "bar", "service": "securityscan"}, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"bar"}, - }, - }, - }, - TopologyKey: "zone", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"securityscan"}, - }, - }, - }, - TopologyKey: "zone", - }, - }, nil), - pods: []*v1.Pod{{Spec: v1.PodSpec{NodeName: "nodeA"}, ObjectMeta: metav1.ObjectMeta{Name: "p1", Labels: map[string]string{"foo": "bar"}}}}, + pod: st.MakePod().Namespace(defaultNamespace).Labels(map[string]string{"foo": "bar", "service": "securityscan"}). + PodAffinityIn("foo", "zone", []string{"bar"}, st.PodAffinityWithRequiredReq). + PodAffinityIn("service", "zone", []string{"securityscan"}, st.PodAffinityWithRequiredReq).Obj(), + pods: []*v1.Pod{ + st.MakePod().Name("p1").Node("nodeA").Labels(map[string]string{"foo": "bar"}).Obj(), + }, nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: map[string]string{"zoneLabel": "az1", "hostname": "h1"}}}, {ObjectMeta: metav1.ObjectMeta{Name: "nodeB", Labels: map[string]string{"zoneLabel": "az2", "hostname": "h2"}}}, @@ -1152,23 +636,9 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { name: "The first pod of the collection can only be scheduled on nodes labelled with the requested topology keys", }, { - pod: createPodWithAffinityTerms(defaultNamespace, "", nil, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"abc"}, - }, - }, - }, - TopologyKey: "region", - }, - }), + pod: st.MakePod().Namespace(defaultNamespace).PodAntiAffinityIn("foo", "region", []string{"abc"}, st.PodAntiAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "nodeA"}, ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "abc"}}}, + st.MakePod().Node("nodeA").Labels(map[string]string{"foo": "abc"}).Obj(), }, nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: map[string]string{"region": "r1", "hostname": "nodeA"}}}, @@ -1187,35 +657,10 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { name: "NodeA and nodeB have same topologyKey and label value. NodeA has an existing pod that matches the inter pod affinity rule. The pod can not be scheduled onto nodeA and nodeB.", }, { - pod: createPodWithAffinityTerms(defaultNamespace, "", nil, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"abc"}, - }, - }, - }, - TopologyKey: "region", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "service", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"securityscan"}, - }, - }, - }, - TopologyKey: "zone", - }, - }), + pod: st.MakePod().Namespace(defaultNamespace).PodAntiAffinityIn("foo", "region", []string{"abc"}, st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityIn("service", "zone", []string{"securityscan"}, st.PodAntiAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "nodeA"}, ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "abc", "service": "securityscan"}}}, + st.MakePod().Node("nodeA").Labels(map[string]string{"foo": "abc", "service": "securityscan"}).Obj(), }, nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: map[string]string{"region": "r1", "zone": "z1", "hostname": "nodeA"}}}, @@ -1234,23 +679,9 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { name: "This test ensures that anti-affinity matches a pod when any term of the anti-affinity rule matches a pod.", }, { - pod: createPodWithAffinityTerms(defaultNamespace, "", nil, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"abc"}, - }, - }, - }, - TopologyKey: "region", - }, - }), + pod: st.MakePod().Namespace(defaultNamespace).PodAntiAffinityIn("foo", "region", []string{"abc"}, st.PodAntiAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "nodeA"}, ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "abc"}}}, + st.MakePod().Node("nodeA").Labels(map[string]string{"foo": "abc"}).Obj(), }, nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: labelRgChina}}, @@ -1271,44 +702,10 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { name: "NodeA and nodeB have same topologyKey and label value. NodeA has an existing pod that matches the inter pod affinity rule. The pod can not be scheduled onto nodeA and nodeB but can be scheduled onto nodeC", }, { - pod: createPodWithAffinityTerms("NS1", "", map[string]string{"foo": "123"}, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"bar"}, - }, - }, - }, - TopologyKey: "region", - }, - }), + pod: st.MakePod().Namespace("NS1").Labels(map[string]string{"foo": "123"}).PodAntiAffinityIn("foo", "region", []string{"bar"}, st.PodAntiAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - { - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{"foo": "bar"}, - Namespace: "NS1", - }, - Spec: v1.PodSpec{NodeName: "nodeA"}, - }, - createPodWithAffinityTerms("NS2", "nodeC", nil, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpIn, - Values: []string{"123"}, - }, - }, - }, - TopologyKey: "region", - }, - }), + st.MakePod().Node("nodeA").Namespace("NS1").Labels(map[string]string{"foo": "bar"}).Obj(), + st.MakePod().Node("nodeC").Namespace("NS2").PodAntiAffinityIn("foo", "region", []string{"123"}, st.PodAntiAffinityWithRequiredReq).Obj(), }, nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: labelRgChina}}, @@ -1329,24 +726,9 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { name: "NodeA and nodeB have same topologyKey and label value. NodeA has an existing pod that matches the inter pod affinity rule. The pod can not be scheduled onto nodeA, nodeB, but can be scheduled onto nodeC (NodeC has an existing pod that match the inter pod affinity rule but in different namespace)", }, { - pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": ""}}, - }, + pod: st.MakePod().Label("foo", "").Obj(), pods: []*v1.Pod{ - createPodWithAffinityTerms(defaultNamespace, "nodeA", nil, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "invalid-node-label", - }, - }), + st.MakePod().Node("nodeA").Namespace(defaultNamespace).PodAntiAffinityExists("foo", "invalid-node-label", st.PodAntiAffinityWithRequiredReq).Obj(), }, nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: map[string]string{"region": "r1", "zone": "z1", "hostname": "nodeA"}}}, @@ -1356,27 +738,9 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { name: "Test existing pod's anti-affinity: if an existing pod has a term with invalid topologyKey, labelSelector of the term is firstly checked, and then topologyKey of the term is also checked", }, { - pod: createPodWithAffinityTerms(defaultNamespace, "", nil, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "invalid-node-label", - }, - }), + pod: st.MakePod().Node("nodeA").Namespace(defaultNamespace).PodAntiAffinityExists("foo", "invalid-node-label", st.PodAntiAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - { - ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": ""}}, - Spec: v1.PodSpec{ - NodeName: "nodeA", - }, - }, + st.MakePod().Node("nodeA").Labels(map[string]string{"foo": ""}).Obj(), }, nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: map[string]string{"region": "r1", "zone": "z1", "hostname": "nodeA"}}}, @@ -1386,38 +750,10 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { name: "Test incoming pod's anti-affinity: even if labelSelector matches, we still check if topologyKey matches", }, { - pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "", "bar": ""}}, - }, + pod: st.MakePod().Label("foo", "").Label("bar", "").Obj(), pods: []*v1.Pod{ - createPodWithAffinityTerms(defaultNamespace, "nodeA", nil, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }), - createPodWithAffinityTerms(defaultNamespace, "nodeA", nil, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "bar", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "region", - }, - }), + st.MakePod().Node("nodeA").Namespace(defaultNamespace).PodAntiAffinityExists("foo", "zone", st.PodAntiAffinityWithRequiredReq).Obj(), + st.MakePod().Node("nodeA").Namespace(defaultNamespace).PodAntiAffinityExists("bar", "region", st.PodAntiAffinityWithRequiredReq).Obj(), }, nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: map[string]string{"region": "r1", "zone": "z1", "hostname": "nodeA"}}}, @@ -1436,44 +772,11 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { name: "Test existing pod's anti-affinity: incoming pod wouldn't considered as a fit as it violates each existingPod's terms on all nodes", }, { - pod: createPodWithAffinityTerms(defaultNamespace, "", nil, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "bar", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "region", - }, - }), + pod: st.MakePod().Namespace(defaultNamespace).PodAntiAffinityExists("foo", "zone", st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityExists("bar", "region", st.PodAntiAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - { - ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": ""}}, - Spec: v1.PodSpec{ - NodeName: "nodeA", - }, - }, - { - ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"bar": ""}}, - Spec: v1.PodSpec{ - NodeName: "nodeB", - }, - }, + st.MakePod().Node("nodeA").Labels(map[string]string{"foo": ""}).Obj(), + st.MakePod().Node("nodeB").Labels(map[string]string{"bar": ""}).Obj(), }, nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: map[string]string{"region": "r1", "zone": "z1", "hostname": "nodeA"}}}, @@ -1492,35 +795,10 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { name: "Test incoming pod's anti-affinity: incoming pod wouldn't considered as a fit as it at least violates one anti-affinity rule of existingPod", }, { - pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "", "bar": ""}}, - }, + pod: st.MakePod().Label("foo", "").Label("bar", "").Obj(), pods: []*v1.Pod{ - createPodWithAffinityTerms(defaultNamespace, "nodeA", nil, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "invalid-node-label", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "bar", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }), + st.MakePod().Node("nodeA").Namespace(defaultNamespace).PodAntiAffinityExists("foo", "invalid-node-label", st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityExists("bar", "zone", st.PodAntiAffinityWithRequiredReq).Obj(), }, nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: map[string]string{"region": "r1", "zone": "z1", "hostname": "nodeA"}}}, @@ -1536,41 +814,10 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { name: "Test existing pod's anti-affinity: only when labelSelector and topologyKey both match, it's counted as a single term match - case when one term has invalid topologyKey", }, { - pod: createPodWithAffinityTerms(defaultNamespace, "", nil, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "invalid-node-label", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "bar", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }), + pod: st.MakePod().Namespace(defaultNamespace).PodAntiAffinityExists("foo", "invalid-node-label", st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityExists("bar", "zone", st.PodAntiAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "podA", - Labels: map[string]string{"foo": "", "bar": ""}, - }, - Spec: v1.PodSpec{ - NodeName: "nodeA", - }, - }, + st.MakePod().Name("podA").Node("nodeA").Labels(map[string]string{"foo": "", "bar": ""}).Obj(), }, nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: map[string]string{"region": "r1", "zone": "z1", "hostname": "nodeA"}}}, @@ -1586,35 +833,10 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { name: "Test incoming pod's anti-affinity: only when labelSelector and topologyKey both match, it's counted as a single term match - case when one term has invalid topologyKey", }, { - pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "", "bar": ""}}, - }, + pod: st.MakePod().Label("foo", "").Label("bar", "").Obj(), pods: []*v1.Pod{ - createPodWithAffinityTerms(defaultNamespace, "nodeA", nil, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "region", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "bar", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }), + st.MakePod().Namespace(defaultNamespace).Node("nodeA").PodAntiAffinityExists("foo", "region", st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityExists("bar", "zone", st.PodAntiAffinityWithRequiredReq).Obj(), }, nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: map[string]string{"region": "r1", "zone": "z1", "hostname": "nodeA"}}}, @@ -1633,38 +855,10 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { name: "Test existing pod's anti-affinity: only when labelSelector and topologyKey both match, it's counted as a single term match - case when all terms have valid topologyKey", }, { - pod: createPodWithAffinityTerms(defaultNamespace, "", nil, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "region", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "bar", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }), + pod: st.MakePod().Namespace(defaultNamespace).PodAntiAffinityExists("foo", "region", st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityExists("bar", "zone", st.PodAntiAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - { - ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "", "bar": ""}}, - Spec: v1.PodSpec{ - NodeName: "nodeA", - }, - }, + st.MakePod().Node("nodeA").Labels(map[string]string{"foo": "", "bar": ""}).Obj(), }, nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: map[string]string{"region": "r1", "zone": "z1", "hostname": "nodeA"}}}, @@ -1683,60 +877,12 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { name: "Test incoming pod's anti-affinity: only when labelSelector and topologyKey both match, it's counted as a single term match - case when all terms have valid topologyKey", }, { - pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "", "bar": ""}}, - }, + pod: st.MakePod().Label("foo", "").Label("bar", "").Obj(), pods: []*v1.Pod{ - createPodWithAffinityTerms(defaultNamespace, "nodeA", nil, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "labelA", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }), - createPodWithAffinityTerms(defaultNamespace, "nodeB", nil, nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "bar", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "labelB", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }), + st.MakePod().Node("nodeA").Namespace(defaultNamespace).PodAntiAffinityExists("foo", "zone", st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityExists("labelA", "zone", st.PodAntiAffinityWithRequiredReq).Obj(), + st.MakePod().Node("nodeB").Namespace(defaultNamespace).PodAntiAffinityExists("bar", "zone", st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityExists("labelB", "zone", st.PodAntiAffinityWithRequiredReq).Obj(), }, nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: map[string]string{"region": "r1", "zone": "z1", "hostname": "nodeA"}}}, @@ -1757,38 +903,10 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { name: "Test existing pod's anti-affinity: existingPod on nodeA and nodeB has at least one anti-affinity term matches incoming pod, so incoming pod can only be scheduled to nodeC", }, { - pod: createPodWithAffinityTerms(defaultNamespace, "", nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "region", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "bar", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }, nil), + pod: st.MakePod().Namespace(defaultNamespace).PodAffinityExists("foo", "region", st.PodAffinityWithRequiredReq). + PodAffinityExists("bar", "zone", st.PodAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - { - ObjectMeta: metav1.ObjectMeta{Name: "pod1", Labels: map[string]string{"foo": "", "bar": ""}}, - Spec: v1.PodSpec{ - NodeName: "nodeA", - }, - }, + st.MakePod().Name("pod1").Labels(map[string]string{"foo": "", "bar": ""}).Node("nodeA").Obj(), }, nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: map[string]string{"region": "r1", "zone": "z1", "hostname": "nodeA"}}}, @@ -1798,44 +916,11 @@ func TestRequiredAffinityMultipleNodes(t *testing.T) { name: "Test incoming pod's affinity: firstly check if all affinityTerms match, and then check if all topologyKeys match", }, { - pod: createPodWithAffinityTerms(defaultNamespace, "", nil, - []v1.PodAffinityTerm{ - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "foo", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "region", - }, - { - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "bar", - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "zone", - }, - }, nil), + pod: st.MakePod().Namespace(defaultNamespace).PodAffinityExists("foo", "region", st.PodAffinityWithRequiredReq). + PodAffinityExists("bar", "zone", st.PodAffinityWithRequiredReq).Obj(), pods: []*v1.Pod{ - { - ObjectMeta: metav1.ObjectMeta{Name: "pod1", Labels: map[string]string{"foo": ""}}, - Spec: v1.PodSpec{ - NodeName: "nodeA", - }, - }, - { - ObjectMeta: metav1.ObjectMeta{Name: "pod2", Labels: map[string]string{"bar": ""}}, - Spec: v1.PodSpec{ - NodeName: "nodeB", - }, - }, + st.MakePod().Node("nodeA").Name("pod1").Namespace(defaultNamespace).Labels(map[string]string{"foo": ""}).Obj(), + st.MakePod().Node("nodeB").Name("pod2").Namespace(defaultNamespace).Labels(map[string]string{"bar": ""}).Obj(), }, nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: map[string]string{"region": "r1", "zone": "z1", "hostname": "nodeA"}}}, @@ -1993,10 +1078,8 @@ func TestPreFilterStateAddRemovePod(t *testing.T) { expectedAffinity topologyToMatchedTermCount }{ { - name: "no affinity exist", - pendingPod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "pending", Labels: selector1}, - }, + name: "no affinity exist", + pendingPod: st.MakePod().Name("pending").Labels(selector1).Obj(), existingPods: []*v1.Pod{ {ObjectMeta: metav1.ObjectMeta{Name: "p1", Labels: selector1}, Spec: v1.PodSpec{NodeName: "nodeA"}, @@ -2005,10 +1088,7 @@ func TestPreFilterStateAddRemovePod(t *testing.T) { Spec: v1.PodSpec{NodeName: "nodeC"}, }, }, - addedPod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "addedPod", Labels: selector1}, - Spec: v1.PodSpec{NodeName: "nodeB"}, - }, + addedPod: st.MakePod().Name("addedPod").Labels(selector1).Node("nodeB").Obj(), nodes: []*v1.Node{ {ObjectMeta: metav1.ObjectMeta{Name: "nodeA", Labels: label1}}, {ObjectMeta: metav1.ObjectMeta{Name: "nodeB", Labels: label2}}, @@ -2217,8 +1297,8 @@ func TestPreFilterStateAddRemovePod(t *testing.T) { func TestPreFilterStateClone(t *testing.T) { source := &preFilterState{ existingAntiAffinityCounts: topologyToMatchedTermCount{ - {key: "name", value: "machine1"}: 1, - {key: "name", value: "machine2"}: 1, + {key: "name", value: "node1"}: 1, + {key: "name", value: "node2"}: 1, }, affinityCounts: topologyToMatchedTermCount{ {key: "name", value: "nodeA"}: 1, @@ -2242,32 +1322,12 @@ func TestPreFilterStateClone(t *testing.T) { // TestGetTPMapMatchingIncomingAffinityAntiAffinity tests against method getTPMapMatchingIncomingAffinityAntiAffinity // on Anti Affinity cases func TestGetTPMapMatchingIncomingAffinityAntiAffinity(t *testing.T) { - newPodAffinityTerms := func(keys ...string) []v1.PodAffinityTerm { - var terms []v1.PodAffinityTerm - for _, key := range keys { - terms = append(terms, v1.PodAffinityTerm{ - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: key, - Operator: metav1.LabelSelectorOpExists, - }, - }, - }, - TopologyKey: "hostname", - }) - } - return terms - } newPod := func(labels ...string) *v1.Pod { - labelMap := make(map[string]string) + pod := st.MakePod().Name("normal").Node("nodeA") for _, l := range labels { - labelMap[l] = "" - } - return &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "normal", Labels: labelMap}, - Spec: v1.PodSpec{NodeName: "nodeA"}, + pod.Label(l, "") } + return pod.Obj() } normalPodA := newPod("aaa") normalPodB := newPod("bbb") @@ -2283,21 +1343,17 @@ func TestGetTPMapMatchingIncomingAffinityAntiAffinity(t *testing.T) { wantAntiAffinityPodsMap topologyToMatchedTermCount }{ { - name: "nil test", - nodes: []*v1.Node{nodeA}, - pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "aaa-normal"}, - }, + name: "nil test", + nodes: []*v1.Node{nodeA}, + pod: st.MakePod().Name("aaa-normal").Obj(), wantAffinityPodsMap: make(topologyToMatchedTermCount), wantAntiAffinityPodsMap: make(topologyToMatchedTermCount), }, { - name: "incoming pod without affinity/anti-affinity causes a no-op", - existingPods: []*v1.Pod{normalPodA}, - nodes: []*v1.Node{nodeA}, - pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "aaa-normal"}, - }, + name: "incoming pod without affinity/anti-affinity causes a no-op", + existingPods: []*v1.Pod{normalPodA}, + nodes: []*v1.Node{nodeA}, + pod: st.MakePod().Name("aaa-normal").Obj(), wantAffinityPodsMap: make(topologyToMatchedTermCount), wantAntiAffinityPodsMap: make(topologyToMatchedTermCount), }, @@ -2305,19 +1361,8 @@ func TestGetTPMapMatchingIncomingAffinityAntiAffinity(t *testing.T) { name: "no pod has label that violates incoming pod's affinity and anti-affinity", existingPods: []*v1.Pod{normalPodB}, nodes: []*v1.Node{nodeA}, - pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "aaa-anti"}, - Spec: v1.PodSpec{ - Affinity: &v1.Affinity{ - PodAffinity: &v1.PodAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: newPodAffinityTerms("aaa"), - }, - PodAntiAffinity: &v1.PodAntiAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: newPodAffinityTerms("aaa"), - }, - }, - }, - }, + pod: st.MakePod().Name("aaa-anti").PodAffinityExists("aaa", "hostname", st.PodAffinityWithRequiredReq). + PodAntiAffinityExists("aaa", "hostname", st.PodAntiAffinityWithRequiredReq).Obj(), wantAffinityPodsMap: make(topologyToMatchedTermCount), wantAntiAffinityPodsMap: make(topologyToMatchedTermCount), }, @@ -2325,19 +1370,8 @@ func TestGetTPMapMatchingIncomingAffinityAntiAffinity(t *testing.T) { name: "existing pod matches incoming pod's affinity and anti-affinity - single term case", existingPods: []*v1.Pod{normalPodA}, nodes: []*v1.Node{nodeA}, - pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "affi-antiaffi"}, - Spec: v1.PodSpec{ - Affinity: &v1.Affinity{ - PodAffinity: &v1.PodAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: newPodAffinityTerms("aaa"), - }, - PodAntiAffinity: &v1.PodAntiAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: newPodAffinityTerms("aaa"), - }, - }, - }, - }, + pod: st.MakePod().Name("affi-antiaffi").PodAffinityExists("aaa", "hostname", st.PodAffinityWithRequiredReq). + PodAntiAffinityExists("aaa", "hostname", st.PodAntiAffinityWithRequiredReq).Obj(), wantAffinityPodsMap: topologyToMatchedTermCount{ {key: "hostname", value: "nodeA"}: 1, }, @@ -2349,19 +1383,8 @@ func TestGetTPMapMatchingIncomingAffinityAntiAffinity(t *testing.T) { name: "existing pod matches incoming pod's affinity and anti-affinity - multiple terms case", existingPods: []*v1.Pod{normalPodAB}, nodes: []*v1.Node{nodeA}, - pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "affi-antiaffi"}, - Spec: v1.PodSpec{ - Affinity: &v1.Affinity{ - PodAffinity: &v1.PodAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: newPodAffinityTerms("aaa", "bbb"), - }, - PodAntiAffinity: &v1.PodAntiAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: newPodAffinityTerms("aaa"), - }, - }, - }, - }, + pod: st.MakePod().Name("affi-antiaffi").PodAffinityExists("aaa", "hostname", st.PodAffinityWithRequiredReq). + PodAffinityExists("bbb", "hostname", st.PodAffinityWithRequiredReq).PodAntiAffinityExists("aaa", "hostname", st.PodAntiAffinityWithRequiredReq).Obj(), wantAffinityPodsMap: topologyToMatchedTermCount{ {key: "hostname", value: "nodeA"}: 2, // 2 one for each term. }, @@ -2373,19 +1396,10 @@ func TestGetTPMapMatchingIncomingAffinityAntiAffinity(t *testing.T) { name: "existing pod not match incoming pod's affinity but matches anti-affinity", existingPods: []*v1.Pod{normalPodA}, nodes: []*v1.Node{nodeA}, - pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "affi-antiaffi"}, - Spec: v1.PodSpec{ - Affinity: &v1.Affinity{ - PodAffinity: &v1.PodAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: newPodAffinityTerms("aaa", "bbb"), - }, - PodAntiAffinity: &v1.PodAntiAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: newPodAffinityTerms("aaa", "bbb"), - }, - }, - }, - }, + pod: st.MakePod().Name("affi-antiaffi").PodAffinityExists("aaa", "hostname", st.PodAffinityWithRequiredReq). + PodAffinityExists("bbb", "hostname", st.PodAffinityWithRequiredReq). + PodAntiAffinityExists("aaa", "hostname", st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityExists("bbb", "hostname", st.PodAntiAffinityWithRequiredReq).Obj(), wantAffinityPodsMap: make(topologyToMatchedTermCount), wantAntiAffinityPodsMap: topologyToMatchedTermCount{ {key: "hostname", value: "nodeA"}: 1, @@ -2395,19 +1409,10 @@ func TestGetTPMapMatchingIncomingAffinityAntiAffinity(t *testing.T) { name: "incoming pod's anti-affinity has more than one term - existing pod violates partial term - case 1", existingPods: []*v1.Pod{normalPodAB}, nodes: []*v1.Node{nodeA}, - pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "anaffi-antiaffiti"}, - Spec: v1.PodSpec{ - Affinity: &v1.Affinity{ - PodAffinity: &v1.PodAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: newPodAffinityTerms("aaa", "ccc"), - }, - PodAntiAffinity: &v1.PodAntiAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: newPodAffinityTerms("aaa", "ccc"), - }, - }, - }, - }, + pod: st.MakePod().Name("anaffi-antiaffiti").PodAffinityExists("aaa", "hostname", st.PodAffinityWithRequiredReq). + PodAffinityExists("ccc", "hostname", st.PodAffinityWithRequiredReq). + PodAntiAffinityExists("aaa", "hostname", st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityExists("ccc", "hostname", st.PodAntiAffinityWithRequiredReq).Obj(), wantAffinityPodsMap: make(topologyToMatchedTermCount), wantAntiAffinityPodsMap: topologyToMatchedTermCount{ {key: "hostname", value: "nodeA"}: 1, @@ -2417,19 +1422,10 @@ func TestGetTPMapMatchingIncomingAffinityAntiAffinity(t *testing.T) { name: "incoming pod's anti-affinity has more than one term - existing pod violates partial term - case 2", existingPods: []*v1.Pod{normalPodB}, nodes: []*v1.Node{nodeA}, - pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "affi-antiaffi"}, - Spec: v1.PodSpec{ - Affinity: &v1.Affinity{ - PodAffinity: &v1.PodAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: newPodAffinityTerms("aaa", "bbb"), - }, - PodAntiAffinity: &v1.PodAntiAffinity{ - RequiredDuringSchedulingIgnoredDuringExecution: newPodAffinityTerms("aaa", "bbb"), - }, - }, - }, - }, + pod: st.MakePod().Name("affi-antiaffi").PodAffinityExists("aaa", "hostname", st.PodAffinityWithRequiredReq). + PodAffinityExists("bbb", "hostname", st.PodAffinityWithRequiredReq). + PodAntiAffinityExists("aaa", "hostname", st.PodAntiAffinityWithRequiredReq). + PodAntiAffinityExists("bbb", "hostname", st.PodAntiAffinityWithRequiredReq).Obj(), wantAffinityPodsMap: make(topologyToMatchedTermCount), wantAntiAffinityPodsMap: topologyToMatchedTermCount{ {key: "hostname", value: "nodeA"}: 1, diff --git a/pkg/scheduler/framework/plugins/interpodaffinity/scoring_test.go b/pkg/scheduler/framework/plugins/interpodaffinity/scoring_test.go index 4e227f7066e..1093797ad30 100644 --- a/pkg/scheduler/framework/plugins/interpodaffinity/scoring_test.go +++ b/pkg/scheduler/framework/plugins/interpodaffinity/scoring_test.go @@ -22,7 +22,7 @@ import ( "strings" "testing" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/kubernetes/pkg/scheduler/apis/config" @@ -377,52 +377,52 @@ func TestPreferredAffinity(t *testing.T) { wantStatus *framework.Status }{ { - name: "all machines are same priority as Affinity is nil", + name: "all nodes are same priority as Affinity is nil", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelAzAz1}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}, {Name: "machine3", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}, {Name: "node3", Score: 0}}, }, - // the node(machine1) that have the label {"region": "China"} (match the topology key) and that have existing pods that match the labelSelector get high score - // the node(machine3) that don't have the label {"region": "whatever the value is"} (mismatch the topology key) but that have existing pods that match the labelSelector get low score - // the node(machine2) that have the label {"region": "China"} (match the topology key) but that have existing pods that mismatch the labelSelector get low score + // the node(node1) that have the label {"region": "China"} (match the topology key) and that have existing pods that match the labelSelector get high score + // the node(node3) that don't have the label {"region": "whatever the value is"} (mismatch the topology key) but that have existing pods that match the labelSelector get low score + // the node(node2) that have the label {"region": "China"} (match the topology key) but that have existing pods that mismatch the labelSelector get low score { name: "Affinity: pod that matches topology key & pods in nodes will get high score comparing to others" + "which doesn't match either pods in nodes or in topology key", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: stayWithS1InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, - {Spec: v1.PodSpec{NodeName: "machine3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, + {Spec: v1.PodSpec{NodeName: "node3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelAzAz1}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: 0}, {Name: "machine3", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: 0}, {Name: "node3", Score: 0}}, }, - // the node1(machine1) that have the label {"region": "China"} (match the topology key) and that have existing pods that match the labelSelector get high score - // the node2(machine2) that have the label {"region": "China"}, match the topology key and have the same label value with node1, get the same high score with node1 - // the node3(machine3) that have the label {"region": "India"}, match the topology key but have a different label value, don't have existing pods that match the labelSelector, + // the node1(node1) that have the label {"region": "China"} (match the topology key) and that have existing pods that match the labelSelector get high score + // the node2(node2) that have the label {"region": "China"}, match the topology key and have the same label value with node1, get the same high score with node1 + // the node3(node3) that have the label {"region": "India"}, match the topology key but have a different label value, don't have existing pods that match the labelSelector, // get a low score. { name: "All the nodes that have the same topology key & label value with one of them has an existing pod that match the affinity rules, have the same score", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: stayWithS1InRegion}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgChinaAzAz1}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgChinaAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelRgIndia}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: framework.MaxNodeScore}, {Name: "machine3", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: framework.MaxNodeScore}, {Name: "node3", Score: 0}}, }, - // there are 2 regions, say regionChina(machine1,machine3,machine4) and regionIndia(machine2,machine5), both regions have nodes that match the preference. + // there are 2 regions, say regionChina(node1,node3,node4) and regionIndia(node2,node5), both regions have nodes that match the preference. // But there are more nodes(actually more existing pods) in regionChina that match the preference than regionIndia. // Then, nodes in regionChina get higher score than nodes in regionIndia, and all the nodes in regionChina should get a same score(high score), // while all the nodes in regionIndia should get another same score(low score). @@ -430,37 +430,37 @@ func TestPreferredAffinity(t *testing.T) { name: "Affinity: nodes in one region has more matching pods comparing to other region, so the region which has more matches will get high score", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: stayWithS2InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, - {Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, - {Spec: v1.PodSpec{NodeName: "machine3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, - {Spec: v1.PodSpec{NodeName: "machine4"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, - {Spec: v1.PodSpec{NodeName: "machine5"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, + {Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, + {Spec: v1.PodSpec{NodeName: "node3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, + {Spec: v1.PodSpec{NodeName: "node4"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, + {Spec: v1.PodSpec{NodeName: "node5"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine4", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine5", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node4", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node5", Labels: labelRgIndia}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: 0}, {Name: "machine3", Score: framework.MaxNodeScore}, {Name: "machine4", Score: framework.MaxNodeScore}, {Name: "machine5", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: 0}, {Name: "node3", Score: framework.MaxNodeScore}, {Name: "node4", Score: framework.MaxNodeScore}, {Name: "node5", Score: 0}}, }, // Test with the different operators and values for pod affinity scheduling preference, including some match failures. { name: "Affinity: different Label operators and values for pod affinity scheduling preference, including some match failures ", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: affinity3}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, - {Spec: v1.PodSpec{NodeName: "machine3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, + {Spec: v1.PodSpec{NodeName: "node3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelAzAz1}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 20}, {Name: "machine2", Score: framework.MaxNodeScore}, {Name: "machine3", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 20}, {Name: "node2", Score: framework.MaxNodeScore}, {Name: "node3", Score: 0}}, }, // Test the symmetry cases for affinity, the difference between affinity and symmetry is not the pod wants to run together with some existing pods, // but the existing pods have the inter pod affinity preference while the pod to schedule satisfy the preference. @@ -468,57 +468,57 @@ func TestPreferredAffinity(t *testing.T) { name: "Affinity symmetry: considered only the preferredDuringSchedulingIgnoredDuringExecution in pod affinity symmetry", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1", Affinity: stayWithS1InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2", Affinity: stayWithS2InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, + {Spec: v1.PodSpec{NodeName: "node1", Affinity: stayWithS1InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2", Affinity: stayWithS2InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelAzAz1}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: framework.MaxNodeScore}, {Name: "machine3", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: framework.MaxNodeScore}, {Name: "node3", Score: 0}}, }, { name: "Affinity symmetry with namespace selector", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1", Affinity: affinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2", Affinity: stayWithS2InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, + {Spec: v1.PodSpec{NodeName: "node1", Affinity: affinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2", Affinity: stayWithS2InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelAzAz1}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: 0}, {Name: "machine3", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: 0}, {Name: "node3", Score: 0}}, }, { name: "AntiAffinity symmetry with namespace selector", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1", Affinity: antiAffinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2", Affinity: stayWithS2InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, + {Spec: v1.PodSpec{NodeName: "node1", Affinity: antiAffinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2", Affinity: stayWithS2InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelAzAz1}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: framework.MaxNodeScore}, {Name: "machine3", Score: framework.MaxNodeScore}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: framework.MaxNodeScore}, {Name: "node3", Score: framework.MaxNodeScore}}, }, { name: "Affinity symmetry: considered RequiredDuringSchedulingIgnoredDuringExecution in pod affinity symmetry", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1", Affinity: hardAffinity}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2", Affinity: hardAffinity}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, + {Spec: v1.PodSpec{NodeName: "node1", Affinity: hardAffinity}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2", Affinity: hardAffinity}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelAzAz1}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: framework.MaxNodeScore}, {Name: "machine3", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: framework.MaxNodeScore}, {Name: "node3", Score: 0}}, }, // The pod to schedule prefer to stay away from some existing pods at node level using the pod anti affinity. @@ -531,94 +531,94 @@ func TestPreferredAffinity(t *testing.T) { name: "Anti Affinity: pod that does not match existing pods in node will get high score ", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: awayFromS1InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelAzAz1}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgChina}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: framework.MaxNodeScore}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: framework.MaxNodeScore}}, }, { name: "Anti Affinity: pod that does not match topology key & match the pods in nodes will get higher score comparing to others ", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: awayFromS1InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelAzAz1}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgChina}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: framework.MaxNodeScore}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: framework.MaxNodeScore}}, }, { name: "Anti Affinity: one node has more matching pods comparing to other node, so the node which has more unmatches will get high score", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: awayFromS1InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelAzAz1}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: framework.MaxNodeScore}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: framework.MaxNodeScore}}, }, // Test the symmetry cases for anti affinity { name: "Anti Affinity symmetry: the existing pods in node which has anti affinity match will get high score", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1", Affinity: awayFromS2InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2", Affinity: awayFromS1InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, + {Spec: v1.PodSpec{NodeName: "node1", Affinity: awayFromS2InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2", Affinity: awayFromS1InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelAzAz1}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelAzAz2}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelAzAz2}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: framework.MaxNodeScore}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: framework.MaxNodeScore}}, }, // Test both affinity and anti-affinity { name: "Affinity and Anti Affinity: considered only preferredDuringSchedulingIgnoredDuringExecution in both pod affinity & anti affinity", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: stayWithS1InRegionAwayFromS2InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelAzAz1}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: 0}}, }, // Combined cases considering both affinity and anti-affinity, the pod to schedule and existing pods have the same labels (they are in the same RC/service), // the pod prefer to run together with its brother pods in the same region, but wants to stay away from them at node level, // so that all the pods of a RC/service can stay in a same region but trying to separate with each other - // machine-1,machine-3,machine-4 are in ChinaRegion others machine-2,machine-5 are in IndiaRegion + // node-1,node-3,node-4 are in ChinaRegion others node-2,node-5 are in IndiaRegion { name: "Affinity and Anti Affinity: considering both affinity and anti-affinity, the pod to schedule and existing pods have the same labels", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: stayWithS1InRegionAwayFromS2InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine4"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine5"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node4"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node5"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChinaAzAz1}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine4", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine5", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChinaAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node4", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node5", Labels: labelRgIndia}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: 0}, {Name: "machine3", Score: framework.MaxNodeScore}, {Name: "machine4", Score: framework.MaxNodeScore}, {Name: "machine5", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: 0}, {Name: "node3", Score: framework.MaxNodeScore}, {Name: "node4", Score: framework.MaxNodeScore}, {Name: "node5", Score: 0}}, }, // Consider Affinity, Anti Affinity and symmetry together. // for Affinity, the weights are: 8, 0, 0, 0 @@ -629,18 +629,18 @@ func TestPreferredAffinity(t *testing.T) { name: "Affinity and Anti Affinity and symmetry: considered only preferredDuringSchedulingIgnoredDuringExecution in both pod affinity & anti affinity & symmetry", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: stayWithS1InRegionAwayFromS2InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, - {Spec: v1.PodSpec{NodeName: "machine3", Affinity: stayWithS1InRegionAwayFromS2InAz}}, - {Spec: v1.PodSpec{NodeName: "machine4", Affinity: awayFromS1InAz}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}}, + {Spec: v1.PodSpec{NodeName: "node3", Affinity: stayWithS1InRegionAwayFromS2InAz}}, + {Spec: v1.PodSpec{NodeName: "node4", Affinity: awayFromS1InAz}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelAzAz1}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelRgIndia}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine4", Labels: labelAzAz2}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node4", Labels: labelAzAz2}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: 0}, {Name: "machine3", Score: framework.MaxNodeScore}, {Name: "machine4", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: 0}, {Name: "node3", Score: framework.MaxNodeScore}, {Name: "node4", Score: 0}}, }, // Cover https://github.com/kubernetes/kubernetes/issues/82796 which panics upon: // 1. Some nodes in a topology don't have pods with affinity, but other nodes in the same topology have. @@ -649,22 +649,22 @@ func TestPreferredAffinity(t *testing.T) { name: "Avoid panic when partial nodes in a topology don't have pods with affinity", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2", Affinity: stayWithS1InRegionAwayFromS2InAz}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2", Affinity: stayWithS1InRegionAwayFromS2InAz}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgChina}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}}, }, { name: "invalid Affinity fails PreScore", pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: invalidAffinityLabels}}, wantStatus: framework.NewStatus(framework.Error, `Invalid value: "{{.bad-value.}}"`), nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgChina}}, }, }, { @@ -672,69 +672,69 @@ func TestPreferredAffinity(t *testing.T) { pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: invalidAntiAffinityLabels}}, wantStatus: framework.NewStatus(framework.Error, `Invalid value: "{{.bad-value.}}"`), nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgChina}}, }, }, { name: "Affinity with pods matching NamespaceSelector", pod: &v1.Pod{Spec: v1.PodSpec{Affinity: affinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team2", Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team1", Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team2", Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team1", Labels: podLabelSecurityS1}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: 0}}, }, { name: "Affinity with pods matching both NamespaceSelector and Namespaces fields", pod: &v1.Pod{Spec: v1.PodSpec{Affinity: affinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team2", Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team1", Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team2", Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team1", Labels: podLabelSecurityS1}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: 0}}, }, { name: "Affinity with pods matching NamespaceSelector", pod: &v1.Pod{Spec: v1.PodSpec{Affinity: antiAffinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team2", Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team1", Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team2", Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team1", Labels: podLabelSecurityS1}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: framework.MaxNodeScore}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: framework.MaxNodeScore}}, }, { name: "Affinity with pods matching both NamespaceSelector and Namespaces fields", pod: &v1.Pod{Spec: v1.PodSpec{Affinity: antiAffinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team2", Labels: podLabelSecurityS1}}, - {Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team1", Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team2", Labels: podLabelSecurityS1}}, + {Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team1", Labels: podLabelSecurityS1}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: framework.MaxNodeScore}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: framework.MaxNodeScore}}, }, } for _, test := range tests { @@ -826,76 +826,76 @@ func TestPreferredAffinityWithHardPodAffinitySymmetricWeight(t *testing.T) { name: "with default weight", pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: podLabelServiceS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1", Affinity: hardPodAffinity}}, - {Spec: v1.PodSpec{NodeName: "machine2", Affinity: hardPodAffinity}}, + {Spec: v1.PodSpec{NodeName: "node1", Affinity: hardPodAffinity}}, + {Spec: v1.PodSpec{NodeName: "node2", Affinity: hardPodAffinity}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelAzAz1}}, }, hardPodAffinityWeight: v1.DefaultHardPodAffinitySymmetricWeight, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: framework.MaxNodeScore}, {Name: "machine3", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: framework.MaxNodeScore}, {Name: "node3", Score: 0}}, }, { name: "with zero weight", pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: podLabelServiceS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1", Affinity: hardPodAffinity}}, - {Spec: v1.PodSpec{NodeName: "machine2", Affinity: hardPodAffinity}}, + {Spec: v1.PodSpec{NodeName: "node1", Affinity: hardPodAffinity}}, + {Spec: v1.PodSpec{NodeName: "node2", Affinity: hardPodAffinity}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelAzAz1}}, }, hardPodAffinityWeight: 0, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}, {Name: "machine3", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}, {Name: "node3", Score: 0}}, }, { name: "with no matching namespace", pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team2", Labels: podLabelServiceS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1", Affinity: hardPodAffinity}}, - {Spec: v1.PodSpec{NodeName: "machine2", Affinity: hardPodAffinity}}, + {Spec: v1.PodSpec{NodeName: "node1", Affinity: hardPodAffinity}}, + {Spec: v1.PodSpec{NodeName: "node2", Affinity: hardPodAffinity}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelAzAz1}}, }, hardPodAffinityWeight: v1.DefaultHardPodAffinitySymmetricWeight, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}, {Name: "machine3", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}, {Name: "node3", Score: 0}}, }, { name: "with matching NamespaceSelector", pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelServiceS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1", Affinity: hardPodAffinity}}, - {Spec: v1.PodSpec{NodeName: "machine2", Affinity: hardPodAffinity}}, + {Spec: v1.PodSpec{NodeName: "node1", Affinity: hardPodAffinity}}, + {Spec: v1.PodSpec{NodeName: "node2", Affinity: hardPodAffinity}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelAzAz1}}, }, hardPodAffinityWeight: v1.DefaultHardPodAffinitySymmetricWeight, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: framework.MaxNodeScore}, {Name: "machine3", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: framework.MaxNodeScore}, {Name: "node3", Score: 0}}, }, { name: "with matching Namespaces", pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team2", Labels: podLabelServiceS1}}, pods: []*v1.Pod{ - {Spec: v1.PodSpec{NodeName: "machine1", Affinity: hardPodAffinity}}, - {Spec: v1.PodSpec{NodeName: "machine2", Affinity: hardPodAffinity}}, + {Spec: v1.PodSpec{NodeName: "node1", Affinity: hardPodAffinity}}, + {Spec: v1.PodSpec{NodeName: "node2", Affinity: hardPodAffinity}}, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelAzAz1}}, }, hardPodAffinityWeight: v1.DefaultHardPodAffinitySymmetricWeight, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: framework.MaxNodeScore}, {Name: "machine3", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: framework.MaxNodeScore}, {Name: "node3", Score: 0}}, }, } for _, test := range tests { diff --git a/pkg/scheduler/framework/plugins/nodeaffinity/node_affinity_test.go b/pkg/scheduler/framework/plugins/nodeaffinity/node_affinity_test.go index ba0da937273..e2ab85bcab1 100644 --- a/pkg/scheduler/framework/plugins/nodeaffinity/node_affinity_test.go +++ b/pkg/scheduler/framework/plugins/nodeaffinity/node_affinity_test.go @@ -28,6 +28,7 @@ import ( "k8s.io/kubernetes/pkg/scheduler/framework" "k8s.io/kubernetes/pkg/scheduler/framework/runtime" "k8s.io/kubernetes/pkg/scheduler/internal/cache" + st "k8s.io/kubernetes/pkg/scheduler/testing" ) // TODO: Add test case for RequiredDuringSchedulingRequiredDuringExecution after it's implemented. @@ -49,37 +50,25 @@ func TestNodeAffinity(t *testing.T) { }, { name: "missing labels", - pod: &v1.Pod{ - Spec: v1.PodSpec{ - NodeSelector: map[string]string{ - "foo": "bar", - }, - }, - }, + pod: st.MakePod().NodeSelector(map[string]string{ + "foo": "bar", + }).Obj(), wantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReasonPod), }, { name: "same labels", - pod: &v1.Pod{ - Spec: v1.PodSpec{ - NodeSelector: map[string]string{ - "foo": "bar", - }, - }, - }, + pod: st.MakePod().NodeSelector(map[string]string{ + "foo": "bar", + }).Obj(), labels: map[string]string{ "foo": "bar", }, }, { name: "node labels are superset", - pod: &v1.Pod{ - Spec: v1.PodSpec{ - NodeSelector: map[string]string{ - "foo": "bar", - }, - }, - }, + pod: st.MakePod().NodeSelector(map[string]string{ + "foo": "bar", + }).Obj(), labels: map[string]string{ "foo": "bar", "baz": "blah", @@ -87,14 +76,10 @@ func TestNodeAffinity(t *testing.T) { }, { name: "node labels are subset", - pod: &v1.Pod{ - Spec: v1.PodSpec{ - NodeSelector: map[string]string{ - "foo": "bar", - "baz": "blah", - }, - }, - }, + pod: st.MakePod().NodeSelector(map[string]string{ + "foo": "bar", + "baz": "blah", + }).Obj(), labels: map[string]string{ "foo": "bar", }, @@ -1029,69 +1014,69 @@ func TestNodeAffinityPriority(t *testing.T) { disablePreScore bool }{ { - name: "all machines are same priority as NodeAffinity is nil", + name: "all nodes are same priority as NodeAffinity is nil", pod: &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{}, }, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: label1}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: label2}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: label3}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: label1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: label2}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: label3}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}, {Name: "machine3", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}, {Name: "node3", Score: 0}}, }, { - name: "no machine matches preferred scheduling requirements in NodeAffinity of pod so all machines' priority is zero", + name: "no node matches preferred scheduling requirements in NodeAffinity of pod so all nodes' priority is zero", pod: &v1.Pod{ Spec: v1.PodSpec{ Affinity: affinity1, }, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: label4}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: label2}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: label3}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: label4}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: label2}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: label3}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}, {Name: "machine3", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}, {Name: "node3", Score: 0}}, }, { - name: "only machine1 matches the preferred scheduling requirements of pod", + name: "only node1 matches the preferred scheduling requirements of pod", pod: &v1.Pod{ Spec: v1.PodSpec{ Affinity: affinity1, }, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: label1}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: label2}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: label3}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: label1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: label2}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: label3}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: 0}, {Name: "machine3", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: 0}, {Name: "node3", Score: 0}}, }, { - name: "all machines matches the preferred scheduling requirements of pod but with different priorities ", + name: "all nodes matches the preferred scheduling requirements of pod but with different priorities ", pod: &v1.Pod{ Spec: v1.PodSpec{ Affinity: affinity2, }, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: label1}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine5", Labels: label5}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: label2}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: label1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node5", Labels: label5}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: label2}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 18}, {Name: "machine5", Score: framework.MaxNodeScore}, {Name: "machine2", Score: 36}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 18}, {Name: "node5", Score: framework.MaxNodeScore}, {Name: "node2", Score: 36}}, }, { name: "added affinity", pod: &v1.Pod{}, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: label1}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: label2}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: label1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: label2}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: 0}}, args: config.NodeAffinityArgs{ AddedAffinity: affinity1.NodeAffinity, }, @@ -1104,11 +1089,11 @@ func TestNodeAffinityPriority(t *testing.T) { }, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: label1}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: label2}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: label5}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: label1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: label2}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: label5}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 40}, {Name: "machine2", Score: 60}, {Name: "machine3", Score: framework.MaxNodeScore}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 40}, {Name: "node2", Score: 60}, {Name: "node3", Score: framework.MaxNodeScore}}, args: config.NodeAffinityArgs{ AddedAffinity: &v1.NodeAffinity{ PreferredDuringSchedulingIgnoredDuringExecution: []v1.PreferredSchedulingTerm{ @@ -1136,11 +1121,11 @@ func TestNodeAffinityPriority(t *testing.T) { }, }, nodes: []*v1.Node{ - {ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: label1}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine5", Labels: label5}}, - {ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: label2}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: label1}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node5", Labels: label5}}, + {ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: label2}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 18}, {Name: "machine5", Score: framework.MaxNodeScore}, {Name: "machine2", Score: 36}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 18}, {Name: "node5", Score: framework.MaxNodeScore}, {Name: "node2", Score: 36}}, disablePreScore: true, }, } diff --git a/pkg/scheduler/framework/plugins/nodename/node_name_test.go b/pkg/scheduler/framework/plugins/nodename/node_name_test.go index db5abaa4767..90461ea5676 100644 --- a/pkg/scheduler/framework/plugins/nodename/node_name_test.go +++ b/pkg/scheduler/framework/plugins/nodename/node_name_test.go @@ -22,8 +22,8 @@ import ( "testing" v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/kubernetes/pkg/scheduler/framework" + st "k8s.io/kubernetes/pkg/scheduler/testing" ) func TestNodeName(t *testing.T) { @@ -39,29 +39,13 @@ func TestNodeName(t *testing.T) { name: "no host specified", }, { - pod: &v1.Pod{ - Spec: v1.PodSpec{ - NodeName: "foo", - }, - }, - node: &v1.Node{ - ObjectMeta: metav1.ObjectMeta{ - Name: "foo", - }, - }, + pod: st.MakePod().Node("foo").Obj(), + node: st.MakeNode().Name("foo").Obj(), name: "host matches", }, { - pod: &v1.Pod{ - Spec: v1.PodSpec{ - NodeName: "bar", - }, - }, - node: &v1.Node{ - ObjectMeta: metav1.ObjectMeta{ - Name: "foo", - }, - }, + pod: st.MakePod().Node("bar").Obj(), + node: st.MakeNode().Name("foo").Obj(), name: "host doesn't match", wantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReason), }, diff --git a/pkg/scheduler/framework/plugins/nodeports/node_ports_test.go b/pkg/scheduler/framework/plugins/nodeports/node_ports_test.go index f02bfca54f2..f148461701f 100644 --- a/pkg/scheduler/framework/plugins/nodeports/node_ports_test.go +++ b/pkg/scheduler/framework/plugins/nodeports/node_ports_test.go @@ -27,6 +27,7 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/diff" "k8s.io/kubernetes/pkg/scheduler/framework" + st "k8s.io/kubernetes/pkg/scheduler/testing" ) func newPod(host string, hostPortInfos ...string) *v1.Pod { @@ -41,16 +42,7 @@ func newPod(host string, hostPortInfos ...string) *v1.Pod { Protocol: v1.Protocol(splited[0]), }) } - return &v1.Pod{ - Spec: v1.PodSpec{ - NodeName: host, - Containers: []v1.Container{ - { - Ports: networkPorts, - }, - }, - }, - } + return st.MakePod().Node(host).ContainerPort(networkPorts).Obj() } func TestNodePorts(t *testing.T) { @@ -184,66 +176,42 @@ func TestGetContainerPorts(t *testing.T) { expected []*v1.ContainerPort }{ { - pod1: &v1.Pod{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - { - Ports: []v1.ContainerPort{ - { - ContainerPort: 8001, - Protocol: v1.ProtocolTCP, - }, - { - ContainerPort: 8002, - Protocol: v1.ProtocolTCP, - }, - }, - }, - { - Ports: []v1.ContainerPort{ - { - ContainerPort: 8003, - Protocol: v1.ProtocolTCP, - }, - { - ContainerPort: 8004, - Protocol: v1.ProtocolTCP, - }, - }, - }, - }, + pod1: st.MakePod().ContainerPort([]v1.ContainerPort{ + { + ContainerPort: 8001, + Protocol: v1.ProtocolTCP, }, - }, - pod2: &v1.Pod{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - { - Ports: []v1.ContainerPort{ - { - ContainerPort: 8011, - Protocol: v1.ProtocolTCP, - }, - { - ContainerPort: 8012, - Protocol: v1.ProtocolTCP, - }, - }, - }, - { - Ports: []v1.ContainerPort{ - { - ContainerPort: 8013, - Protocol: v1.ProtocolTCP, - }, - { - ContainerPort: 8014, - Protocol: v1.ProtocolTCP, - }, - }, - }, - }, + { + ContainerPort: 8002, + Protocol: v1.ProtocolTCP, + }}).ContainerPort([]v1.ContainerPort{ + { + ContainerPort: 8003, + Protocol: v1.ProtocolTCP, }, - }, + { + ContainerPort: 8004, + Protocol: v1.ProtocolTCP, + }, + }).Obj(), + pod2: st.MakePod().ContainerPort([]v1.ContainerPort{ + { + ContainerPort: 8011, + Protocol: v1.ProtocolTCP, + }, + { + ContainerPort: 8012, + Protocol: v1.ProtocolTCP, + }}).ContainerPort([]v1.ContainerPort{ + { + ContainerPort: 8013, + Protocol: v1.ProtocolTCP, + }, + { + ContainerPort: 8014, + Protocol: v1.ProtocolTCP, + }, + }).Obj(), expected: []*v1.ContainerPort{ { ContainerPort: 8001, diff --git a/pkg/scheduler/framework/plugins/noderesources/balanced_allocation_test.go b/pkg/scheduler/framework/plugins/noderesources/balanced_allocation_test.go index b728cd2d41e..4376f8025de 100644 --- a/pkg/scheduler/framework/plugins/noderesources/balanced_allocation_test.go +++ b/pkg/scheduler/framework/plugins/noderesources/balanced_allocation_test.go @@ -29,6 +29,7 @@ import ( "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" "k8s.io/kubernetes/pkg/scheduler/framework/runtime" "k8s.io/kubernetes/pkg/scheduler/internal/cache" + st "k8s.io/kubernetes/pkg/scheduler/testing" ) func TestNodeResourcesBalancedAllocation(t *testing.T) { @@ -52,7 +53,7 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) { }, }, }, - NodeName: "machine1", + NodeName: "node1", } labels1 := map[string]string{ "foo": "bar", @@ -62,17 +63,8 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) { "bar": "foo", "baz": "blah", } - machine1Spec := v1.PodSpec{ - NodeName: "machine1", - } - machine2Spec := v1.PodSpec{ - NodeName: "machine2", - } - noResources := v1.PodSpec{ - Containers: []v1.Container{}, - } cpuOnly := v1.PodSpec{ - NodeName: "machine1", + NodeName: "node1", Containers: []v1.Container{ { Resources: v1.ResourceRequirements{ @@ -93,9 +85,9 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) { }, } cpuOnly2 := cpuOnly - cpuOnly2.NodeName = "machine2" + cpuOnly2.NodeName = "node2" cpuAndMemory := v1.PodSpec{ - NodeName: "machine2", + NodeName: "node2", Containers: []v1.Container{ { Resources: v1.ResourceRequirements{ @@ -115,13 +107,6 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) { }, }, } - nonZeroContainer := v1.PodSpec{ - Containers: []v1.Container{{}}, - } - nonZeroContainer1 := v1.PodSpec{ - NodeName: "machine1", - Containers: []v1.Container{{}}, - } defaultResourceBalancedAllocationSet := []config.ResourceSpec{ {Name: string(v1.ResourceCPU), Weight: 1}, @@ -148,9 +133,9 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) { // CPU Fraction: 0 / 4000 = 0 % // Memory Fraction: 0 / 10000 = 0% // Node2 Score: (1-0) * MaxNodeScore = MaxNodeScore - pod: &v1.Pod{Spec: noResources}, - nodes: []*v1.Node{makeNode("machine1", 4000, 10000, nil), makeNode("machine2", 4000, 10000, nil)}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: framework.MaxNodeScore}}, + pod: st.MakePod().Obj(), + nodes: []*v1.Node{makeNode("node1", 4000, 10000, nil), makeNode("node2", 4000, 10000, nil)}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: framework.MaxNodeScore}}, name: "nothing scheduled, nothing requested", args: config.NodeResourcesBalancedAllocationArgs{Resources: defaultResourceBalancedAllocationSet}, }, @@ -166,9 +151,9 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) { // Node2 std: 0 // Node2 Score: (1-0) * MaxNodeScore = MaxNodeScore pod: &v1.Pod{Spec: cpuAndMemory}, - nodes: []*v1.Node{makeNode("machine1", 4000, 10000, nil), makeNode("machine2", 6000, 10000, nil)}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 87}, {Name: "machine2", Score: framework.MaxNodeScore}}, - name: "nothing scheduled, resources requested, differently sized machines", + nodes: []*v1.Node{makeNode("node1", 4000, 10000, nil), makeNode("node2", 6000, 10000, nil)}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 87}, {Name: "node2", Score: framework.MaxNodeScore}}, + name: "nothing scheduled, resources requested, differently sized nodes", args: config.NodeResourcesBalancedAllocationArgs{Resources: defaultResourceBalancedAllocationSet}, }, { @@ -182,15 +167,15 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) { // Memory Fraction: 0 / 10000 = 0% // Node2 std: 0 // Node2 Score: (1-0) * MaxNodeScore = MaxNodeScore - pod: &v1.Pod{Spec: noResources}, - nodes: []*v1.Node{makeNode("machine1", 4000, 10000, nil), makeNode("machine2", 4000, 10000, nil)}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: framework.MaxNodeScore}}, + pod: st.MakePod().Obj(), + nodes: []*v1.Node{makeNode("node1", 4000, 10000, nil), makeNode("node2", 4000, 10000, nil)}, + expectedList: []framework.NodeScore{{Name: "node2", Score: framework.MaxNodeScore}, {Name: "node2", Score: framework.MaxNodeScore}}, name: "no resources requested, pods without container scheduled", pods: []*v1.Pod{ - {Spec: machine1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}}, - {Spec: machine1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, - {Spec: machine2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, - {Spec: machine2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, + st.MakePod().Node("node1").Labels(labels2).Obj(), + st.MakePod().Node("node1").Labels(labels1).Obj(), + st.MakePod().Node("node2").Labels(labels1).Obj(), + st.MakePod().Node("node2").Labels(labels1).Obj(), }, args: config.NodeResourcesBalancedAllocationArgs{Resources: defaultResourceBalancedAllocationSet}, }, @@ -205,13 +190,13 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) { // Memory Fraction: 0 / 1000 = 0% // Node2 std: (0 - 0) / 2 = 0 // Node2 Score: (1 - 0)*MaxNodeScore = 100 - pod: &v1.Pod{Spec: nonZeroContainer}, - nodes: []*v1.Node{makeNode("machine1", 250, 1000*1024*1024, nil), makeNode("machine2", 250, 1000*1024*1024, nil)}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 100}, {Name: "machine2", Score: 100}}, + pod: st.MakePod().Obj(), + nodes: []*v1.Node{makeNode("node1", 250, 1000*1024*1024, nil), makeNode("node2", 250, 1000*1024*1024, nil)}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 100}, {Name: "node2", Score: 100}}, name: "no resources requested, pods with container scheduled", pods: []*v1.Pod{ - {Spec: nonZeroContainer1}, - {Spec: nonZeroContainer1}, + st.MakePod().Node("node1").Obj(), + st.MakePod().Node("node1").Obj(), }, args: config.NodeResourcesBalancedAllocationArgs{Resources: defaultResourceBalancedAllocationSet}, }, @@ -226,9 +211,9 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) { // Memory Fraction: 5000 / 20000 = 25% // Node2 std: (0.6 - 0.25) / 2 = 0.175 // Node2 Score: (1 - 0.175)*MaxNodeScore = 82 - pod: &v1.Pod{Spec: noResources}, - nodes: []*v1.Node{makeNode("machine1", 10000, 20000, nil), makeNode("machine2", 10000, 20000, nil)}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 70}, {Name: "machine2", Score: 82}}, + pod: st.MakePod().Obj(), + nodes: []*v1.Node{makeNode("node1", 10000, 20000, nil), makeNode("node2", 10000, 20000, nil)}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 70}, {Name: "node2", Score: 82}}, name: "no resources requested, pods scheduled with resources", pods: []*v1.Pod{ {Spec: cpuOnly, ObjectMeta: metav1.ObjectMeta{Labels: labels2}}, @@ -250,8 +235,8 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) { // Node2 std: (0.6 - 0.5) / 2 = 0.05 // Node2 Score: (1 - 0.05)*MaxNodeScore = 95 pod: &v1.Pod{Spec: cpuAndMemory}, - nodes: []*v1.Node{makeNode("machine1", 10000, 20000, nil), makeNode("machine2", 10000, 20000, nil)}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 82}, {Name: "machine2", Score: 95}}, + nodes: []*v1.Node{makeNode("node1", 10000, 20000, nil), makeNode("node2", 10000, 20000, nil)}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 82}, {Name: "node2", Score: 95}}, name: "resources requested, pods scheduled with resources", pods: []*v1.Pod{ {Spec: cpuOnly}, @@ -271,9 +256,9 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) { // Node2 std: (0.6 - 0.2) / 2 = 0.2 // Node2 Score: (1 - 0.2)*MaxNodeScore = 80 pod: &v1.Pod{Spec: cpuAndMemory}, - nodes: []*v1.Node{makeNode("machine1", 10000, 20000, nil), makeNode("machine2", 10000, 50000, nil)}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 82}, {Name: "machine2", Score: 80}}, - name: "resources requested, pods scheduled with resources, differently sized machines", + nodes: []*v1.Node{makeNode("node1", 10000, 20000, nil), makeNode("node2", 10000, 50000, nil)}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 82}, {Name: "node2", Score: 80}}, + name: "resources requested, pods scheduled with resources, differently sized nodes", pods: []*v1.Pod{ {Spec: cpuOnly}, {Spec: cpuAndMemory}, @@ -293,8 +278,8 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) { // Node2 std: (1 - 0.5) / 2 = 0.25 // Node2 Score: (1 - 0.25)*MaxNodeScore = 75 pod: &v1.Pod{Spec: cpuOnly}, - nodes: []*v1.Node{makeNode("machine1", 6000, 10000, nil), makeNode("machine2", 6000, 10000, nil)}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 50}, {Name: "machine2", Score: 75}}, + nodes: []*v1.Node{makeNode("node1", 6000, 10000, nil), makeNode("node2", 6000, 10000, nil)}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 50}, {Name: "node2", Score: 75}}, name: "requested resources at node capacity", pods: []*v1.Pod{ {Spec: cpuOnly}, @@ -303,9 +288,9 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) { args: config.NodeResourcesBalancedAllocationArgs{Resources: defaultResourceBalancedAllocationSet}, }, { - pod: &v1.Pod{Spec: noResources}, - nodes: []*v1.Node{makeNode("machine1", 0, 0, nil), makeNode("machine2", 0, 0, nil)}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 100}, {Name: "machine2", Score: 100}}, + pod: st.MakePod().Obj(), + nodes: []*v1.Node{makeNode("node1", 0, 0, nil), makeNode("node2", 0, 0, nil)}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 100}, {Name: "node2", Score: 100}}, name: "zero node resources, pods scheduled with resources", pods: []*v1.Pod{ {Spec: cpuOnly}, @@ -326,22 +311,12 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) { // Node2 std: sqrt(((0.8571 - 0.378) * (0.8571 - 0.378) + (0.378 - 0.125) * (0.378 - 0.125)) + (0.378 - 0.125) * (0.378 - 0.125)) / 3) = 0.345 // Node2 Score: (1 - 0.358)*MaxNodeScore = 65 { - pod: &v1.Pod{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - { - Resources: v1.ResourceRequirements{ - Requests: v1.ResourceList{ - v1.ResourceMemory: resource.MustParse("0"), - "nvidia.com/gpu": resource.MustParse("1"), - }, - }, - }, - }, - }, - }, - nodes: []*v1.Node{makeNode("machine1", 3500, 40000, scalarResource), makeNode("machine2", 3500, 40000, scalarResource)}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 70}, {Name: "machine2", Score: 65}}, + pod: st.MakePod().Req(map[v1.ResourceName]string{ + v1.ResourceMemory: "0", + "nvidia.com/gpu": "1", + }).Obj(), + nodes: []*v1.Node{makeNode("node1", 3500, 40000, scalarResource), makeNode("node2", 3500, 40000, scalarResource)}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 70}, {Name: "node2", Score: 65}}, name: "include scalar resource on a node for balanced resource allocation", pods: []*v1.Pod{ {Spec: cpuAndMemory}, @@ -353,13 +328,13 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) { {Name: "nvidia.com/gpu", Weight: 1}, }}, }, - // Only one node (machine1) has the scalar resource, pod doesn't request the scalar resource and the scalar resource should be skipped for consideration. + // Only one node (node1) has the scalar resource, pod doesn't request the scalar resource and the scalar resource should be skipped for consideration. // Node1: std = 0, score = 100 // Node2: std = 0, score = 100 { - pod: &v1.Pod{Spec: v1.PodSpec{Containers: []v1.Container{{}}}}, - nodes: []*v1.Node{makeNode("machine1", 3500, 40000, scalarResource), makeNode("machine2", 3500, 40000, nil)}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 100}, {Name: "machine2", Score: 100}}, + pod: st.MakePod().Obj(), + nodes: []*v1.Node{makeNode("node1", 3500, 40000, scalarResource), makeNode("node2", 3500, 40000, nil)}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 100}, {Name: "node2", Score: 100}}, name: "node without the scalar resource results to a higher score", pods: []*v1.Pod{ {Spec: cpuOnly}, diff --git a/pkg/scheduler/framework/plugins/noderesources/least_allocated_test.go b/pkg/scheduler/framework/plugins/noderesources/least_allocated_test.go index f6d3391d4f7..5f8f3097d50 100644 --- a/pkg/scheduler/framework/plugins/noderesources/least_allocated_test.go +++ b/pkg/scheduler/framework/plugins/noderesources/least_allocated_test.go @@ -81,7 +81,7 @@ func TestLeastAllocatedScoringStrategy(t *testing.T) { // CPU Score: ((6000 - 3000) * MaxNodeScore) / 6000 = 50 // Memory Score: ((10000 - 5000) * MaxNodeScore) / 10000 = 50 // Node2 Score: (50 + 50) / 2 = 50 - name: "nothing scheduled, resources requested, differently sized machines", + name: "nothing scheduled, resources requested, differently sized nodes", requestedPod: st.MakePod(). Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}). Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}). @@ -95,7 +95,7 @@ func TestLeastAllocatedScoringStrategy(t *testing.T) { resources: defaultResources, }, { - name: "Resources not set, nothing scheduled, resources requested, differently sized machines", + name: "Resources not set, nothing scheduled, resources requested, differently sized nodes", requestedPod: st.MakePod(). Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}). Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}). @@ -190,7 +190,7 @@ func TestLeastAllocatedScoringStrategy(t *testing.T) { // CPU Score: ((10000 - 6000) * MaxNodeScore) / 10000 = 40 // Memory Score: ((50000 - 10000) * MaxNodeScore) / 50000 = 80 // Node2 Score: (40 + 80) / 2 = 60 - name: "resources requested, pods scheduled with resources, differently sized machines", + name: "resources requested, pods scheduled with resources, differently sized nodes", requestedPod: st.MakePod(). Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}). Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}). @@ -249,7 +249,7 @@ func TestLeastAllocatedScoringStrategy(t *testing.T) { // CPU Score: ((6000 - 3000) *100) / 6000 = 50 // Memory Score: ((10000 - 5000) *100) / 10000 = 50 // Node2 Score: (50 * 1 + 50 * 2) / (1 + 2) = 50 - name: "nothing scheduled, resources requested with different weight on CPU and memory, differently sized machines", + name: "nothing scheduled, resources requested with different weight on CPU and memory, differently sized nodes", requestedPod: st.MakePod().Node("node1"). Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}). Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}). diff --git a/pkg/scheduler/framework/plugins/noderesources/most_allocated_test.go b/pkg/scheduler/framework/plugins/noderesources/most_allocated_test.go index 5abd80d7211..5226ec15342 100644 --- a/pkg/scheduler/framework/plugins/noderesources/most_allocated_test.go +++ b/pkg/scheduler/framework/plugins/noderesources/most_allocated_test.go @@ -80,7 +80,7 @@ func TestMostAllocatedScoringStrategy(t *testing.T) { // CPU Score: (3000 * MaxNodeScore) / 6000 = 50 // Memory Score: (5000 * MaxNodeScore) / 10000 = 50 // Node2 Score: (50 + 50) / 2 = 50 - name: "nothing scheduled, resources requested, differently sized machines", + name: "nothing scheduled, resources requested, differently sized nodes", requestedPod: st.MakePod(). Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}). Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}). @@ -94,7 +94,7 @@ func TestMostAllocatedScoringStrategy(t *testing.T) { resources: defaultResources, }, { - name: "Resources not set, nothing scheduled, resources requested, differently sized machines", + name: "Resources not set, nothing scheduled, resources requested, differently sized nodes", requestedPod: st.MakePod(). Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}). Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}). @@ -185,7 +185,7 @@ func TestMostAllocatedScoringStrategy(t *testing.T) { // CPU Score: (3000 *100) / 6000 = 50 // Memory Score: (5000 *100) / 10000 = 50 // Node2 Score: (50 * 1 + 50 * 2) / (1 + 2) = 50 - name: "nothing scheduled, resources requested, differently sized machines", + name: "nothing scheduled, resources requested, differently sized nodes", requestedPod: st.MakePod(). Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}). Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}). diff --git a/pkg/scheduler/framework/plugins/noderesources/requested_to_capacity_ratio_test.go b/pkg/scheduler/framework/plugins/noderesources/requested_to_capacity_ratio_test.go index 3b0970891c7..f99c6b7247b 100644 --- a/pkg/scheduler/framework/plugins/noderesources/requested_to_capacity_ratio_test.go +++ b/pkg/scheduler/framework/plugins/noderesources/requested_to_capacity_ratio_test.go @@ -24,7 +24,6 @@ import ( "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/kubernetes/pkg/scheduler/apis/config" "k8s.io/kubernetes/pkg/scheduler/framework" @@ -73,7 +72,7 @@ func TestRequestedToCapacityRatioScoringStrategy(t *testing.T) { shape: shape, }, { - name: "nothing scheduled, resources requested, differently sized machines (default - least requested nodes have priority)", + name: "nothing scheduled, resources requested, differently sized nodes (default - least requested nodes have priority)", requestedPod: st.MakePod(). Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}). Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}). @@ -213,38 +212,19 @@ func TestBrokenLinearFunction(t *testing.T) { } func TestResourceBinPackingSingleExtended(t *testing.T) { - extendedResource := "intel.com/foo" extendedResource1 := map[string]int64{ "intel.com/foo": 4, } extendedResource2 := map[string]int64{ "intel.com/foo": 8, } + extendedResource3 := map[v1.ResourceName]string{ + "intel.com/foo": "2", + } + extendedResource4 := map[v1.ResourceName]string{ + "intel.com/foo": "4", + } - extendedResourcePod1 := v1.PodSpec{ - Containers: []v1.Container{ - { - Resources: v1.ResourceRequirements{ - Requests: v1.ResourceList{ - v1.ResourceName(extendedResource): resource.MustParse("2"), - }, - }, - }, - }, - } - extendedResourcePod2 := v1.PodSpec{ - Containers: []v1.Container{ - { - Resources: v1.ResourceRequirements{ - Requests: v1.ResourceList{ - v1.ResourceName(extendedResource): resource.MustParse("4"), - }, - }, - }, - }, - } - machine2Pod := extendedResourcePod1 - machine2Pod.NodeName = "machine2" tests := []struct { pod *v1.Pod pods []*v1.Pod @@ -255,8 +235,8 @@ func TestResourceBinPackingSingleExtended(t *testing.T) { { // Node1 Score = Node2 Score = 0 as the incoming Pod doesn't request extended resource. pod: st.MakePod().Obj(), - nodes: []*v1.Node{makeNode("machine1", 4000, 10000*1024*1024, extendedResource2), makeNode("machine2", 4000, 10000*1024*1024, extendedResource1)}, - expectedScores: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}}, + nodes: []*v1.Node{makeNode("node1", 4000, 10000*1024*1024, extendedResource2), makeNode("node2", 4000, 10000*1024*1024, extendedResource1)}, + expectedScores: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}}, name: "nothing scheduled, nothing requested", }, { @@ -271,13 +251,11 @@ func TestResourceBinPackingSingleExtended(t *testing.T) { // resourceScoringFunction((0+2),4) // = 2/4 * maxUtilization = 50 = rawScoringFunction(50) // Node2 Score: 5 - pod: &v1.Pod{Spec: extendedResourcePod1}, - nodes: []*v1.Node{makeNode("machine1", 4000, 10000*1024*1024, extendedResource2), makeNode("machine2", 4000, 10000*1024*1024, extendedResource1)}, - expectedScores: []framework.NodeScore{{Name: "machine1", Score: 2}, {Name: "machine2", Score: 5}}, + pod: st.MakePod().Req(extendedResource3).Obj(), + nodes: []*v1.Node{makeNode("node1", 4000, 10000*1024*1024, extendedResource2), makeNode("node2", 4000, 10000*1024*1024, extendedResource1)}, + expectedScores: []framework.NodeScore{{Name: "node1", Score: 2}, {Name: "node2", Score: 5}}, name: "resources requested, pods scheduled with less resources", - pods: []*v1.Pod{ - st.MakePod().Obj(), - }, + pods: []*v1.Pod{st.MakePod().Obj()}, }, { // Node1 scores (used resources) on 0-MaxNodeScore scale @@ -291,13 +269,11 @@ func TestResourceBinPackingSingleExtended(t *testing.T) { // resourceScoringFunction((2+2),4) // = 4/4 * maxUtilization = maxUtilization = rawScoringFunction(maxUtilization) // Node2 Score: 10 - pod: &v1.Pod{Spec: extendedResourcePod1}, - nodes: []*v1.Node{makeNode("machine1", 4000, 10000*1024*1024, extendedResource2), makeNode("machine2", 4000, 10000*1024*1024, extendedResource1)}, - expectedScores: []framework.NodeScore{{Name: "machine1", Score: 2}, {Name: "machine2", Score: 10}}, + pod: st.MakePod().Req(extendedResource3).Obj(), + nodes: []*v1.Node{makeNode("node1", 4000, 10000*1024*1024, extendedResource2), makeNode("node2", 4000, 10000*1024*1024, extendedResource1)}, + expectedScores: []framework.NodeScore{{Name: "node1", Score: 2}, {Name: "node2", Score: 10}}, name: "resources requested, pods scheduled with resources, on node with existing pod running ", - pods: []*v1.Pod{ - {Spec: machine2Pod}, - }, + pods: []*v1.Pod{st.MakePod().Req(extendedResource3).Node("node2").Obj()}, }, { // Node1 scores (used resources) on 0-MaxNodeScore scale @@ -311,9 +287,9 @@ func TestResourceBinPackingSingleExtended(t *testing.T) { // resourceScoringFunction((0+4),4) // = 4/4 * maxUtilization = maxUtilization = rawScoringFunction(maxUtilization) // Node2 Score: 10 - pod: &v1.Pod{Spec: extendedResourcePod2}, - nodes: []*v1.Node{makeNode("machine1", 4000, 10000*1024*1024, extendedResource2), makeNode("machine2", 4000, 10000*1024*1024, extendedResource1)}, - expectedScores: []framework.NodeScore{{Name: "machine1", Score: 5}, {Name: "machine2", Score: 10}}, + pod: st.MakePod().Req(extendedResource4).Obj(), + nodes: []*v1.Node{makeNode("node1", 4000, 10000*1024*1024, extendedResource2), makeNode("node2", 4000, 10000*1024*1024, extendedResource1)}, + expectedScores: []framework.NodeScore{{Name: "node1", Score: 5}, {Name: "node2", Score: 10}}, name: "resources requested, pods scheduled with more resources", pods: []*v1.Pod{ st.MakePod().Obj(), @@ -362,44 +338,24 @@ func TestResourceBinPackingSingleExtended(t *testing.T) { } func TestResourceBinPackingMultipleExtended(t *testing.T) { - extendedResource1 := "intel.com/foo" - extendedResource2 := "intel.com/bar" extendedResources1 := map[string]int64{ "intel.com/foo": 4, "intel.com/bar": 8, } - extendedResources2 := map[string]int64{ "intel.com/foo": 8, "intel.com/bar": 4, } - extnededResourcePod1 := v1.PodSpec{ - Containers: []v1.Container{ - { - Resources: v1.ResourceRequirements{ - Requests: v1.ResourceList{ - v1.ResourceName(extendedResource1): resource.MustParse("2"), - v1.ResourceName(extendedResource2): resource.MustParse("2"), - }, - }, - }, - }, + extendedResourcePod1 := map[v1.ResourceName]string{ + "intel.com/foo": "2", + "intel.com/bar": "2", } - extnededResourcePod2 := v1.PodSpec{ - Containers: []v1.Container{ - { - Resources: v1.ResourceRequirements{ - Requests: v1.ResourceList{ - v1.ResourceName(extendedResource1): resource.MustParse("4"), - v1.ResourceName(extendedResource2): resource.MustParse("2"), - }, - }, - }, - }, + extendedResourcePod2 := map[v1.ResourceName]string{ + "intel.com/foo": "4", + "intel.com/bar": "2", } - machine2Pod := extnededResourcePod1 - machine2Pod.NodeName = "machine2" + tests := []struct { pod *v1.Pod pods []*v1.Pod @@ -436,11 +392,10 @@ func TestResourceBinPackingMultipleExtended(t *testing.T) { // Node2 Score: (0 * 3) + (0 * 5) / 8 = 0 pod: st.MakePod().Obj(), - nodes: []*v1.Node{makeNode("machine1", 4000, 10000*1024*1024, extendedResources2), makeNode("machine2", 4000, 10000*1024*1024, extendedResources1)}, - expectedScores: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}}, + nodes: []*v1.Node{makeNode("node1", 4000, 10000*1024*1024, extendedResources2), makeNode("node2", 4000, 10000*1024*1024, extendedResources1)}, + expectedScores: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}}, name: "nothing scheduled, nothing requested", }, - { // resources["intel.com/foo"] = 3 @@ -469,15 +424,14 @@ func TestResourceBinPackingMultipleExtended(t *testing.T) { // = 2/8 * 100 = 25 = rawScoringFunction(25) // Node2 Score: (5 * 3) + (2 * 5) / 8 = 3 - pod: &v1.Pod{Spec: extnededResourcePod1}, - nodes: []*v1.Node{makeNode("machine1", 4000, 10000*1024*1024, extendedResources2), makeNode("machine2", 4000, 10000*1024*1024, extendedResources1)}, - expectedScores: []framework.NodeScore{{Name: "machine1", Score: 4}, {Name: "machine2", Score: 3}}, + pod: st.MakePod().Req(extendedResourcePod1).Obj(), + nodes: []*v1.Node{makeNode("node1", 4000, 10000*1024*1024, extendedResources2), makeNode("node2", 4000, 10000*1024*1024, extendedResources1)}, + expectedScores: []framework.NodeScore{{Name: "node1", Score: 4}, {Name: "node2", Score: 3}}, name: "resources requested, pods scheduled with less resources", pods: []*v1.Pod{ st.MakePod().Obj(), }, }, - { // resources["intel.com/foo"] = 3 @@ -505,15 +459,12 @@ func TestResourceBinPackingMultipleExtended(t *testing.T) { // = 4/8 *100 = 50 = rawScoringFunction(50) // Node2 Score: (10 * 3) + (5 * 5) / 8 = 7 - pod: &v1.Pod{Spec: extnededResourcePod1}, - nodes: []*v1.Node{makeNode("machine1", 4000, 10000*1024*1024, extendedResources2), makeNode("machine2", 4000, 10000*1024*1024, extendedResources1)}, - expectedScores: []framework.NodeScore{{Name: "machine1", Score: 4}, {Name: "machine2", Score: 7}}, + pod: st.MakePod().Req(extendedResourcePod1).Obj(), + nodes: []*v1.Node{makeNode("node1", 4000, 10000*1024*1024, extendedResources2), makeNode("node2", 4000, 10000*1024*1024, extendedResources1)}, + expectedScores: []framework.NodeScore{{Name: "node1", Score: 4}, {Name: "node2", Score: 7}}, name: "resources requested, pods scheduled with resources, on node with existing pod running ", - pods: []*v1.Pod{ - {Spec: machine2Pod}, - }, + pods: []*v1.Pod{st.MakePod().Req(extendedResourcePod2).Node("node2").Obj()}, }, - { // resources["intel.com/foo"] = 3 @@ -556,9 +507,9 @@ func TestResourceBinPackingMultipleExtended(t *testing.T) { // = 2/8 * 100 = 25 = rawScoringFunction(25) // Node2 Score: (10 * 3) + (2 * 5) / 8 = 5 - pod: &v1.Pod{Spec: extnededResourcePod2}, - nodes: []*v1.Node{makeNode("machine1", 4000, 10000*1024*1024, extendedResources2), makeNode("machine2", 4000, 10000*1024*1024, extendedResources1)}, - expectedScores: []framework.NodeScore{{Name: "machine1", Score: 5}, {Name: "machine2", Score: 5}}, + pod: st.MakePod().Req(extendedResourcePod2).Obj(), + nodes: []*v1.Node{makeNode("node1", 4000, 10000*1024*1024, extendedResources2), makeNode("node2", 4000, 10000*1024*1024, extendedResources1)}, + expectedScores: []framework.NodeScore{{Name: "node1", Score: 5}, {Name: "node2", Score: 5}}, name: "resources requested, pods scheduled with more resources", pods: []*v1.Pod{ st.MakePod().Obj(), diff --git a/pkg/scheduler/framework/plugins/nodevolumelimits/csi_test.go b/pkg/scheduler/framework/plugins/nodevolumelimits/csi_test.go index 0b68239c4cf..331d920b0df 100644 --- a/pkg/scheduler/framework/plugins/nodevolumelimits/csi_test.go +++ b/pkg/scheduler/framework/plugins/nodevolumelimits/csi_test.go @@ -36,6 +36,7 @@ import ( "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/scheduler/framework" fakeframework "k8s.io/kubernetes/pkg/scheduler/framework/fake" + st "k8s.io/kubernetes/pkg/scheduler/testing" volumeutil "k8s.io/kubernetes/pkg/volume/util" utilpointer "k8s.io/utils/pointer" ) @@ -68,195 +69,35 @@ func getVolumeLimitKey(filterType string) v1.ResourceName { } func TestCSILimits(t *testing.T) { - runningPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "csi-ebs.csi.aws.com-3", - }, - }, - }, - }, - }, - } - - pendingVolumePod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "csi-4", - }, - }, - }, - }, - }, - } + runningPod := st.MakePod().PVC("csi-ebs.csi.aws.com-3").Obj() + pendingVolumePod := st.MakePod().PVC("csi-4").Obj() // Different pod than pendingVolumePod, but using the same unbound PVC - unboundPVCPod2 := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "csi-4", - }, - }, - }, - }, - }, - } + unboundPVCPod2 := st.MakePod().PVC("csi-4").Obj() - missingPVPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "csi-6", - }, - }, - }, - }, - }, - } + missingPVPod := st.MakePod().PVC("csi-6").Obj() + noSCPVCPod := st.MakePod().PVC("csi-5").Obj() + + gceTwoVolPod := st.MakePod().PVC("csi-pd.csi.storage.gke.io-1").PVC("csi-pd.csi.storage.gke.io-2").Obj() - noSCPVCPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "csi-5", - }, - }, - }, - }, - }, - } - gceTwoVolPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "csi-pd.csi.storage.gke.io-1", - }, - }, - }, - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "csi-pd.csi.storage.gke.io-2", - }, - }, - }, - }, - }, - } // In-tree volumes - inTreeOneVolPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "csi-kubernetes.io/aws-ebs-0", - }, - }, - }, - }, - }, - } - inTreeTwoVolPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "csi-kubernetes.io/aws-ebs-1", - }, - }, - }, - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "csi-kubernetes.io/aws-ebs-2", - }, - }, - }, - }, - }, - } - // pods with matching csi driver names - csiEBSOneVolPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "csi-ebs.csi.aws.com-0", - }, - }, - }, - }, - }, - } - csiEBSTwoVolPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "csi-ebs.csi.aws.com-1", - }, - }, - }, - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "csi-ebs.csi.aws.com-2", - }, - }, - }, - }, - }, - } - inTreeNonMigratableOneVolPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "csi-kubernetes.io/hostpath-0", - }, - }, - }, - }, - }, - } + inTreeOneVolPod := st.MakePod().PVC("csi-kubernetes.io/aws-ebs-0").Obj() + inTreeTwoVolPod := st.MakePod().PVC("csi-kubernetes.io/aws-ebs-1").PVC("csi-kubernetes.io/aws-ebs-2").Obj() - ephemeralVolumePod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "test", - Name: "abc", - UID: "12345", - }, - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - Name: "xyz", - VolumeSource: v1.VolumeSource{ - Ephemeral: &v1.EphemeralVolumeSource{}, - }, - }, + // pods with matching csi driver names + csiEBSOneVolPod := st.MakePod().PVC("csi-ebs.csi.aws.com-0").Obj() + csiEBSTwoVolPod := st.MakePod().PVC("csi-ebs.csi.aws.com-1").PVC("csi-ebs.csi.aws.com-2").Obj() + + inTreeNonMigratableOneVolPod := st.MakePod().PVC("csi-kubernetes.io/hostpath-0").Obj() + + ephemeralVolumePod := st.MakePod().Name("abc").Namespace("test").UID("12345").Volume( + v1.Volume{ + Name: "xyz", + VolumeSource: v1.VolumeSource{ + Ephemeral: &v1.EphemeralVolumeSource{}, }, - }, - } + }).Obj() + controller := true ephemeralClaim := &v1.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{ @@ -278,29 +119,18 @@ func TestCSILimits(t *testing.T) { conflictingClaim := ephemeralClaim.DeepCopy() conflictingClaim.OwnerReferences = nil - ephemeralTwoVolumePod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "test", - Name: "abc", - UID: "12345II", + ephemeralTwoVolumePod := st.MakePod().Name("abc").Namespace("test").UID("12345II").Volume(v1.Volume{ + Name: "x", + VolumeSource: v1.VolumeSource{ + Ephemeral: &v1.EphemeralVolumeSource{}, }, - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - Name: "x", - VolumeSource: v1.VolumeSource{ - Ephemeral: &v1.EphemeralVolumeSource{}, - }, - }, - { - Name: "y", - VolumeSource: v1.VolumeSource{ - Ephemeral: &v1.EphemeralVolumeSource{}, - }, - }, - }, + }).Volume(v1.Volume{ + Name: "y", + VolumeSource: v1.VolumeSource{ + Ephemeral: &v1.EphemeralVolumeSource{}, }, - } + }).Obj() + ephemeralClaimX := &v1.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{ Namespace: ephemeralTwoVolumePod.Namespace, diff --git a/pkg/scheduler/framework/plugins/nodevolumelimits/non_csi_test.go b/pkg/scheduler/framework/plugins/nodevolumelimits/non_csi_test.go index ebf2a504ab2..922abd071db 100644 --- a/pkg/scheduler/framework/plugins/nodevolumelimits/non_csi_test.go +++ b/pkg/scheduler/framework/plugins/nodevolumelimits/non_csi_test.go @@ -18,6 +18,7 @@ package nodevolumelimits import ( "context" + "fmt" "os" "reflect" "strings" @@ -29,32 +30,67 @@ import ( "k8s.io/kubernetes/pkg/scheduler/framework" fakeframework "k8s.io/kubernetes/pkg/scheduler/framework/fake" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" + st "k8s.io/kubernetes/pkg/scheduler/testing" utilpointer "k8s.io/utils/pointer" ) +var ( + oneVolPod = st.MakePod().Volume(v1.Volume{ + VolumeSource: v1.VolumeSource{ + AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{VolumeID: "ovp"}, + }, + }).Obj() + twoVolPod = st.MakePod().Volume(v1.Volume{ + VolumeSource: v1.VolumeSource{ + AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{VolumeID: "tvp1"}, + }, + }).Volume(v1.Volume{ + VolumeSource: v1.VolumeSource{ + AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{VolumeID: "tvp2"}, + }, + }).Obj() + splitVolsPod = st.MakePod().Volume(v1.Volume{ + VolumeSource: v1.VolumeSource{ + HostPath: &v1.HostPathVolumeSource{}, + }, + }).Volume(v1.Volume{ + VolumeSource: v1.VolumeSource{ + AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{VolumeID: "svp"}, + }, + }).Obj() + nonApplicablePod = st.MakePod().Volume(v1.Volume{ + VolumeSource: v1.VolumeSource{ + HostPath: &v1.HostPathVolumeSource{}, + }, + }).Obj() + + deletedPVCPod = st.MakePod().PVC("deletedPVC").Obj() + twoDeletedPVCPod = st.MakePod().PVC("deletedPVC").PVC("anotherDeletedPVC").Obj() + deletedPVPod = st.MakePod().PVC("pvcWithDeletedPV").Obj() + // deletedPVPod2 is a different pod than deletedPVPod but using the same PVC + deletedPVPod2 = st.MakePod().PVC("pvcWithDeletedPV").Obj() + anotherDeletedPVPod = st.MakePod().PVC("anotherPVCWithDeletedPV").Obj() + emptyPod = st.MakePod().Obj() + unboundPVCPod = st.MakePod().PVC("unboundPVC").Obj() + // Different pod than unboundPVCPod, but using the same unbound PVC + unboundPVCPod2 = st.MakePod().PVC("unboundPVC").Obj() + // pod with unbound PVC that's different to unboundPVC + anotherUnboundPVCPod = st.MakePod().PVC("anotherUnboundPVC").Obj() +) + func TestEphemeralLimits(t *testing.T) { // We have to specify a valid filter and arbitrarily pick Cinder here. // It doesn't matter for the test cases. filterName := gcePDVolumeFilterType driverName := csilibplugins.GCEPDInTreePluginName - ephemeralVolumePod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "test", - Name: "abc", - UID: "12345", + ephemeralVolumePod := st.MakePod().Name("abc").Namespace("test").UID("12345").Volume(v1.Volume{ + Name: "xyz", + VolumeSource: v1.VolumeSource{ + Ephemeral: &v1.EphemeralVolumeSource{}, }, - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - Name: "xyz", - VolumeSource: v1.VolumeSource{ - Ephemeral: &v1.EphemeralVolumeSource{}, - }, - }, - }, - }, - } + }).Obj() + controller := true ephemeralClaim := &v1.PersistentVolumeClaim{ ObjectMeta: metav1.ObjectMeta{ @@ -130,180 +166,6 @@ func TestEphemeralLimits(t *testing.T) { } func TestAzureDiskLimits(t *testing.T) { - oneVolPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{VolumeID: "ovp"}, - }, - }, - }, - }, - } - twoVolPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{VolumeID: "tvp1"}, - }, - }, - { - VolumeSource: v1.VolumeSource{ - AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{VolumeID: "tvp2"}, - }, - }, - }, - }, - } - splitVolsPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - HostPath: &v1.HostPathVolumeSource{}, - }, - }, - { - VolumeSource: v1.VolumeSource{ - AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{VolumeID: "svp"}, - }, - }, - }, - }, - } - nonApplicablePod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - HostPath: &v1.HostPathVolumeSource{}, - }, - }, - }, - }, - } - deletedPVCPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "deletedPVC", - }, - }, - }, - }, - }, - } - twoDeletedPVCPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "deletedPVC", - }, - }, - }, - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "anotherDeletedPVC", - }, - }, - }, - }, - }, - } - deletedPVPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "pvcWithDeletedPV", - }, - }, - }, - }, - }, - } - // deletedPVPod2 is a different pod than deletedPVPod but using the same PVC - deletedPVPod2 := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "pvcWithDeletedPV", - }, - }, - }, - }, - }, - } - // anotherDeletedPVPod is a different pod than deletedPVPod and uses another PVC - anotherDeletedPVPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "anotherPVCWithDeletedPV", - }, - }, - }, - }, - }, - } - emptyPod := &v1.Pod{ - Spec: v1.PodSpec{}, - } - unboundPVCPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "unboundPVC", - }, - }, - }, - }, - }, - } - // Different pod than unboundPVCPod, but using the same unbound PVC - unboundPVCPod2 := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "unboundPVC", - }, - }, - }, - }, - }, - } - - // pod with unbound PVC that's different to unboundPVC - anotherUnboundPVCPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "anotherUnboundPVC", - }, - }, - }, - }, - }, - } - tests := []struct { newPod *v1.Pod existingPods []*v1.Pod @@ -468,205 +330,8 @@ func TestAzureDiskLimits(t *testing.T) { } func TestEBSLimits(t *testing.T) { - oneVolPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{VolumeID: "ovp"}, - }, - }, - }, - }, - } - twoVolPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{VolumeID: "tvp1"}, - }, - }, - { - VolumeSource: v1.VolumeSource{ - AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{VolumeID: "tvp2"}, - }, - }, - }, - }, - } - unboundPVCwithInvalidSCPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "unboundPVCwithInvalidSCPod", - }, - }, - }, - }, - }, - } - unboundPVCwithDefaultSCPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "unboundPVCwithDefaultSCPod", - }, - }, - }, - }, - }, - } - splitVolsPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - HostPath: &v1.HostPathVolumeSource{}, - }, - }, - { - VolumeSource: v1.VolumeSource{ - AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{VolumeID: "svp"}, - }, - }, - }, - }, - } - nonApplicablePod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - HostPath: &v1.HostPathVolumeSource{}, - }, - }, - }, - }, - } - deletedPVCPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "deletedPVC", - }, - }, - }, - }, - }, - } - twoDeletedPVCPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "deletedPVC", - }, - }, - }, - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "anotherDeletedPVC", - }, - }, - }, - }, - }, - } - deletedPVPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "pvcWithDeletedPV", - }, - }, - }, - }, - }, - } - // deletedPVPod2 is a different pod than deletedPVPod but using the same PVC - deletedPVPod2 := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "pvcWithDeletedPV", - }, - }, - }, - }, - }, - } - // anotherDeletedPVPod is a different pod than deletedPVPod and uses another PVC - anotherDeletedPVPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "anotherPVCWithDeletedPV", - }, - }, - }, - }, - }, - } - emptyPod := &v1.Pod{ - Spec: v1.PodSpec{}, - } - unboundPVCPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "unboundPVC", - }, - }, - }, - }, - }, - } - // Different pod than unboundPVCPod, but using the same unbound PVC - unboundPVCPod2 := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "unboundPVC", - }, - }, - }, - }, - }, - } - - // pod with unbound PVC that's different to unboundPVC - anotherUnboundPVCPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "anotherUnboundPVC", - }, - }, - }, - }, - }, - } + unboundPVCWithInvalidSCPod := st.MakePod().PVC("unboundPVCWithInvalidSCPod").Obj() + unboundPVCWithDefaultSCPod := st.MakePod().PVC("unboundPVCWithDefaultSCPod").Obj() tests := []struct { newPod *v1.Pod @@ -777,7 +442,7 @@ func TestEBSLimits(t *testing.T) { test: "two missing PVCs are not counted towards the PV limit twice", }, { - newPod: unboundPVCwithInvalidSCPod, + newPod: unboundPVCWithInvalidSCPod, existingPods: []*v1.Pod{oneVolPod}, filterName: ebsVolumeFilterType, driverName: csilibplugins.AWSEBSInTreePluginName, @@ -785,14 +450,13 @@ func TestEBSLimits(t *testing.T) { test: "unbound PVC with invalid SC is not counted towards the PV limit", }, { - newPod: unboundPVCwithDefaultSCPod, + newPod: unboundPVCWithDefaultSCPod, existingPods: []*v1.Pod{oneVolPod}, filterName: ebsVolumeFilterType, driverName: csilibplugins.AWSEBSInTreePluginName, maxVols: 1, test: "unbound PVC from different provisioner is not counted towards the PV limit", }, - { newPod: onePVCPod(ebsVolumeFilterType), existingPods: []*v1.Pod{oneVolPod, deletedPVPod}, @@ -876,180 +540,6 @@ func TestEBSLimits(t *testing.T) { } func TestGCEPDLimits(t *testing.T) { - oneVolPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{VolumeID: "ovp"}, - }, - }, - }, - }, - } - twoVolPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{VolumeID: "tvp1"}, - }, - }, - { - VolumeSource: v1.VolumeSource{ - AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{VolumeID: "tvp2"}, - }, - }, - }, - }, - } - splitVolsPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - HostPath: &v1.HostPathVolumeSource{}, - }, - }, - { - VolumeSource: v1.VolumeSource{ - AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{VolumeID: "svp"}, - }, - }, - }, - }, - } - nonApplicablePod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - HostPath: &v1.HostPathVolumeSource{}, - }, - }, - }, - }, - } - deletedPVCPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "deletedPVC", - }, - }, - }, - }, - }, - } - twoDeletedPVCPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "deletedPVC", - }, - }, - }, - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "anotherDeletedPVC", - }, - }, - }, - }, - }, - } - deletedPVPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "pvcWithDeletedPV", - }, - }, - }, - }, - }, - } - // deletedPVPod2 is a different pod than deletedPVPod but using the same PVC - deletedPVPod2 := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "pvcWithDeletedPV", - }, - }, - }, - }, - }, - } - // anotherDeletedPVPod is a different pod than deletedPVPod and uses another PVC - anotherDeletedPVPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "anotherPVCWithDeletedPV", - }, - }, - }, - }, - }, - } - emptyPod := &v1.Pod{ - Spec: v1.PodSpec{}, - } - unboundPVCPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "unboundPVC", - }, - }, - }, - }, - }, - } - // Different pod than unboundPVCPod, but using the same unbound PVC - unboundPVCPod2 := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "unboundPVC", - }, - }, - }, - }, - }, - } - - // pod with unbound PVC that's different to unboundPVC - anotherUnboundPVCPod := &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "anotherUnboundPVC", - }, - }, - }, - }, - }, - } - tests := []struct { newPod *v1.Pod existingPods []*v1.Pod @@ -1299,14 +789,14 @@ func getFakePVCLister(filterName string) fakeframework.PersistentVolumeClaimList }, }, { - ObjectMeta: metav1.ObjectMeta{Name: "unboundPVCwithDefaultSCPod"}, + ObjectMeta: metav1.ObjectMeta{Name: "unboundPVCWithDefaultSCPod"}, Spec: v1.PersistentVolumeClaimSpec{ VolumeName: "", StorageClassName: utilpointer.StringPtr("standard-sc"), }, }, { - ObjectMeta: metav1.ObjectMeta{Name: "unboundPVCwithInvalidSCPod"}, + ObjectMeta: metav1.ObjectMeta{Name: "unboundPVCWithInvalidSCPod"}, Spec: v1.PersistentVolumeClaimSpec{ VolumeName: "", StorageClassName: utilpointer.StringPtr("invalid-sc"), @@ -1335,40 +825,9 @@ func getFakePVLister(filterName string) fakeframework.PersistentVolumeLister { } func onePVCPod(filterName string) *v1.Pod { - return &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "some" + filterName + "Vol", - }, - }, - }, - }, - }, - } + return st.MakePod().PVC(fmt.Sprintf("some%sVol", filterName)).Obj() } func splitPVCPod(filterName string) *v1.Pod { - return &v1.Pod{ - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "someNon" + filterName + "Vol", - }, - }, - }, - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "some" + filterName + "Vol", - }, - }, - }, - }, - }, - } + return st.MakePod().PVC(fmt.Sprintf("someNon%sVol", filterName)).PVC(fmt.Sprintf("some%sVol", filterName)).Obj() } diff --git a/pkg/scheduler/framework/plugins/queuesort/priority_sort_test.go b/pkg/scheduler/framework/plugins/queuesort/priority_sort_test.go index 5982422e5ef..edaf7bc92e5 100644 --- a/pkg/scheduler/framework/plugins/queuesort/priority_sort_test.go +++ b/pkg/scheduler/framework/plugins/queuesort/priority_sort_test.go @@ -17,10 +17,11 @@ limitations under the License. package queuesort import ( - v1 "k8s.io/api/core/v1" - "k8s.io/kubernetes/pkg/scheduler/framework" "testing" "time" + + "k8s.io/kubernetes/pkg/scheduler/framework" + st "k8s.io/kubernetes/pkg/scheduler/testing" ) func TestLess(t *testing.T) { @@ -37,55 +38,31 @@ func TestLess(t *testing.T) { { name: "p1.priority less than p2.priority", p1: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(&v1.Pod{ - Spec: v1.PodSpec{ - Priority: &lowPriority, - }, - }), + PodInfo: framework.NewPodInfo(st.MakePod().Priority(lowPriority).Obj()), }, p2: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(&v1.Pod{ - Spec: v1.PodSpec{ - Priority: &highPriority, - }, - }), + PodInfo: framework.NewPodInfo(st.MakePod().Priority(highPriority).Obj()), }, expected: false, // p2 should be ahead of p1 in the queue }, { name: "p1.priority greater than p2.priority", p1: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(&v1.Pod{ - Spec: v1.PodSpec{ - Priority: &highPriority, - }, - }), + PodInfo: framework.NewPodInfo(st.MakePod().Priority(highPriority).Obj()), }, p2: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(&v1.Pod{ - Spec: v1.PodSpec{ - Priority: &lowPriority, - }, - }), + PodInfo: framework.NewPodInfo(st.MakePod().Priority(lowPriority).Obj()), }, expected: true, // p1 should be ahead of p2 in the queue }, { name: "equal priority. p1 is added to schedulingQ earlier than p2", p1: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(&v1.Pod{ - Spec: v1.PodSpec{ - Priority: &highPriority, - }, - }), + PodInfo: framework.NewPodInfo(st.MakePod().Priority(highPriority).Obj()), Timestamp: t1, }, p2: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(&v1.Pod{ - Spec: v1.PodSpec{ - Priority: &highPriority, - }, - }), + PodInfo: framework.NewPodInfo(st.MakePod().Priority(highPriority).Obj()), Timestamp: t2, }, expected: true, // p1 should be ahead of p2 in the queue @@ -93,19 +70,11 @@ func TestLess(t *testing.T) { { name: "equal priority. p2 is added to schedulingQ earlier than p1", p1: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(&v1.Pod{ - Spec: v1.PodSpec{ - Priority: &highPriority, - }, - }), + PodInfo: framework.NewPodInfo(st.MakePod().Priority(highPriority).Obj()), Timestamp: t2, }, p2: &framework.QueuedPodInfo{ - PodInfo: framework.NewPodInfo(&v1.Pod{ - Spec: v1.PodSpec{ - Priority: &highPriority, - }, - }), + PodInfo: framework.NewPodInfo(st.MakePod().Priority(highPriority).Obj()), Timestamp: t1, }, expected: false, // p2 should be ahead of p1 in the queue diff --git a/pkg/scheduler/framework/plugins/selectorspread/selector_spread_test.go b/pkg/scheduler/framework/plugins/selectorspread/selector_spread_test.go index d293e0d783d..12d425391bc 100644 --- a/pkg/scheduler/framework/plugins/selectorspread/selector_spread_test.go +++ b/pkg/scheduler/framework/plugins/selectorspread/selector_spread_test.go @@ -33,6 +33,7 @@ import ( "k8s.io/kubernetes/pkg/scheduler/framework" frameworkruntime "k8s.io/kubernetes/pkg/scheduler/framework/runtime" "k8s.io/kubernetes/pkg/scheduler/internal/cache" + st "k8s.io/kubernetes/pkg/scheduler/testing" "k8s.io/utils/pointer" ) @@ -63,10 +64,10 @@ func TestSelectorSpreadScore(t *testing.T) { "baz": "blah", } zone1Spec := v1.PodSpec{ - NodeName: "machine1", + NodeName: "node1", } zone2Spec := v1.PodSpec{ - NodeName: "machine2", + NodeName: "node2", } tests := []struct { pod *v1.Pod @@ -81,122 +82,122 @@ func TestSelectorSpreadScore(t *testing.T) { }{ { pod: new(v1.Pod), - nodes: []string{"machine1", "machine2"}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: framework.MaxNodeScore}}, + nodes: []string{"node1", "node2"}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: framework.MaxNodeScore}}, name: "nothing scheduled", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, - pods: []*v1.Pod{{Spec: zone1Spec}}, - nodes: []string{"machine1", "machine2"}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: framework.MaxNodeScore}}, + pod: st.MakePod().Labels(labels1).Obj(), + pods: []*v1.Pod{st.MakePod().Node("node1").Obj()}, + nodes: []string{"node1", "node2"}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: framework.MaxNodeScore}}, name: "no services", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, - pods: []*v1.Pod{{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}}}, - nodes: []string{"machine1", "machine2"}, + pod: st.MakePod().Labels(labels1).Obj(), + pods: []*v1.Pod{st.MakePod().Labels(labels2).Node("node1").Obj()}, + nodes: []string{"node1", "node2"}, services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "s1"}, Spec: v1.ServiceSpec{Selector: map[string]string{"key": "value"}}}}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: framework.MaxNodeScore}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: framework.MaxNodeScore}}, name: "different services", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, + pod: st.MakePod().Labels(labels1).Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, + st.MakePod().Labels(labels2).Node("node1").Obj(), + st.MakePod().Labels(labels1).Node("node2").Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "s1"}, Spec: v1.ServiceSpec{Selector: labels1}}}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: 0}}, name: "two pods, one service pod", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, + pod: st.MakePod().Labels(labels1).Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1, Namespace: metav1.NamespaceDefault}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1, Namespace: "ns1"}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}}, + st.MakePod().Labels(labels2).Node("node1").Obj(), + st.MakePod().Labels(labels1).Node("node1").Namespace(metav1.NamespaceDefault).Obj(), + st.MakePod().Labels(labels1).Node("node1").Namespace("ns1").Obj(), + st.MakePod().Labels(labels1).Node("node2").Obj(), + st.MakePod().Labels(labels2).Node("node2").Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "s1"}, Spec: v1.ServiceSpec{Selector: labels1}}}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: 0}}, name: "five pods, one service pod in no namespace", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: labels1, Namespace: metav1.NamespaceDefault}}, + pod: st.MakePod().Labels(labels1).Namespace(metav1.NamespaceDefault).Obj(), pods: []*v1.Pod{ {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1, Namespace: "ns1"}}, {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1, Namespace: metav1.NamespaceDefault}}, {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}}, }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "s1"}, Spec: v1.ServiceSpec{Selector: labels1}}}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: 0}}, name: "four pods, one service pod in default namespace", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: labels1, Namespace: "ns1"}}, + pod: st.MakePod().Labels(labels1).Namespace("ns1").Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1, Namespace: metav1.NamespaceDefault}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1, Namespace: "ns2"}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1, Namespace: "ns1"}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}}, + st.MakePod().Labels(labels2).Node("node1").Obj(), + st.MakePod().Labels(labels1).Node("node1").Namespace(metav1.NamespaceDefault).Obj(), + st.MakePod().Labels(labels1).Node("node1").Namespace("ns2").Obj(), + st.MakePod().Labels(labels1).Node("node2").Namespace("ns1").Obj(), + st.MakePod().Labels(labels2).Node("node2").Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, services: []*v1.Service{{Spec: v1.ServiceSpec{Selector: labels1}, ObjectMeta: metav1.ObjectMeta{Namespace: "ns1"}}}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: 0}}, name: "five pods, one service pod in specific namespace", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, + pod: st.MakePod().Labels(labels1).Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, + st.MakePod().Labels(labels2).Node("node1").Obj(), + st.MakePod().Labels(labels1).Node("node1").Obj(), + st.MakePod().Labels(labels1).Node("node2").Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "s1"}, Spec: v1.ServiceSpec{Selector: labels1}}}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}}, - name: "three pods, two service pods on different machines", + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}}, + name: "three pods, two service pods on different nodes", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, + pod: st.MakePod().Labels(labels1).Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, + st.MakePod().Labels(labels2).Node("node1").Obj(), + st.MakePod().Labels(labels1).Node("node1").Obj(), + st.MakePod().Labels(labels1).Node("node2").Obj(), + st.MakePod().Labels(labels1).Node("node2").Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "s1"}, Spec: v1.ServiceSpec{Selector: labels1}}}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 50}, {Name: "machine2", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 50}, {Name: "node2", Score: 0}}, name: "four pods, three service pods", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, + pod: st.MakePod().Labels(labels1).Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}}, + st.MakePod().Labels(labels2).Node("node1").Obj(), + st.MakePod().Labels(labels1).Node("node1").Obj(), + st.MakePod().Labels(labels1).Node("node2").Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "s1"}, Spec: v1.ServiceSpec{Selector: map[string]string{"baz": "blah"}}}}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 50}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 50}}, name: "service with partial pod label matches", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rc1", rcKind)}}, + pod: st.MakePod().Namespace(metav1.NamespaceDefault).Labels(labels1).OwnerReference("rc1", rcKind).Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1}}, + st.MakePod().Node("node1").Namespace(metav1.NamespaceDefault).Labels(labels2).Obj(), + st.MakePod().Node("node1").Namespace(metav1.NamespaceDefault).Labels(labels1).Obj(), + st.MakePod().Node("node2").Namespace(metav1.NamespaceDefault).Labels(labels1).Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, rcs: []*v1.ReplicationController{ {ObjectMeta: metav1.ObjectMeta{Name: "rc1", Namespace: metav1.NamespaceDefault}, Spec: v1.ReplicationControllerSpec{Selector: map[string]string{"foo": "bar"}}}, {ObjectMeta: metav1.ObjectMeta{Name: "rc2", Namespace: metav1.NamespaceDefault}, Spec: v1.ReplicationControllerSpec{Selector: map[string]string{"bar": "foo"}}}, @@ -204,163 +205,162 @@ func TestSelectorSpreadScore(t *testing.T) { services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Name: "s1", Namespace: metav1.NamespaceDefault}, Spec: v1.ServiceSpec{Selector: map[string]string{"baz": "blah"}}}}, // "baz=blah" matches both labels1 and labels2, and "foo=bar" matches only labels 1. This means that we assume that we want to // do spreading pod2 and pod3 and not pod1. - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}}, name: "service with partial pod label matches with service and replication controller", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rs1", rsKind)}}, + pod: st.MakePod().Namespace(metav1.NamespaceDefault).Labels(labels1).OwnerReference("rs1", rsKind).Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1}}, + st.MakePod().Node("node1").Namespace(metav1.NamespaceDefault).Labels(labels2).Obj(), + st.MakePod().Node("node1").Namespace(metav1.NamespaceDefault).Labels(labels1).Obj(), + st.MakePod().Node("node2").Namespace(metav1.NamespaceDefault).Labels(labels1).Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Name: "s1", Namespace: metav1.NamespaceDefault}, Spec: v1.ServiceSpec{Selector: map[string]string{"baz": "blah"}}}}, rss: []*apps.ReplicaSet{ {ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "rs1"}, Spec: apps.ReplicaSetSpec{Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}}}, {ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "rs2"}, Spec: apps.ReplicaSetSpec{Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"bar": "foo"}}}}, }, // We use ReplicaSet, instead of ReplicationController. The result should be exactly as above. - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}}, name: "service with partial pod label matches with service and replica set", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("ss1", ssKind)}}, + pod: st.MakePod().Namespace(metav1.NamespaceDefault).Labels(labels1).OwnerReference("ss1", ssKind).Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1}}, + st.MakePod().Node("node1").Namespace(metav1.NamespaceDefault).Labels(labels2).Obj(), + st.MakePod().Node("node1").Namespace(metav1.NamespaceDefault).Labels(labels1).Obj(), + st.MakePod().Node("node2").Namespace(metav1.NamespaceDefault).Labels(labels1).Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Name: "s1", Namespace: metav1.NamespaceDefault}, Spec: v1.ServiceSpec{Selector: map[string]string{"baz": "blah"}}}}, sss: []*apps.StatefulSet{ {ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "ss1"}, Spec: apps.StatefulSetSpec{Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}}}, {ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "ss2"}, Spec: apps.StatefulSetSpec{Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"bar": "foo"}}}}, }, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}}, name: "service with partial pod label matches with service and statefulset", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: map[string]string{"foo": "bar", "bar": "foo"}, OwnerReferences: controllerRef("rc3", rcKind)}}, + pod: st.MakePod().Namespace(metav1.NamespaceDefault).Labels(map[string]string{"foo": "bar", "bar": "foo"}).OwnerReference("rc3", rcKind).Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("rc2", rcKind)}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rc1", rcKind)}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rc1", rcKind)}}, + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("rc2", rcKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("rc1", rcKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node2").Labels(labels1).OwnerReference("rc1", rcKind).Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, rcs: []*v1.ReplicationController{{ ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "rc3"}, Spec: v1.ReplicationControllerSpec{Selector: map[string]string{"foo": "bar"}}}}, services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Name: "s1", Namespace: metav1.NamespaceDefault}, Spec: v1.ServiceSpec{Selector: map[string]string{"bar": "foo"}}}}, // Taken together Service and Replication Controller should match no pods. - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: framework.MaxNodeScore}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: framework.MaxNodeScore}}, name: "disjoined service and replication controller matches no pods", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: map[string]string{"foo": "bar", "bar": "foo"}, - OwnerReferences: controllerRef("rs3", rsKind)}}, + pod: st.MakePod().Namespace(metav1.NamespaceDefault).Labels(map[string]string{"foo": "bar", "bar": "foo"}).OwnerReference("rs3", rsKind).Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("rs2", rsKind)}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rs1", rsKind)}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rs1", rsKind)}}, + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("rs2", rsKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("rs1", rsKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node2").Labels(labels1).OwnerReference("rs1", rsKind).Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Name: "s1", Namespace: metav1.NamespaceDefault}, Spec: v1.ServiceSpec{Selector: map[string]string{"bar": "foo"}}}}, rss: []*apps.ReplicaSet{ {ObjectMeta: metav1.ObjectMeta{Name: "rs3", Namespace: metav1.NamespaceDefault}, Spec: apps.ReplicaSetSpec{Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}}}}, // We use ReplicaSet, instead of ReplicationController. The result should be exactly as above. - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: framework.MaxNodeScore}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: framework.MaxNodeScore}}, name: "disjoined service and replica set matches no pods", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: map[string]string{"foo": "bar", "bar": "foo"}, OwnerReferences: controllerRef("ss3", ssKind)}}, + pod: st.MakePod().Namespace(metav1.NamespaceDefault).Labels(map[string]string{"foo": "bar", "bar": "foo"}).OwnerReference("ss3", ssKind).Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("ss2", ssKind)}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("ss1", ssKind)}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("ss1", ssKind)}}, + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("ss2", ssKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("ss1", ssKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node2").Labels(labels1).OwnerReference("ss1", ssKind).Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Name: "s1", Namespace: metav1.NamespaceDefault}, Spec: v1.ServiceSpec{Selector: map[string]string{"bar": "foo"}}}}, sss: []*apps.StatefulSet{ {ObjectMeta: metav1.ObjectMeta{Name: "ss3", Namespace: metav1.NamespaceDefault}, Spec: apps.StatefulSetSpec{Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}}}}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: framework.MaxNodeScore}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: framework.MaxNodeScore}, {Name: "node2", Score: framework.MaxNodeScore}}, name: "disjoined service and stateful set matches no pods", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rc1", rcKind)}}, + pod: st.MakePod().Namespace(metav1.NamespaceDefault).Labels(labels1).OwnerReference("rc1", rcKind).Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("rc2", rcKind)}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rc1", rcKind)}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rc1", rcKind)}}, + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("rc2", rcKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("rc1", rcKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node2").Labels(labels1).OwnerReference("rc1", rcKind).Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, rcs: []*v1.ReplicationController{{ObjectMeta: metav1.ObjectMeta{Name: "rc1", Namespace: metav1.NamespaceDefault}, Spec: v1.ReplicationControllerSpec{Selector: map[string]string{"foo": "bar"}}}}, // Both Nodes have one pod from the given RC, hence both get 0 score. - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}}, name: "Replication controller with partial pod label matches", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rs1", rsKind)}}, + pod: st.MakePod().Namespace(metav1.NamespaceDefault).Labels(labels1).OwnerReference("rs1", rsKind).Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("rs2", rsKind)}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rs1", rsKind)}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rs1", rsKind)}}, + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("rs2", rsKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("rs1", rsKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node2").Labels(labels1).OwnerReference("rs1", rsKind).Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, rss: []*apps.ReplicaSet{{ObjectMeta: metav1.ObjectMeta{Name: "rs1", Namespace: metav1.NamespaceDefault}, Spec: apps.ReplicaSetSpec{Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}}}}, // We use ReplicaSet, instead of ReplicationController. The result should be exactly as above. - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}}, name: "Replica set with partial pod label matches", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("ss1", ssKind)}}, + pod: st.MakePod().Namespace(metav1.NamespaceDefault).Labels(labels1).OwnerReference("ss1", ssKind).Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("ss2", ssKind)}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("ss1", ssKind)}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("ss1", ssKind)}}, + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("ss2", ssKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("ss1", ssKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node2").Labels(labels1).OwnerReference("ss1", ssKind).Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, sss: []*apps.StatefulSet{{ObjectMeta: metav1.ObjectMeta{Name: "ss1", Namespace: metav1.NamespaceDefault}, Spec: apps.StatefulSetSpec{Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}}}}, // We use StatefulSet, instead of ReplicationController. The result should be exactly as above. - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}}, name: "StatefulSet with partial pod label matches", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rc3", rcKind)}}, + pod: st.MakePod().Namespace(metav1.NamespaceDefault).Labels(labels1).OwnerReference("rc3", rcKind).Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("rc2", rcKind)}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rc1", rcKind)}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rc1", rcKind)}}, + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("rc2", rcKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("rc1", rcKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node2").Labels(labels1).OwnerReference("rc1", rcKind).Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, rcs: []*v1.ReplicationController{{ObjectMeta: metav1.ObjectMeta{Name: "rc3", Namespace: metav1.NamespaceDefault}, Spec: v1.ReplicationControllerSpec{Selector: map[string]string{"baz": "blah"}}}}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 50}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 50}}, name: "Another replication controller with partial pod label matches", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rs3", rsKind)}}, + pod: st.MakePod().Namespace(metav1.NamespaceDefault).Labels(labels1).OwnerReference("rs3", rsKind).Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("rs2", rsKind)}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rs1", rsKind)}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rs1", rsKind)}}, + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("rs2", rsKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("rs1", rsKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node2").Labels(labels1).OwnerReference("rs1", rsKind).Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, rss: []*apps.ReplicaSet{{ObjectMeta: metav1.ObjectMeta{Name: "rs3", Namespace: metav1.NamespaceDefault}, Spec: apps.ReplicaSetSpec{Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"baz": "blah"}}}}}, // We use ReplicaSet, instead of ReplicationController. The result should be exactly as above. - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 50}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 50}}, name: "Another replication set with partial pod label matches", }, { - pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("ss3", ssKind)}}, + pod: st.MakePod().Namespace(metav1.NamespaceDefault).Labels(labels1).OwnerReference("ss3", ssKind).Obj(), pods: []*v1.Pod{ - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("ss2", ssKind)}}, - {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("ss1", ssKind)}}, - {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("ss1", ssKind)}}, + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("ss2", ssKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("ss1", ssKind).Obj(), + st.MakePod().Namespace(metav1.NamespaceDefault).Node("node2").Labels(labels1).OwnerReference("ss1", ssKind).Obj(), }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, sss: []*apps.StatefulSet{{ObjectMeta: metav1.ObjectMeta{Name: "ss3", Namespace: metav1.NamespaceDefault}, Spec: apps.StatefulSetSpec{Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"baz": "blah"}}}}}, // We use StatefulSet, instead of ReplicationController. The result should be exactly as above. - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 50}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 50}}, name: "Another stateful set with partial pod label matches", }, { @@ -385,9 +385,9 @@ func TestSelectorSpreadScore(t *testing.T) { {Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("ss1", ssKind)}}, {Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("ss1", ssKind)}}, }, - nodes: []string{"machine1", "machine2"}, + nodes: []string{"node1", "node2"}, sss: []*apps.StatefulSet{{ObjectMeta: metav1.ObjectMeta{Name: "ss1", Namespace: metav1.NamespaceDefault}, Spec: apps.StatefulSetSpec{Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"baz": "blah"}}}}}, - expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}}, + expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}}, name: "Another statefulset with TopologySpreadConstraints set in pod", }, } @@ -458,12 +458,12 @@ func TestZoneSelectorSpreadPriority(t *testing.T) { "baz": "blah", } - const nodeMachine1Zone1 = "machine1.zone1" - const nodeMachine1Zone2 = "machine1.zone2" - const nodeMachine2Zone2 = "machine2.zone2" - const nodeMachine1Zone3 = "machine1.zone3" - const nodeMachine2Zone3 = "machine2.zone3" - const nodeMachine3Zone3 = "machine3.zone3" + const nodeMachine1Zone1 = "node1.zone1" + const nodeMachine1Zone2 = "node1.zone2" + const nodeMachine2Zone2 = "node2.zone2" + const nodeMachine1Zone3 = "node1.zone3" + const nodeMachine2Zone3 = "node2.zone3" + const nodeMachine3Zone3 = "node3.zone3" buildNodeLabels := func(failureDomain string) map[string]string { labels := map[string]string{ @@ -555,7 +555,7 @@ func TestZoneSelectorSpreadPriority(t *testing.T) { services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "s1"}, Spec: v1.ServiceSpec{Selector: labels1}}}, expectedList: []framework.NodeScore{ {Name: nodeMachine1Zone1, Score: framework.MaxNodeScore}, - {Name: nodeMachine1Zone2, Score: 0}, // Already have pod on machine + {Name: nodeMachine1Zone2, Score: 0}, // Already have pod on node {Name: nodeMachine2Zone2, Score: 33}, // Already have pod in zone {Name: nodeMachine1Zone3, Score: framework.MaxNodeScore}, {Name: nodeMachine2Zone3, Score: framework.MaxNodeScore}, diff --git a/pkg/scheduler/framework/plugins/volumerestrictions/volume_restrictions_test.go b/pkg/scheduler/framework/plugins/volumerestrictions/volume_restrictions_test.go index d083db38b86..088eeb9d05d 100644 --- a/pkg/scheduler/framework/plugins/volumerestrictions/volume_restrictions_test.go +++ b/pkg/scheduler/framework/plugins/volumerestrictions/volume_restrictions_test.go @@ -32,28 +32,21 @@ import ( "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" plugintesting "k8s.io/kubernetes/pkg/scheduler/framework/plugins/testing" "k8s.io/kubernetes/pkg/scheduler/internal/cache" + st "k8s.io/kubernetes/pkg/scheduler/testing" ) func TestGCEDiskConflicts(t *testing.T) { - volState := v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{ - PDName: "foo", - }, - }, + volState := v1.Volume{ + VolumeSource: v1.VolumeSource{ + GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{ + PDName: "foo", }, }, } - volState2 := v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{ - PDName: "bar", - }, - }, + volState2 := v1.Volume{ + VolumeSource: v1.VolumeSource{ + GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{ + PDName: "bar", }, }, } @@ -66,9 +59,9 @@ func TestGCEDiskConflicts(t *testing.T) { wantStatus *framework.Status }{ {&v1.Pod{}, framework.NewNodeInfo(), true, "nothing", nil}, - {&v1.Pod{}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), true, "one state", nil}, - {&v1.Pod{Spec: volState}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), false, "same state", errStatus}, - {&v1.Pod{Spec: volState2}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), true, "different state", nil}, + {&v1.Pod{}, framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), true, "one state", nil}, + {st.MakePod().Volume(volState).Obj(), framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), false, "same state", errStatus}, + {st.MakePod().Volume(volState2).Obj(), framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), true, "different state", nil}, } for _, test := range tests { @@ -85,25 +78,17 @@ func TestGCEDiskConflicts(t *testing.T) { } func TestAWSDiskConflicts(t *testing.T) { - volState := v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{ - VolumeID: "foo", - }, - }, + volState := v1.Volume{ + VolumeSource: v1.VolumeSource{ + AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{ + VolumeID: "foo", }, }, } - volState2 := v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{ - VolumeID: "bar", - }, - }, + volState2 := v1.Volume{ + VolumeSource: v1.VolumeSource{ + AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{ + VolumeID: "bar", }, }, } @@ -116,9 +101,9 @@ func TestAWSDiskConflicts(t *testing.T) { wantStatus *framework.Status }{ {&v1.Pod{}, framework.NewNodeInfo(), true, "nothing", nil}, - {&v1.Pod{}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), true, "one state", nil}, - {&v1.Pod{Spec: volState}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), false, "same state", errStatus}, - {&v1.Pod{Spec: volState2}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), true, "different state", nil}, + {&v1.Pod{}, framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), true, "one state", nil}, + {st.MakePod().Volume(volState).Obj(), framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), false, "same state", errStatus}, + {st.MakePod().Volume(volState2).Obj(), framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), true, "different state", nil}, } for _, test := range tests { @@ -135,31 +120,23 @@ func TestAWSDiskConflicts(t *testing.T) { } func TestRBDDiskConflicts(t *testing.T) { - volState := v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - RBD: &v1.RBDVolumeSource{ - CephMonitors: []string{"a", "b"}, - RBDPool: "foo", - RBDImage: "bar", - FSType: "ext4", - }, - }, + volState := v1.Volume{ + VolumeSource: v1.VolumeSource{ + RBD: &v1.RBDVolumeSource{ + CephMonitors: []string{"a", "b"}, + RBDPool: "foo", + RBDImage: "bar", + FSType: "ext4", }, }, } - volState2 := v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - RBD: &v1.RBDVolumeSource{ - CephMonitors: []string{"c", "d"}, - RBDPool: "foo", - RBDImage: "bar", - FSType: "ext4", - }, - }, + volState2 := v1.Volume{ + VolumeSource: v1.VolumeSource{ + RBD: &v1.RBDVolumeSource{ + CephMonitors: []string{"c", "d"}, + RBDPool: "foo", + RBDImage: "bar", + FSType: "ext4", }, }, } @@ -172,9 +149,9 @@ func TestRBDDiskConflicts(t *testing.T) { wantStatus *framework.Status }{ {&v1.Pod{}, framework.NewNodeInfo(), true, "nothing", nil}, - {&v1.Pod{}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), true, "one state", nil}, - {&v1.Pod{Spec: volState}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), false, "same state", errStatus}, - {&v1.Pod{Spec: volState2}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), true, "different state", nil}, + {&v1.Pod{}, framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), true, "one state", nil}, + {st.MakePod().Volume(volState).Obj(), framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), false, "same state", errStatus}, + {st.MakePod().Volume(volState2).Obj(), framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), true, "different state", nil}, } for _, test := range tests { @@ -191,31 +168,23 @@ func TestRBDDiskConflicts(t *testing.T) { } func TestISCSIDiskConflicts(t *testing.T) { - volState := v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - ISCSI: &v1.ISCSIVolumeSource{ - TargetPortal: "127.0.0.1:3260", - IQN: "iqn.2016-12.server:storage.target01", - FSType: "ext4", - Lun: 0, - }, - }, + volState := v1.Volume{ + VolumeSource: v1.VolumeSource{ + ISCSI: &v1.ISCSIVolumeSource{ + TargetPortal: "127.0.0.1:3260", + IQN: "iqn.2016-12.server:storage.target01", + FSType: "ext4", + Lun: 0, }, }, } - volState2 := v1.PodSpec{ - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - ISCSI: &v1.ISCSIVolumeSource{ - TargetPortal: "127.0.0.1:3260", - IQN: "iqn.2017-12.server:storage.target01", - FSType: "ext4", - Lun: 0, - }, - }, + volState2 := v1.Volume{ + VolumeSource: v1.VolumeSource{ + ISCSI: &v1.ISCSIVolumeSource{ + TargetPortal: "127.0.0.1:3260", + IQN: "iqn.2017-12.server:storage.target01", + FSType: "ext4", + Lun: 0, }, }, } @@ -228,9 +197,9 @@ func TestISCSIDiskConflicts(t *testing.T) { wantStatus *framework.Status }{ {&v1.Pod{}, framework.NewNodeInfo(), true, "nothing", nil}, - {&v1.Pod{}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), true, "one state", nil}, - {&v1.Pod{Spec: volState}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), false, "same state", errStatus}, - {&v1.Pod{Spec: volState2}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), true, "different state", nil}, + {&v1.Pod{}, framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), true, "one state", nil}, + {st.MakePod().Volume(volState).Obj(), framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), false, "same state", errStatus}, + {st.MakePod().Volume(volState2).Obj(), framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), true, "different state", nil}, } for _, test := range tests { @@ -249,44 +218,10 @@ func TestISCSIDiskConflicts(t *testing.T) { func TestAccessModeConflicts(t *testing.T) { defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, true)() - podWithReadWriteOncePodPVC := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - // Required for querying lister for PVCs in the same namespace. - Namespace: "default", - Name: "pod-with-rwop", - }, - Spec: v1.PodSpec{ - NodeName: "node-1", - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "claim-with-rwop", - }, - }, - }, - }, - }, - } - podWithReadWriteManyPVC := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - // Required for querying lister for PVCs in the same namespace. - Namespace: "default", - Name: "pod-with-rwx", - }, - Spec: v1.PodSpec{ - NodeName: "node-1", - Volumes: []v1.Volume{ - { - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: "claim-with-rwx", - }, - }, - }, - }, - }, - } + // Required for querying lister for PVCs in the same namespace. + podWithReadWriteOncePodPVC := st.MakePod().Name("pod-with-rwop").Namespace(metav1.NamespaceDefault).PVC("claim-with-rwop").Node("node-1").Obj() + // Required for querying lister for PVCs in the same namespace. + podWithReadWriteManyPVC := st.MakePod().Name("pod-with-rwx").Namespace(metav1.NamespaceDefault).PVC("claim-with-rwx").Node("node-1").Obj() node := &v1.Node{ ObjectMeta: metav1.ObjectMeta{ diff --git a/pkg/scheduler/framework/plugins/volumezone/volume_zone_test.go b/pkg/scheduler/framework/plugins/volumezone/volume_zone_test.go index 1ec592aed17..ecc99896b08 100644 --- a/pkg/scheduler/framework/plugins/volumezone/volume_zone_test.go +++ b/pkg/scheduler/framework/plugins/volumezone/volume_zone_test.go @@ -26,24 +26,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/kubernetes/pkg/scheduler/framework" fakeframework "k8s.io/kubernetes/pkg/scheduler/framework/fake" + st "k8s.io/kubernetes/pkg/scheduler/testing" ) func createPodWithVolume(pod, pv, pvc string) *v1.Pod { - return &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: pod, Namespace: "default"}, - Spec: v1.PodSpec{ - Volumes: []v1.Volume{ - { - Name: pv, - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: pvc, - }, - }, - }, - }, - }, - } + return st.MakePod().Name(pod).Namespace(metav1.NamespaceDefault).PVC(pvc).Obj() } func TestSingleZone(t *testing.T) { @@ -100,9 +87,7 @@ func TestSingleZone(t *testing.T) { }{ { name: "pod without volume", - Pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{Name: "pod_1", Namespace: "default"}, - }, + Pod: st.MakePod().Name("pod_1").Namespace(metav1.NamespaceDefault).Obj(), Node: &v1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: "host1",