mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 07:47:56 +00:00
EvenPodsSpread: refactor "chained" utils
- move "chanined" utils to pkg/scheduler/testing/utils.go so as to be re-used by all scheduler tests
This commit is contained in:
parent
3dbef991a3
commit
dce6686c9a
@ -25,7 +25,7 @@ import (
|
|||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
|
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.
|
// sortablePods lets us to sort pods.
|
||||||
@ -352,16 +352,16 @@ func TestPredicateMetadata_AddRemovePod(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
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 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)
|
nodeInfoMap := schedulernodeinfo.CreateNodeNameToInfoMap(lister, test.nodes)
|
||||||
// nodeList is a list of non-pointer nodes to feed to FakeNodeListInfo.
|
// nodeList is a list of non-pointer nodes to feed to FakeNodeListInfo.
|
||||||
nodeList := []v1.Node{}
|
nodeList := []v1.Node{}
|
||||||
for _, n := range test.nodes {
|
for _, n := range test.nodes {
|
||||||
nodeList = append(nodeList, *n)
|
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)
|
RegisterPredicateMetadataProducer("ServiceAffinityMetaProducer", precompute)
|
||||||
pmf := PredicateMetadataFactory{lister}
|
pmf := PredicateMetadataFactory{lister}
|
||||||
meta := pmf.GetMetadata(test.pendingPod, nodeInfoMap)
|
meta := pmf.GetMetadata(test.pendingPod, nodeInfoMap)
|
||||||
@ -372,7 +372,7 @@ func TestPredicateMetadata_AddRemovePod(t *testing.T) {
|
|||||||
// are given to the metadata producer.
|
// are given to the metadata producer.
|
||||||
allPodsMeta, _ := getMeta(allPodLister)
|
allPodsMeta, _ := getMeta(allPodLister)
|
||||||
// existingPodsMeta1 is meta data produced for test.existingPods (without test.addedPod).
|
// 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
|
// Add test.addedPod to existingPodsMeta1 and make sure meta is equal to allPodsMeta
|
||||||
nodeInfo := nodeInfoMap[test.addedPod.Spec.NodeName]
|
nodeInfo := nodeInfoMap[test.addedPod.Spec.NodeName]
|
||||||
if err := existingPodsMeta1.AddPod(test.addedPod, nodeInfo); err != nil {
|
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
|
// Remove the added pod and from existingPodsMeta1 an make sure it is equal
|
||||||
// to meta generated for existing pods.
|
// 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 {
|
if err := existingPodsMeta1.RemovePod(test.addedPod); err != nil {
|
||||||
t.Errorf("error removing pod from meta: %v", err)
|
t.Errorf("error removing pod from meta: %v", err)
|
||||||
}
|
}
|
||||||
@ -936,14 +936,14 @@ func TestGetTPMapMatchingSpreadConstraints(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "clean cluster with one spreadConstraint",
|
name: "clean cluster with one spreadConstraint",
|
||||||
pod: makePod().name("p").label("foo", "").spreadConstraint(
|
pod: st.MakePod().Name("p").Label("foo", "").SpreadConstraint(
|
||||||
1, "zone", hardSpread, makeLabelSelector().exists("foo").obj(),
|
1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(),
|
||||||
).obj(),
|
).Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
makeNode().name("node-a").label("zone", "zone1").label("node", "node-a").obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
makeNode().name("node-b").label("zone", "zone1").label("node", "node-b").obj(),
|
st.MakeNode().Name("node-b").Label("zone", "zone1").Label("node", "node-b").Obj(),
|
||||||
makeNode().name("node-x").label("zone", "zone2").label("node", "node-x").obj(),
|
st.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-y").Label("zone", "zone2").Label("node", "node-y").Obj(),
|
||||||
},
|
},
|
||||||
injectPodPointers: map[topologyPair][]int{
|
injectPodPointers: map[topologyPair][]int{
|
||||||
// denotes no existing pod is matched on this zone pair, but still needed to be
|
// 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",
|
name: "normal case with one spreadConstraint",
|
||||||
pod: makePod().name("p").label("foo", "").spreadConstraint(
|
pod: st.MakePod().Name("p").Label("foo", "").SpreadConstraint(
|
||||||
1, "zone", hardSpread, makeLabelSelector().exists("foo").obj(),
|
1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(),
|
||||||
).obj(),
|
).Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
makeNode().name("node-a").label("zone", "zone1").label("node", "node-a").obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
makeNode().name("node-b").label("zone", "zone1").label("node", "node-b").obj(),
|
st.MakeNode().Name("node-b").Label("zone", "zone1").Label("node", "node-b").Obj(),
|
||||||
makeNode().name("node-x").label("zone", "zone2").label("node", "node-x").obj(),
|
st.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-y").Label("zone", "zone2").Label("node", "node-y").Obj(),
|
||||||
},
|
},
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
makePod().name("p-a1").node("node-a").label("foo", "").obj(),
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
makePod().name("p-a2").node("node-a").label("foo", "").obj(),
|
st.MakePod().Name("p-a2").Node("node-a").Label("foo", "").Obj(),
|
||||||
makePod().name("p-b1").node("node-b").label("foo", "").obj(),
|
st.MakePod().Name("p-b1").Node("node-b").Label("foo", "").Obj(),
|
||||||
makePod().name("p-y1").node("node-y").label("foo", "").obj(),
|
st.MakePod().Name("p-y1").Node("node-y").Label("foo", "").Obj(),
|
||||||
makePod().name("p-y2").node("node-y").label("foo", "").obj(),
|
st.MakePod().Name("p-y2").Node("node-y").Label("foo", "").Obj(),
|
||||||
},
|
},
|
||||||
injectPodPointers: map[topologyPair][]int{
|
injectPodPointers: map[topologyPair][]int{
|
||||||
// denotes existingPods[0,1,2]
|
// denotes existingPods[0,1,2]
|
||||||
@ -997,21 +997,21 @@ func TestGetTPMapMatchingSpreadConstraints(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "namespace mis-match doesn't count",
|
name: "namespace mis-match doesn't count",
|
||||||
pod: makePod().name("p").label("foo", "").spreadConstraint(
|
pod: st.MakePod().Name("p").Label("foo", "").SpreadConstraint(
|
||||||
1, "zone", hardSpread, makeLabelSelector().exists("foo").obj(),
|
1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj(),
|
||||||
).obj(),
|
).Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
makeNode().name("node-a").label("zone", "zone1").label("node", "node-a").obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
makeNode().name("node-b").label("zone", "zone1").label("node", "node-b").obj(),
|
st.MakeNode().Name("node-b").Label("zone", "zone1").Label("node", "node-b").Obj(),
|
||||||
makeNode().name("node-x").label("zone", "zone2").label("node", "node-x").obj(),
|
st.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-y").Label("zone", "zone2").Label("node", "node-y").Obj(),
|
||||||
},
|
},
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
makePod().name("p-a1").node("node-a").label("foo", "").obj(),
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
makePod().name("p-a2").namespace("ns1").node("node-a").label("foo", "").obj(),
|
st.MakePod().Name("p-a2").Namespace("ns1").Node("node-a").Label("foo", "").Obj(),
|
||||||
makePod().name("p-b1").node("node-b").label("foo", "").obj(),
|
st.MakePod().Name("p-b1").Node("node-b").Label("foo", "").Obj(),
|
||||||
makePod().name("p-y1").namespace("ns2").node("node-y").label("foo", "").obj(),
|
st.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-y2").Node("node-y").Label("foo", "").Obj(),
|
||||||
},
|
},
|
||||||
injectPodPointers: map[topologyPair][]int{
|
injectPodPointers: map[topologyPair][]int{
|
||||||
{key: "zone", value: "zone1"}: {0, 2},
|
{key: "zone", value: "zone1"}: {0, 2},
|
||||||
@ -1030,24 +1030,24 @@ func TestGetTPMapMatchingSpreadConstraints(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "normal case with two spreadConstraints",
|
name: "normal case with two spreadConstraints",
|
||||||
pod: makePod().name("p").label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
spreadConstraint(1, "zone", hardSpread, makeLabelSelector().exists("foo").obj()).
|
SpreadConstraint(1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj()).
|
||||||
spreadConstraint(1, "node", hardSpread, makeLabelSelector().exists("foo").obj()).
|
SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj()).
|
||||||
obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
makeNode().name("node-a").label("zone", "zone1").label("node", "node-a").obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
makeNode().name("node-b").label("zone", "zone1").label("node", "node-b").obj(),
|
st.MakeNode().Name("node-b").Label("zone", "zone1").Label("node", "node-b").Obj(),
|
||||||
makeNode().name("node-x").label("zone", "zone2").label("node", "node-x").obj(),
|
st.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-y").Label("zone", "zone2").Label("node", "node-y").Obj(),
|
||||||
},
|
},
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
makePod().name("p-a1").node("node-a").label("foo", "").obj(),
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
makePod().name("p-a2").node("node-a").label("foo", "").obj(),
|
st.MakePod().Name("p-a2").Node("node-a").Label("foo", "").Obj(),
|
||||||
makePod().name("p-b1").node("node-b").label("foo", "").obj(),
|
st.MakePod().Name("p-b1").Node("node-b").Label("foo", "").Obj(),
|
||||||
makePod().name("p-y1").node("node-y").label("foo", "").obj(),
|
st.MakePod().Name("p-y1").Node("node-y").Label("foo", "").Obj(),
|
||||||
makePod().name("p-y2").node("node-y").label("foo", "").obj(),
|
st.MakePod().Name("p-y2").Node("node-y").Label("foo", "").Obj(),
|
||||||
makePod().name("p-y3").node("node-y").label("foo", "").obj(),
|
st.MakePod().Name("p-y3").Node("node-y").Label("foo", "").Obj(),
|
||||||
makePod().name("p-y4").node("node-y").label("foo", "").obj(),
|
st.MakePod().Name("p-y4").Node("node-y").Label("foo", "").Obj(),
|
||||||
},
|
},
|
||||||
injectPodPointers: map[topologyPair][]int{
|
injectPodPointers: map[topologyPair][]int{
|
||||||
{key: "zone", value: "zone1"}: {0, 1, 2},
|
{key: "zone", value: "zone1"}: {0, 1, 2},
|
||||||
@ -1074,25 +1074,25 @@ func TestGetTPMapMatchingSpreadConstraints(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "soft spreadConstraints should be bypassed",
|
name: "soft spreadConstraints should be bypassed",
|
||||||
pod: makePod().name("p").label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
spreadConstraint(1, "zone", softSpread, makeLabelSelector().exists("foo").obj()).
|
SpreadConstraint(1, "zone", softSpread, st.MakeLabelSelector().Exists("foo").Obj()).
|
||||||
spreadConstraint(1, "zone", hardSpread, makeLabelSelector().exists("foo").obj()).
|
SpreadConstraint(1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj()).
|
||||||
spreadConstraint(1, "zone", softSpread, makeLabelSelector().exists("foo").obj()).
|
SpreadConstraint(1, "zone", softSpread, st.MakeLabelSelector().Exists("foo").Obj()).
|
||||||
spreadConstraint(1, "node", hardSpread, makeLabelSelector().exists("foo").obj()).
|
SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj()).
|
||||||
obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
makeNode().name("node-a").label("zone", "zone1").label("node", "node-a").obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
makeNode().name("node-b").label("zone", "zone1").label("node", "node-b").obj(),
|
st.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-y").Label("zone", "zone2").Label("node", "node-y").Obj(),
|
||||||
},
|
},
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
makePod().name("p-a1").node("node-a").label("foo", "").obj(),
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
makePod().name("p-a2").node("node-a").label("foo", "").obj(),
|
st.MakePod().Name("p-a2").Node("node-a").Label("foo", "").Obj(),
|
||||||
makePod().name("p-b1").node("node-b").label("foo", "").obj(),
|
st.MakePod().Name("p-b1").Node("node-b").Label("foo", "").Obj(),
|
||||||
makePod().name("p-y1").node("node-y").label("foo", "").obj(),
|
st.MakePod().Name("p-y1").Node("node-y").Label("foo", "").Obj(),
|
||||||
makePod().name("p-y2").node("node-y").label("foo", "").obj(),
|
st.MakePod().Name("p-y2").Node("node-y").Label("foo", "").Obj(),
|
||||||
makePod().name("p-y3").node("node-y").label("foo", "").obj(),
|
st.MakePod().Name("p-y3").Node("node-y").Label("foo", "").Obj(),
|
||||||
makePod().name("p-y4").node("node-y").label("foo", "").obj(),
|
st.MakePod().Name("p-y4").Node("node-y").Label("foo", "").Obj(),
|
||||||
},
|
},
|
||||||
injectPodPointers: map[topologyPair][]int{
|
injectPodPointers: map[topologyPair][]int{
|
||||||
{key: "zone", value: "zone1"}: {0, 1, 2},
|
{key: "zone", value: "zone1"}: {0, 1, 2},
|
||||||
@ -1118,23 +1118,23 @@ func TestGetTPMapMatchingSpreadConstraints(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "different labelSelectors",
|
name: "different labelSelectors",
|
||||||
pod: makePod().name("p").label("foo", "").label("bar", "").
|
pod: st.MakePod().Name("p").Label("foo", "").Label("bar", "").
|
||||||
spreadConstraint(1, "zone", hardSpread, makeLabelSelector().exists("foo").obj()).
|
SpreadConstraint(1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj()).
|
||||||
spreadConstraint(1, "node", hardSpread, makeLabelSelector().exists("bar").obj()).
|
SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("bar").Obj()).
|
||||||
obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
makeNode().name("node-a").label("zone", "zone1").label("node", "node-a").obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
makeNode().name("node-b").label("zone", "zone1").label("node", "node-b").obj(),
|
st.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-y").Label("zone", "zone2").Label("node", "node-y").Obj(),
|
||||||
},
|
},
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
makePod().name("p-a1").node("node-a").label("foo", "").obj(),
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
makePod().name("p-a2").node("node-a").label("foo", "").label("bar", "").obj(),
|
st.MakePod().Name("p-a2").Node("node-a").Label("foo", "").Label("bar", "").Obj(),
|
||||||
makePod().name("p-b1").node("node-b").label("foo", "").obj(),
|
st.MakePod().Name("p-b1").Node("node-b").Label("foo", "").Obj(),
|
||||||
makePod().name("p-y1").node("node-y").label("foo", "").obj(),
|
st.MakePod().Name("p-y1").Node("node-y").Label("foo", "").Obj(),
|
||||||
makePod().name("p-y2").node("node-y").label("foo", "").label("bar", "").obj(),
|
st.MakePod().Name("p-y2").Node("node-y").Label("foo", "").Label("bar", "").Obj(),
|
||||||
makePod().name("p-y3").node("node-y").label("foo", "").obj(),
|
st.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-y4").Node("node-y").Label("foo", "").Label("bar", "").Obj(),
|
||||||
},
|
},
|
||||||
injectPodPointers: map[topologyPair][]int{
|
injectPodPointers: map[topologyPair][]int{
|
||||||
{key: "zone", value: "zone1"}: {1},
|
{key: "zone", value: "zone1"}: {1},
|
||||||
@ -1156,25 +1156,25 @@ func TestGetTPMapMatchingSpreadConstraints(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "two spreadConstraints, and with podAffinity",
|
name: "two spreadConstraints, and with podAffinity",
|
||||||
pod: makePod().name("p").label("foo", "").
|
pod: st.MakePod().Name("p").Label("foo", "").
|
||||||
nodeAffinityNotIn("node", []string{"node-x"}). // exclude node-x
|
NodeAffinityNotIn("node", []string{"node-x"}). // exclude node-x
|
||||||
spreadConstraint(1, "zone", hardSpread, makeLabelSelector().exists("foo").obj()).
|
SpreadConstraint(1, "zone", hardSpread, st.MakeLabelSelector().Exists("foo").Obj()).
|
||||||
spreadConstraint(1, "node", hardSpread, makeLabelSelector().exists("foo").obj()).
|
SpreadConstraint(1, "node", hardSpread, st.MakeLabelSelector().Exists("foo").Obj()).
|
||||||
obj(),
|
Obj(),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
makeNode().name("node-a").label("zone", "zone1").label("node", "node-a").obj(),
|
st.MakeNode().Name("node-a").Label("zone", "zone1").Label("node", "node-a").Obj(),
|
||||||
makeNode().name("node-b").label("zone", "zone1").label("node", "node-b").obj(),
|
st.MakeNode().Name("node-b").Label("zone", "zone1").Label("node", "node-b").Obj(),
|
||||||
makeNode().name("node-x").label("zone", "zone2").label("node", "node-x").obj(),
|
st.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-y").Label("zone", "zone2").Label("node", "node-y").Obj(),
|
||||||
},
|
},
|
||||||
existingPods: []*v1.Pod{
|
existingPods: []*v1.Pod{
|
||||||
makePod().name("p-a1").node("node-a").label("foo", "").obj(),
|
st.MakePod().Name("p-a1").Node("node-a").Label("foo", "").Obj(),
|
||||||
makePod().name("p-a2").node("node-a").label("foo", "").obj(),
|
st.MakePod().Name("p-a2").Node("node-a").Label("foo", "").Obj(),
|
||||||
makePod().name("p-b1").node("node-b").label("foo", "").obj(),
|
st.MakePod().Name("p-b1").Node("node-b").Label("foo", "").Obj(),
|
||||||
makePod().name("p-y1").node("node-y").label("foo", "").obj(),
|
st.MakePod().Name("p-y1").Node("node-y").Label("foo", "").Obj(),
|
||||||
makePod().name("p-y2").node("node-y").label("foo", "").obj(),
|
st.MakePod().Name("p-y2").Node("node-y").Label("foo", "").Obj(),
|
||||||
makePod().name("p-y3").node("node-y").label("foo", "").obj(),
|
st.MakePod().Name("p-y3").Node("node-y").Label("foo", "").Obj(),
|
||||||
makePod().name("p-y4").node("node-y").label("foo", "").obj(),
|
st.MakePod().Name("p-y4").Node("node-y").Label("foo", "").Obj(),
|
||||||
},
|
},
|
||||||
injectPodPointers: map[topologyPair][]int{
|
injectPodPointers: map[topologyPair][]int{
|
||||||
{key: "zone", value: "zone1"}: {0, 1, 2},
|
{key: "zone", value: "zone1"}: {0, 1, 2},
|
||||||
|
@ -21,7 +21,6 @@ import (
|
|||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
storagev1beta1 "k8s.io/api/storage/v1beta1"
|
storagev1beta1 "k8s.io/api/storage/v1beta1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
@ -148,193 +147,3 @@ func isCSIMigrationOn(csiNode *storagev1beta1.CSINode, pluginName string) bool {
|
|||||||
|
|
||||||
return mpaSet.Has(pluginName)
|
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
|
|
||||||
}
|
|
||||||
|
243
pkg/scheduler/testing/utils.go
Normal file
243
pkg/scheduler/testing/utils.go
Normal file
@ -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
|
||||||
|
}
|
@ -21,7 +21,7 @@ import (
|
|||||||
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
"k8s.io/kubernetes/pkg/apis/scheduling"
|
"k8s.io/kubernetes/pkg/apis/scheduling"
|
||||||
|
Loading…
Reference in New Issue
Block a user