diff --git a/pkg/scheduler/algorithm/predicates/metadata_test.go b/pkg/scheduler/algorithm/predicates/metadata_test.go index f76d9b4a36e..1ca96f948e9 100644 --- a/pkg/scheduler/algorithm/predicates/metadata_test.go +++ b/pkg/scheduler/algorithm/predicates/metadata_test.go @@ -25,7 +25,7 @@ import ( "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo" - schedulertesting "k8s.io/kubernetes/pkg/scheduler/testing" + st "k8s.io/kubernetes/pkg/scheduler/testing" ) // sortablePods lets us to sort pods. @@ -352,16 +352,16 @@ func TestPredicateMetadata_AddRemovePod(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - allPodLister := schedulertesting.FakePodLister(append(test.existingPods, test.addedPod)) + allPodLister := st.FakePodLister(append(test.existingPods, test.addedPod)) // getMeta creates predicate meta data given the list of pods. - getMeta := func(lister schedulertesting.FakePodLister) (*predicateMetadata, map[string]*schedulernodeinfo.NodeInfo) { + getMeta := func(lister st.FakePodLister) (*predicateMetadata, map[string]*schedulernodeinfo.NodeInfo) { nodeInfoMap := schedulernodeinfo.CreateNodeNameToInfoMap(lister, test.nodes) // nodeList is a list of non-pointer nodes to feed to FakeNodeListInfo. nodeList := []v1.Node{} for _, n := range test.nodes { nodeList = append(nodeList, *n) } - _, precompute := NewServiceAffinityPredicate(lister, schedulertesting.FakeServiceLister(test.services), FakeNodeListInfo(nodeList), nil) + _, precompute := NewServiceAffinityPredicate(lister, st.FakeServiceLister(test.services), FakeNodeListInfo(nodeList), nil) RegisterPredicateMetadataProducer("ServiceAffinityMetaProducer", precompute) pmf := PredicateMetadataFactory{lister} meta := pmf.GetMetadata(test.pendingPod, nodeInfoMap) @@ -372,7 +372,7 @@ func TestPredicateMetadata_AddRemovePod(t *testing.T) { // are given to the metadata producer. allPodsMeta, _ := getMeta(allPodLister) // existingPodsMeta1 is meta data produced for test.existingPods (without test.addedPod). - existingPodsMeta1, nodeInfoMap := getMeta(schedulertesting.FakePodLister(test.existingPods)) + existingPodsMeta1, nodeInfoMap := getMeta(st.FakePodLister(test.existingPods)) // Add test.addedPod to existingPodsMeta1 and make sure meta is equal to allPodsMeta nodeInfo := nodeInfoMap[test.addedPod.Spec.NodeName] if err := existingPodsMeta1.AddPod(test.addedPod, nodeInfo); err != nil { @@ -383,7 +383,7 @@ func TestPredicateMetadata_AddRemovePod(t *testing.T) { } // Remove the added pod and from existingPodsMeta1 an make sure it is equal // to meta generated for existing pods. - existingPodsMeta2, _ := getMeta(schedulertesting.FakePodLister(test.existingPods)) + existingPodsMeta2, _ := getMeta(st.FakePodLister(test.existingPods)) if err := existingPodsMeta1.RemovePod(test.addedPod); err != nil { t.Errorf("error removing pod from meta: %v", err) } @@ -936,14 +936,14 @@ func TestGetTPMapMatchingSpreadConstraints(t *testing.T) { }{ { name: "clean cluster with one spreadConstraint", - pod: makePod().name("p").label("foo", "").spreadConstraint( - 1, "zone", hardSpread, makeLabelSelector().exists("foo").obj(), - ).obj(), + pod: st.MakePod().Name("p").Label("foo", "").SpreadConstraint( + 1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), + ).Obj(), nodes: []*v1.Node{ - makeNode().name("node-a").label("zone", "zone1").label("node", "node-a").obj(), - makeNode().name("node-b").label("zone", "zone1").label("node", "node-b").obj(), - makeNode().name("node-x").label("zone", "zone2").label("node", "node-x").obj(), - makeNode().name("node-y").label("zone", "zone2").label("node", "node-y").obj(), + st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(), + st.MakeNode().Name("node-b").Label("zone", "zone1").Label("node", "node-b").Obj(), + st.MakeNode().Name("node-x").Label("zone", "zone2").Label("node", "node-x").Obj(), + st.MakeNode().Name("node-y").Label("zone", "zone2").Label("node", "node-y").Obj(), }, injectPodPointers: map[topologyPair][]int{ // denotes no existing pod is matched on this zone pair, but still needed to be @@ -960,21 +960,21 @@ func TestGetTPMapMatchingSpreadConstraints(t *testing.T) { }, { name: "normal case with one spreadConstraint", - pod: makePod().name("p").label("foo", "").spreadConstraint( - 1, "zone", hardSpread, makeLabelSelector().exists("foo").obj(), - ).obj(), + pod: st.MakePod().Name("p").Label("foo", "").SpreadConstraint( + 1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), + ).Obj(), nodes: []*v1.Node{ - makeNode().name("node-a").label("zone", "zone1").label("node", "node-a").obj(), - makeNode().name("node-b").label("zone", "zone1").label("node", "node-b").obj(), - makeNode().name("node-x").label("zone", "zone2").label("node", "node-x").obj(), - makeNode().name("node-y").label("zone", "zone2").label("node", "node-y").obj(), + st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(), + st.MakeNode().Name("node-b").Label("zone", "zone1").Label("node", "node-b").Obj(), + st.MakeNode().Name("node-x").Label("zone", "zone2").Label("node", "node-x").Obj(), + st.MakeNode().Name("node-y").Label("zone", "zone2").Label("node", "node-y").Obj(), }, existingPods: []*v1.Pod{ - makePod().name("p-a1").node("node-a").label("foo", "").obj(), - makePod().name("p-a2").node("node-a").label("foo", "").obj(), - makePod().name("p-b1").node("node-b").label("foo", "").obj(), - makePod().name("p-y1").node("node-y").label("foo", "").obj(), - makePod().name("p-y2").node("node-y").label("foo", "").obj(), + st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(), + st.MakePod().Name("p-a2").Node("node-a").Label("foo", "").Obj(), + st.MakePod().Name("p-b1").Node("node-b").Label("foo", "").Obj(), + st.MakePod().Name("p-y1").Node("node-y").Label("foo", "").Obj(), + st.MakePod().Name("p-y2").Node("node-y").Label("foo", "").Obj(), }, injectPodPointers: map[topologyPair][]int{ // denotes existingPods[0,1,2] @@ -997,21 +997,21 @@ func TestGetTPMapMatchingSpreadConstraints(t *testing.T) { }, { name: "namespace mis-match doesn't count", - pod: makePod().name("p").label("foo", "").spreadConstraint( - 1, "zone", hardSpread, makeLabelSelector().exists("foo").obj(), - ).obj(), + pod: st.MakePod().Name("p").Label("foo", "").SpreadConstraint( + 1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(), + ).Obj(), nodes: []*v1.Node{ - makeNode().name("node-a").label("zone", "zone1").label("node", "node-a").obj(), - makeNode().name("node-b").label("zone", "zone1").label("node", "node-b").obj(), - makeNode().name("node-x").label("zone", "zone2").label("node", "node-x").obj(), - makeNode().name("node-y").label("zone", "zone2").label("node", "node-y").obj(), + st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(), + st.MakeNode().Name("node-b").Label("zone", "zone1").Label("node", "node-b").Obj(), + st.MakeNode().Name("node-x").Label("zone", "zone2").Label("node", "node-x").Obj(), + st.MakeNode().Name("node-y").Label("zone", "zone2").Label("node", "node-y").Obj(), }, existingPods: []*v1.Pod{ - makePod().name("p-a1").node("node-a").label("foo", "").obj(), - makePod().name("p-a2").namespace("ns1").node("node-a").label("foo", "").obj(), - makePod().name("p-b1").node("node-b").label("foo", "").obj(), - makePod().name("p-y1").namespace("ns2").node("node-y").label("foo", "").obj(), - makePod().name("p-y2").node("node-y").label("foo", "").obj(), + st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(), + st.MakePod().Name("p-a2").Namespace("ns1").Node("node-a").Label("foo", "").Obj(), + st.MakePod().Name("p-b1").Node("node-b").Label("foo", "").Obj(), + st.MakePod().Name("p-y1").Namespace("ns2").Node("node-y").Label("foo", "").Obj(), + st.MakePod().Name("p-y2").Node("node-y").Label("foo", "").Obj(), }, injectPodPointers: map[topologyPair][]int{ {key: "zone", value: "zone1"}: {0, 2}, @@ -1030,24 +1030,24 @@ func TestGetTPMapMatchingSpreadConstraints(t *testing.T) { }, { name: "normal case with two spreadConstraints", - pod: makePod().name("p").label("foo", ""). - spreadConstraint(1, "zone", hardSpread, makeLabelSelector().exists("foo").obj()). - spreadConstraint(1, "node", hardSpread, makeLabelSelector().exists("foo").obj()). - obj(), + pod: st.MakePod().Name("p").Label("foo", ""). + SpreadConstraint(1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj()). + SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj()). + Obj(), nodes: []*v1.Node{ - makeNode().name("node-a").label("zone", "zone1").label("node", "node-a").obj(), - makeNode().name("node-b").label("zone", "zone1").label("node", "node-b").obj(), - makeNode().name("node-x").label("zone", "zone2").label("node", "node-x").obj(), - makeNode().name("node-y").label("zone", "zone2").label("node", "node-y").obj(), + st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(), + st.MakeNode().Name("node-b").Label("zone", "zone1").Label("node", "node-b").Obj(), + st.MakeNode().Name("node-x").Label("zone", "zone2").Label("node", "node-x").Obj(), + st.MakeNode().Name("node-y").Label("zone", "zone2").Label("node", "node-y").Obj(), }, existingPods: []*v1.Pod{ - makePod().name("p-a1").node("node-a").label("foo", "").obj(), - makePod().name("p-a2").node("node-a").label("foo", "").obj(), - makePod().name("p-b1").node("node-b").label("foo", "").obj(), - makePod().name("p-y1").node("node-y").label("foo", "").obj(), - makePod().name("p-y2").node("node-y").label("foo", "").obj(), - makePod().name("p-y3").node("node-y").label("foo", "").obj(), - makePod().name("p-y4").node("node-y").label("foo", "").obj(), + st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(), + st.MakePod().Name("p-a2").Node("node-a").Label("foo", "").Obj(), + st.MakePod().Name("p-b1").Node("node-b").Label("foo", "").Obj(), + st.MakePod().Name("p-y1").Node("node-y").Label("foo", "").Obj(), + st.MakePod().Name("p-y2").Node("node-y").Label("foo", "").Obj(), + st.MakePod().Name("p-y3").Node("node-y").Label("foo", "").Obj(), + st.MakePod().Name("p-y4").Node("node-y").Label("foo", "").Obj(), }, injectPodPointers: map[topologyPair][]int{ {key: "zone", value: "zone1"}: {0, 1, 2}, @@ -1074,25 +1074,25 @@ func TestGetTPMapMatchingSpreadConstraints(t *testing.T) { }, { name: "soft spreadConstraints should be bypassed", - pod: makePod().name("p").label("foo", ""). - spreadConstraint(1, "zone", softSpread, makeLabelSelector().exists("foo").obj()). - spreadConstraint(1, "zone", hardSpread, makeLabelSelector().exists("foo").obj()). - spreadConstraint(1, "zone", softSpread, makeLabelSelector().exists("foo").obj()). - spreadConstraint(1, "node", hardSpread, makeLabelSelector().exists("foo").obj()). - obj(), + pod: st.MakePod().Name("p").Label("foo", ""). + SpreadConstraint(1, "zone", softSpread, st.MakeLabelSelector().Exists("foo").Obj()). + SpreadConstraint(1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj()). + SpreadConstraint(1, "zone", softSpread, st.MakeLabelSelector().Exists("foo").Obj()). + SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj()). + Obj(), nodes: []*v1.Node{ - makeNode().name("node-a").label("zone", "zone1").label("node", "node-a").obj(), - makeNode().name("node-b").label("zone", "zone1").label("node", "node-b").obj(), - makeNode().name("node-y").label("zone", "zone2").label("node", "node-y").obj(), + st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(), + st.MakeNode().Name("node-b").Label("zone", "zone1").Label("node", "node-b").Obj(), + st.MakeNode().Name("node-y").Label("zone", "zone2").Label("node", "node-y").Obj(), }, existingPods: []*v1.Pod{ - makePod().name("p-a1").node("node-a").label("foo", "").obj(), - makePod().name("p-a2").node("node-a").label("foo", "").obj(), - makePod().name("p-b1").node("node-b").label("foo", "").obj(), - makePod().name("p-y1").node("node-y").label("foo", "").obj(), - makePod().name("p-y2").node("node-y").label("foo", "").obj(), - makePod().name("p-y3").node("node-y").label("foo", "").obj(), - makePod().name("p-y4").node("node-y").label("foo", "").obj(), + st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(), + st.MakePod().Name("p-a2").Node("node-a").Label("foo", "").Obj(), + st.MakePod().Name("p-b1").Node("node-b").Label("foo", "").Obj(), + st.MakePod().Name("p-y1").Node("node-y").Label("foo", "").Obj(), + st.MakePod().Name("p-y2").Node("node-y").Label("foo", "").Obj(), + st.MakePod().Name("p-y3").Node("node-y").Label("foo", "").Obj(), + st.MakePod().Name("p-y4").Node("node-y").Label("foo", "").Obj(), }, injectPodPointers: map[topologyPair][]int{ {key: "zone", value: "zone1"}: {0, 1, 2}, @@ -1118,23 +1118,23 @@ func TestGetTPMapMatchingSpreadConstraints(t *testing.T) { }, { name: "different labelSelectors", - pod: makePod().name("p").label("foo", "").label("bar", ""). - spreadConstraint(1, "zone", hardSpread, makeLabelSelector().exists("foo").obj()). - spreadConstraint(1, "node", hardSpread, makeLabelSelector().exists("bar").obj()). - obj(), + pod: st.MakePod().Name("p").Label("foo", "").Label("bar", ""). + SpreadConstraint(1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj()). + SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("bar").Obj()). + Obj(), nodes: []*v1.Node{ - makeNode().name("node-a").label("zone", "zone1").label("node", "node-a").obj(), - makeNode().name("node-b").label("zone", "zone1").label("node", "node-b").obj(), - makeNode().name("node-y").label("zone", "zone2").label("node", "node-y").obj(), + st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(), + st.MakeNode().Name("node-b").Label("zone", "zone1").Label("node", "node-b").Obj(), + st.MakeNode().Name("node-y").Label("zone", "zone2").Label("node", "node-y").Obj(), }, existingPods: []*v1.Pod{ - makePod().name("p-a1").node("node-a").label("foo", "").obj(), - makePod().name("p-a2").node("node-a").label("foo", "").label("bar", "").obj(), - makePod().name("p-b1").node("node-b").label("foo", "").obj(), - makePod().name("p-y1").node("node-y").label("foo", "").obj(), - makePod().name("p-y2").node("node-y").label("foo", "").label("bar", "").obj(), - makePod().name("p-y3").node("node-y").label("foo", "").obj(), - makePod().name("p-y4").node("node-y").label("foo", "").label("bar", "").obj(), + st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(), + st.MakePod().Name("p-a2").Node("node-a").Label("foo", "").Label("bar", "").Obj(), + st.MakePod().Name("p-b1").Node("node-b").Label("foo", "").Obj(), + st.MakePod().Name("p-y1").Node("node-y").Label("foo", "").Obj(), + st.MakePod().Name("p-y2").Node("node-y").Label("foo", "").Label("bar", "").Obj(), + st.MakePod().Name("p-y3").Node("node-y").Label("foo", "").Obj(), + st.MakePod().Name("p-y4").Node("node-y").Label("foo", "").Label("bar", "").Obj(), }, injectPodPointers: map[topologyPair][]int{ {key: "zone", value: "zone1"}: {1}, @@ -1156,25 +1156,25 @@ func TestGetTPMapMatchingSpreadConstraints(t *testing.T) { }, { name: "two spreadConstraints, and with podAffinity", - pod: makePod().name("p").label("foo", ""). - nodeAffinityNotIn("node", []string{"node-x"}). // exclude node-x - spreadConstraint(1, "zone", hardSpread, makeLabelSelector().exists("foo").obj()). - spreadConstraint(1, "node", hardSpread, makeLabelSelector().exists("foo").obj()). - obj(), + pod: st.MakePod().Name("p").Label("foo", ""). + NodeAffinityNotIn("node", []string{"node-x"}). // exclude node-x + SpreadConstraint(1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj()). + SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj()). + Obj(), nodes: []*v1.Node{ - makeNode().name("node-a").label("zone", "zone1").label("node", "node-a").obj(), - makeNode().name("node-b").label("zone", "zone1").label("node", "node-b").obj(), - makeNode().name("node-x").label("zone", "zone2").label("node", "node-x").obj(), - makeNode().name("node-y").label("zone", "zone2").label("node", "node-y").obj(), + st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(), + st.MakeNode().Name("node-b").Label("zone", "zone1").Label("node", "node-b").Obj(), + st.MakeNode().Name("node-x").Label("zone", "zone2").Label("node", "node-x").Obj(), + st.MakeNode().Name("node-y").Label("zone", "zone2").Label("node", "node-y").Obj(), }, existingPods: []*v1.Pod{ - makePod().name("p-a1").node("node-a").label("foo", "").obj(), - makePod().name("p-a2").node("node-a").label("foo", "").obj(), - makePod().name("p-b1").node("node-b").label("foo", "").obj(), - makePod().name("p-y1").node("node-y").label("foo", "").obj(), - makePod().name("p-y2").node("node-y").label("foo", "").obj(), - makePod().name("p-y3").node("node-y").label("foo", "").obj(), - makePod().name("p-y4").node("node-y").label("foo", "").obj(), + st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(), + st.MakePod().Name("p-a2").Node("node-a").Label("foo", "").Obj(), + st.MakePod().Name("p-b1").Node("node-b").Label("foo", "").Obj(), + st.MakePod().Name("p-y1").Node("node-y").Label("foo", "").Obj(), + st.MakePod().Name("p-y2").Node("node-y").Label("foo", "").Obj(), + st.MakePod().Name("p-y3").Node("node-y").Label("foo", "").Obj(), + st.MakePod().Name("p-y4").Node("node-y").Label("foo", "").Obj(), }, injectPodPointers: map[topologyPair][]int{ {key: "zone", value: "zone1"}: {0, 1, 2}, diff --git a/pkg/scheduler/algorithm/predicates/utils.go b/pkg/scheduler/algorithm/predicates/utils.go index 3cf266a516d..3115b4e8391 100644 --- a/pkg/scheduler/algorithm/predicates/utils.go +++ b/pkg/scheduler/algorithm/predicates/utils.go @@ -21,7 +21,6 @@ import ( "k8s.io/api/core/v1" storagev1beta1 "k8s.io/api/storage/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/sets" utilfeature "k8s.io/apiserver/pkg/util/feature" @@ -148,193 +147,3 @@ func isCSIMigrationOn(csiNode *storagev1beta1.CSINode, pluginName string) bool { return mpaSet.Has(pluginName) } - -// utilities for building pod/node objects using a "chained" manner -type nodeSelectorWrapper struct{ v1.NodeSelector } - -func makeNodeSelector() *nodeSelectorWrapper { - return &nodeSelectorWrapper{v1.NodeSelector{}} -} - -// NOTE: each time we append a selectorTerm into `s` -// and overall all selecterTerms are ORed -func (s *nodeSelectorWrapper) in(key string, vals []string) *nodeSelectorWrapper { - expression := v1.NodeSelectorRequirement{ - Key: key, - Operator: v1.NodeSelectorOpIn, - Values: vals, - } - selectorTerm := v1.NodeSelectorTerm{} - selectorTerm.MatchExpressions = append(selectorTerm.MatchExpressions, expression) - s.NodeSelectorTerms = append(s.NodeSelectorTerms, selectorTerm) - return s -} - -func (s *nodeSelectorWrapper) notIn(key string, vals []string) *nodeSelectorWrapper { - expression := v1.NodeSelectorRequirement{ - Key: key, - Operator: v1.NodeSelectorOpNotIn, - Values: vals, - } - selectorTerm := v1.NodeSelectorTerm{} - selectorTerm.MatchExpressions = append(selectorTerm.MatchExpressions, expression) - s.NodeSelectorTerms = append(s.NodeSelectorTerms, selectorTerm) - return s -} - -func (s *nodeSelectorWrapper) obj() *v1.NodeSelector { - return &s.NodeSelector -} - -type labelSelectorWrapper struct{ metav1.LabelSelector } - -func makeLabelSelector() *labelSelectorWrapper { - return &labelSelectorWrapper{metav1.LabelSelector{}} -} - -func (s *labelSelectorWrapper) label(k, v string) *labelSelectorWrapper { - if s.MatchLabels == nil { - s.MatchLabels = make(map[string]string) - } - s.MatchLabels[k] = v - return s -} - -func (s *labelSelectorWrapper) in(key string, vals []string) *labelSelectorWrapper { - expression := metav1.LabelSelectorRequirement{ - Key: key, - Operator: metav1.LabelSelectorOpIn, - Values: vals, - } - s.MatchExpressions = append(s.MatchExpressions, expression) - return s -} - -func (s *labelSelectorWrapper) notIn(key string, vals []string) *labelSelectorWrapper { - expression := metav1.LabelSelectorRequirement{ - Key: key, - Operator: metav1.LabelSelectorOpNotIn, - Values: vals, - } - s.MatchExpressions = append(s.MatchExpressions, expression) - return s -} - -func (s *labelSelectorWrapper) exists(k string) *labelSelectorWrapper { - expression := metav1.LabelSelectorRequirement{ - Key: k, - Operator: metav1.LabelSelectorOpExists, - } - s.MatchExpressions = append(s.MatchExpressions, expression) - return s -} - -func (s *labelSelectorWrapper) notExist(k string) *labelSelectorWrapper { - expression := metav1.LabelSelectorRequirement{ - Key: k, - Operator: metav1.LabelSelectorOpDoesNotExist, - } - s.MatchExpressions = append(s.MatchExpressions, expression) - return s -} - -func (s *labelSelectorWrapper) obj() *metav1.LabelSelector { - return &s.LabelSelector -} - -type podWrapper struct{ v1.Pod } - -func makePod() *podWrapper { - return &podWrapper{v1.Pod{}} -} - -func (p *podWrapper) obj() *v1.Pod { - return &p.Pod -} - -func (p *podWrapper) name(s string) *podWrapper { - p.Name = s - return p -} - -func (p *podWrapper) namespace(s string) *podWrapper { - p.Namespace = s - return p -} - -func (p *podWrapper) node(s string) *podWrapper { - p.Spec.NodeName = s - return p -} - -func (p *podWrapper) nodeSelector(m map[string]string) *podWrapper { - p.Spec.NodeSelector = m - return p -} - -// represents HARD node affinity in particular -func (p *podWrapper) nodeAffinityIn(key string, vals []string) *podWrapper { - if p.Spec.Affinity == nil { - p.Spec.Affinity = &v1.Affinity{} - } - if p.Spec.Affinity.NodeAffinity == nil { - p.Spec.Affinity.NodeAffinity = &v1.NodeAffinity{} - } - nodeSelector := makeNodeSelector().in(key, vals).obj() - p.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution = nodeSelector - return p -} - -func (p *podWrapper) nodeAffinityNotIn(key string, vals []string) *podWrapper { - if p.Spec.Affinity == nil { - p.Spec.Affinity = &v1.Affinity{} - } - if p.Spec.Affinity.NodeAffinity == nil { - p.Spec.Affinity.NodeAffinity = &v1.NodeAffinity{} - } - nodeSelector := makeNodeSelector().notIn(key, vals).obj() - p.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution = nodeSelector - return p -} - -func (p *podWrapper) spreadConstraint(maxSkew int, tpKey string, mode v1.UnsatisfiableConstraintAction, selector *metav1.LabelSelector) *podWrapper { - c := v1.TopologySpreadConstraint{ - MaxSkew: int32(maxSkew), - TopologyKey: tpKey, - WhenUnsatisfiable: mode, - LabelSelector: selector, - } - p.Spec.TopologySpreadConstraints = append(p.Spec.TopologySpreadConstraints, c) - return p -} - -func (p *podWrapper) label(k, v string) *podWrapper { - if p.Labels == nil { - p.Labels = make(map[string]string) - } - p.Labels[k] = v - return p -} - -type nodeWrapper struct{ v1.Node } - -func makeNode() *nodeWrapper { - return &nodeWrapper{v1.Node{}} -} - -func (n *nodeWrapper) obj() *v1.Node { - return &n.Node -} - -func (n *nodeWrapper) name(s string) *nodeWrapper { - n.Name = s - return n -} - -func (n *nodeWrapper) label(k, v string) *nodeWrapper { - if n.Labels == nil { - n.Labels = make(map[string]string) - } - n.Labels[k] = v - return n -} diff --git a/pkg/scheduler/testing/utils.go b/pkg/scheduler/testing/utils.go new file mode 100644 index 00000000000..e72e9fd2855 --- /dev/null +++ b/pkg/scheduler/testing/utils.go @@ -0,0 +1,243 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package testing + +import ( + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// NodeSelectorWrapper wraps a NodeSelector inside. +type NodeSelectorWrapper struct{ v1.NodeSelector } + +// MakeNodeSelector creates a NodeSelector wrapper. +func MakeNodeSelector() *NodeSelectorWrapper { + return &NodeSelectorWrapper{v1.NodeSelector{}} +} + +// In injects a matchExpression (with an operator IN) as a selectorTerm +// to the inner nodeSelector. +// NOTE: appended selecterTerms are ORed. +func (s *NodeSelectorWrapper) In(key string, vals []string) *NodeSelectorWrapper { + expression := v1.NodeSelectorRequirement{ + Key: key, + Operator: v1.NodeSelectorOpIn, + Values: vals, + } + selectorTerm := v1.NodeSelectorTerm{} + selectorTerm.MatchExpressions = append(selectorTerm.MatchExpressions, expression) + s.NodeSelectorTerms = append(s.NodeSelectorTerms, selectorTerm) + return s +} + +// NotIn injects a matchExpression (with an operator NotIn) as a selectorTerm +// to the inner nodeSelector. +func (s *NodeSelectorWrapper) NotIn(key string, vals []string) *NodeSelectorWrapper { + expression := v1.NodeSelectorRequirement{ + Key: key, + Operator: v1.NodeSelectorOpNotIn, + Values: vals, + } + selectorTerm := v1.NodeSelectorTerm{} + selectorTerm.MatchExpressions = append(selectorTerm.MatchExpressions, expression) + s.NodeSelectorTerms = append(s.NodeSelectorTerms, selectorTerm) + return s +} + +// Obj returns the inner NodeSelector. +func (s *NodeSelectorWrapper) Obj() *v1.NodeSelector { + return &s.NodeSelector +} + +// LabelSelectorWrapper wraps a LabelSelector inside. +type LabelSelectorWrapper struct{ metav1.LabelSelector } + +// MakeLabelSelector creates a LabelSelector wrapper. +func MakeLabelSelector() *LabelSelectorWrapper { + return &LabelSelectorWrapper{metav1.LabelSelector{}} +} + +// Label applies a {k,v} pair to the inner LabelSelector. +func (s *LabelSelectorWrapper) Label(k, v string) *LabelSelectorWrapper { + if s.MatchLabels == nil { + s.MatchLabels = make(map[string]string) + } + s.MatchLabels[k] = v + return s +} + +// In injects a matchExpression (with an operator In) to the inner labelSelector. +func (s *LabelSelectorWrapper) In(key string, vals []string) *LabelSelectorWrapper { + expression := metav1.LabelSelectorRequirement{ + Key: key, + Operator: metav1.LabelSelectorOpIn, + Values: vals, + } + s.MatchExpressions = append(s.MatchExpressions, expression) + return s +} + +// NotIn injects a matchExpression (with an operator NotIn) to the inner labelSelector. +func (s *LabelSelectorWrapper) NotIn(key string, vals []string) *LabelSelectorWrapper { + expression := metav1.LabelSelectorRequirement{ + Key: key, + Operator: metav1.LabelSelectorOpNotIn, + Values: vals, + } + s.MatchExpressions = append(s.MatchExpressions, expression) + return s +} + +// Exists injects a matchExpression (with an operator Exists) to the inner labelSelector. +func (s *LabelSelectorWrapper) Exists(k string) *LabelSelectorWrapper { + expression := metav1.LabelSelectorRequirement{ + Key: k, + Operator: metav1.LabelSelectorOpExists, + } + s.MatchExpressions = append(s.MatchExpressions, expression) + return s +} + +// NotExist injects a matchExpression (with an operator NotExist) to the inner labelSelector. +func (s *LabelSelectorWrapper) NotExist(k string) *LabelSelectorWrapper { + expression := metav1.LabelSelectorRequirement{ + Key: k, + Operator: metav1.LabelSelectorOpDoesNotExist, + } + s.MatchExpressions = append(s.MatchExpressions, expression) + return s +} + +// Obj returns the inner LabelSelector. +func (s *LabelSelectorWrapper) Obj() *metav1.LabelSelector { + return &s.LabelSelector +} + +// PodWrapper wraps a Pod inside. +type PodWrapper struct{ v1.Pod } + +// MakePod creates a Pod wrapper. +func MakePod() *PodWrapper { + return &PodWrapper{v1.Pod{}} +} + +// Obj returns the inner Pod. +func (p *PodWrapper) Obj() *v1.Pod { + return &p.Pod +} + +// Name sets `s` as the name of the inner pod. +func (p *PodWrapper) Name(s string) *PodWrapper { + p.SetName(s) + return p +} + +// Namespace sets `s` as the namespace of the inner pod. +func (p *PodWrapper) Namespace(s string) *PodWrapper { + p.SetNamespace(s) + return p +} + +// Node sets `s` as the nodeName of the inner pod. +func (p *PodWrapper) Node(s string) *PodWrapper { + p.Spec.NodeName = s + return p +} + +// NodeSelector sets `m` as the nodeSelector of the inner pod. +func (p *PodWrapper) NodeSelector(m map[string]string) *PodWrapper { + p.Spec.NodeSelector = m + return p +} + +// NodeAffinityIn creates a HARD node affinity (with the operator In) +// and injects into the innner pod. +func (p *PodWrapper) NodeAffinityIn(key string, vals []string) *PodWrapper { + if p.Spec.Affinity == nil { + p.Spec.Affinity = &v1.Affinity{} + } + if p.Spec.Affinity.NodeAffinity == nil { + p.Spec.Affinity.NodeAffinity = &v1.NodeAffinity{} + } + nodeSelector := MakeNodeSelector().In(key, vals).Obj() + p.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution = nodeSelector + return p +} + +// NodeAffinityNotIn creates a HARD node affinity (with the operator NotIn) +// and injects into the innner pod. +func (p *PodWrapper) NodeAffinityNotIn(key string, vals []string) *PodWrapper { + if p.Spec.Affinity == nil { + p.Spec.Affinity = &v1.Affinity{} + } + if p.Spec.Affinity.NodeAffinity == nil { + p.Spec.Affinity.NodeAffinity = &v1.NodeAffinity{} + } + nodeSelector := MakeNodeSelector().NotIn(key, vals).Obj() + p.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution = nodeSelector + return p +} + +// SpreadConstraint constructs a TopologySpreadConstraint object and injects +// into the inner pod. +func (p *PodWrapper) SpreadConstraint(maxSkew int, tpKey string, mode v1.UnsatisfiableConstraintAction, selector *metav1.LabelSelector) *PodWrapper { + c := v1.TopologySpreadConstraint{ + MaxSkew: int32(maxSkew), + TopologyKey: tpKey, + WhenUnsatisfiable: mode, + LabelSelector: selector, + } + p.Spec.TopologySpreadConstraints = append(p.Spec.TopologySpreadConstraints, c) + return p +} + +// Label sets a {k,v} pair to the inner pod. +func (p *PodWrapper) Label(k, v string) *PodWrapper { + if p.Labels == nil { + p.Labels = make(map[string]string) + } + p.Labels[k] = v + return p +} + +// NodeWrapper wraps a LabelSelector inside. +type NodeWrapper struct{ v1.Node } + +// MakeNode creates a Node wrapper. +func MakeNode() *NodeWrapper { + return &NodeWrapper{v1.Node{}} +} + +// Obj returns the inner Node. +func (n *NodeWrapper) Obj() *v1.Node { + return &n.Node +} + +// Name sets `s` as the name of the inner pod. +func (n *NodeWrapper) Name(s string) *NodeWrapper { + n.SetName(s) + return n +} + +// Label applies a {k,v} label pair to the inner node. +func (n *NodeWrapper) Label(k, v string) *NodeWrapper { + if n.Labels == nil { + n.Labels = make(map[string]string) + } + n.Labels[k] = v + return n +} diff --git a/pkg/scheduler/util/utils.go b/pkg/scheduler/util/utils.go index 79b8c333e34..eb61f13a085 100644 --- a/pkg/scheduler/util/utils.go +++ b/pkg/scheduler/util/utils.go @@ -21,7 +21,7 @@ import ( "time" - v1 "k8s.io/api/core/v1" + "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/klog" "k8s.io/kubernetes/pkg/apis/scheduling"