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 <yibzhuang@gmail.com>
This commit is contained in:
parent
fd08d47d8b
commit
bc8f3198d5
@ -28,12 +28,11 @@ import (
|
|||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
clienttesting "k8s.io/client-go/testing"
|
clienttesting "k8s.io/client-go/testing"
|
||||||
frameworkruntime "k8s.io/kubernetes/pkg/scheduler/framework/runtime"
|
frameworkruntime "k8s.io/kubernetes/pkg/scheduler/framework/runtime"
|
||||||
|
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDefaultBinder(t *testing.T) {
|
func TestDefaultBinder(t *testing.T) {
|
||||||
testPod := &v1.Pod{
|
testPod := st.MakePod().Name("foo").Namespace("ns").Obj()
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "ns"},
|
|
||||||
}
|
|
||||||
testNode := "foohost.kubernetes.mydomain.com"
|
testNode := "foohost.kubernetes.mydomain.com"
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/client-go/informers"
|
"k8s.io/client-go/informers"
|
||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
|
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetPodServices(t *testing.T) {
|
func TestGetPodServices(t *testing.T) {
|
||||||
@ -48,16 +49,11 @@ func TestGetPodServices(t *testing.T) {
|
|||||||
}
|
}
|
||||||
var pods []*v1.Pod
|
var pods []*v1.Pod
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
pod := &v1.Pod{
|
pod := st.MakePod().Name(fmt.Sprintf("test-pod-%d", i)).
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
Namespace("test").
|
||||||
Namespace: "test",
|
Label("app", fmt.Sprintf("test-%d", i)).
|
||||||
Name: fmt.Sprintf("test-pod-%d", i),
|
Label("label", fmt.Sprintf("label-%d", i)).
|
||||||
Labels: map[string]string{
|
Obj()
|
||||||
"app": fmt.Sprintf("test-%d", i),
|
|
||||||
"label": fmt.Sprintf("label-%d", i),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
pods = append(pods, pod)
|
pods = append(pods, pod)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,8 +240,8 @@ func TestImageLocalityPriority(t *testing.T) {
|
|||||||
// Image: gcr.io/250:latest 250MB
|
// Image: gcr.io/250:latest 250MB
|
||||||
// Score: 100 * (250M/2 - 23M)/(1000M * 2 - 23M) = 5
|
// Score: 100 * (250M/2 - 23M)/(1000M * 2 - 23M) = 5
|
||||||
pod: &v1.Pod{Spec: test40250},
|
pod: &v1.Pod{Spec: test40250},
|
||||||
nodes: []*v1.Node{makeImageNode("machine1", node403002000), makeImageNode("machine2", node25010)},
|
nodes: []*v1.Node{makeImageNode("node1", node403002000), makeImageNode("node2", node25010)},
|
||||||
expectedList: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 5}},
|
expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 5}},
|
||||||
name: "two images spread on two nodes, prefer the larger image one",
|
name: "two images spread on two nodes, prefer the larger image one",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -255,8 +255,8 @@ func TestImageLocalityPriority(t *testing.T) {
|
|||||||
// Image: not present
|
// Image: not present
|
||||||
// Score: 0
|
// Score: 0
|
||||||
pod: &v1.Pod{Spec: test40300},
|
pod: &v1.Pod{Spec: test40300},
|
||||||
nodes: []*v1.Node{makeImageNode("machine1", node403002000), makeImageNode("machine2", node25010)},
|
nodes: []*v1.Node{makeImageNode("node1", node403002000), makeImageNode("node2", node25010)},
|
||||||
expectedList: []framework.NodeScore{{Name: "machine1", Score: 7}, {Name: "machine2", Score: 0}},
|
expectedList: []framework.NodeScore{{Name: "node1", Score: 7}, {Name: "node2", Score: 0}},
|
||||||
name: "two images on one node, prefer this node",
|
name: "two images on one node, prefer this node",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -270,8 +270,8 @@ func TestImageLocalityPriority(t *testing.T) {
|
|||||||
// Image: gcr.io/10:latest 10MB
|
// Image: gcr.io/10:latest 10MB
|
||||||
// Score: 0 (10M/2 < 23M, min-threshold)
|
// Score: 0 (10M/2 < 23M, min-threshold)
|
||||||
pod: &v1.Pod{Spec: testMinMax},
|
pod: &v1.Pod{Spec: testMinMax},
|
||||||
nodes: []*v1.Node{makeImageNode("machine1", node400030), makeImageNode("machine2", node25010)},
|
nodes: []*v1.Node{makeImageNode("node1", node400030), makeImageNode("node2", node25010)},
|
||||||
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: "if exceed limit, use limit",
|
name: "if exceed limit, use limit",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -289,8 +289,8 @@ func TestImageLocalityPriority(t *testing.T) {
|
|||||||
// Image:
|
// Image:
|
||||||
// Score: 0
|
// Score: 0
|
||||||
pod: &v1.Pod{Spec: testMinMax},
|
pod: &v1.Pod{Spec: testMinMax},
|
||||||
nodes: []*v1.Node{makeImageNode("machine1", node400030), makeImageNode("machine2", node25010), makeImageNode("machine3", nodeWithNoImages)},
|
nodes: []*v1.Node{makeImageNode("node1", node400030), makeImageNode("node2", node25010), makeImageNode("node3", nodeWithNoImages)},
|
||||||
expectedList: []framework.NodeScore{{Name: "machine1", Score: 66}, {Name: "machine2", Score: 0}, {Name: "machine3", Score: 0}},
|
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)",
|
name: "if exceed limit, use limit (with node which has no images present)",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -308,9 +308,9 @@ func TestImageLocalityPriority(t *testing.T) {
|
|||||||
// Image:
|
// Image:
|
||||||
// Score: 0
|
// Score: 0
|
||||||
pod: &v1.Pod{Spec: test300600900},
|
pod: &v1.Pod{Spec: test300600900},
|
||||||
nodes: []*v1.Node{makeImageNode("machine1", node60040900), makeImageNode("machine2", node300600900), makeImageNode("machine3", nodeWithNoImages)},
|
nodes: []*v1.Node{makeImageNode("node1", node60040900), makeImageNode("node2", node300600900), makeImageNode("node3", nodeWithNoImages)},
|
||||||
expectedList: []framework.NodeScore{{Name: "machine1", Score: 32}, {Name: "machine2", Score: 36}, {Name: "machine3", Score: 0}},
|
expectedList: []framework.NodeScore{{Name: "node1", Score: 32}, {Name: "node2", Score: 36}, {Name: "node3", Score: 0}},
|
||||||
name: "pod with multiple large images, machine2 is preferred",
|
name: "pod with multiple large images, node2 is preferred",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Pod: gcr.io/30 gcr.io/40
|
// Pod: gcr.io/30 gcr.io/40
|
||||||
@ -323,8 +323,8 @@ func TestImageLocalityPriority(t *testing.T) {
|
|||||||
// Image: 100 * (30M - 23M) / (1000M * 2 - 23M) = 0
|
// Image: 100 * (30M - 23M) / (1000M * 2 - 23M) = 0
|
||||||
// Score: 0
|
// Score: 0
|
||||||
pod: &v1.Pod{Spec: test3040},
|
pod: &v1.Pod{Spec: test3040},
|
||||||
nodes: []*v1.Node{makeImageNode("machine1", node203040), makeImageNode("machine2", node400030)},
|
nodes: []*v1.Node{makeImageNode("node1", node203040), makeImageNode("node2", node400030)},
|
||||||
expectedList: []framework.NodeScore{{Name: "machine1", Score: 1}, {Name: "machine2", Score: 0}},
|
expectedList: []framework.NodeScore{{Name: "node1", Score: 1}, {Name: "node2", Score: 0}},
|
||||||
name: "pod with multiple small images",
|
name: "pod with multiple small images",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||||
@ -377,52 +377,52 @@ func TestPreferredAffinity(t *testing.T) {
|
|||||||
wantStatus *framework.Status
|
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}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}},
|
{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(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(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(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(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(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" +
|
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",
|
"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}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: stayWithS1InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
{Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}},
|
{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 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(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 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(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 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.
|
// 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",
|
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}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: stayWithS1InRegion}},
|
||||||
pods: []*v1.Pod{
|
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{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgChinaAzAz1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgChinaAzAz1}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelRgIndia}},
|
{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.
|
// 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),
|
// 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).
|
// 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",
|
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}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: stayWithS2InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
{Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
{Spec: v1.PodSpec{NodeName: "node3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine4"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
{Spec: v1.PodSpec{NodeName: "node4"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine5"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
{Spec: v1.PodSpec{NodeName: "node5"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine4", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node4", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine5", Labels: labelRgIndia}},
|
{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.
|
// 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 ",
|
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}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: affinity3}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
{Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}},
|
{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,
|
// 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.
|
// 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",
|
name: "Affinity symmetry: considered only the preferredDuringSchedulingIgnoredDuringExecution in pod affinity symmetry",
|
||||||
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1", Affinity: stayWithS1InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1", Affinity: stayWithS1InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2", Affinity: stayWithS2InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
{Spec: v1.PodSpec{NodeName: "node2", Affinity: stayWithS2InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}},
|
{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",
|
name: "Affinity symmetry with namespace selector",
|
||||||
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1", Affinity: affinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1", Affinity: affinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2", Affinity: stayWithS2InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
{Spec: v1.PodSpec{NodeName: "node2", Affinity: stayWithS2InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}},
|
{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",
|
name: "AntiAffinity symmetry with namespace selector",
|
||||||
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1", Affinity: antiAffinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1", Affinity: antiAffinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2", Affinity: stayWithS2InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
{Spec: v1.PodSpec{NodeName: "node2", Affinity: stayWithS2InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}},
|
{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",
|
name: "Affinity symmetry: considered RequiredDuringSchedulingIgnoredDuringExecution in pod affinity symmetry",
|
||||||
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1", Affinity: hardAffinity}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1", Affinity: hardAffinity}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2", Affinity: hardAffinity}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
{Spec: v1.PodSpec{NodeName: "node2", Affinity: hardAffinity}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}},
|
{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.
|
// 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 ",
|
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}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: awayFromS1InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
{Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelAzAz1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelAzAz1}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgChina}},
|
{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 ",
|
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}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: awayFromS1InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelAzAz1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelAzAz1}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgChina}},
|
{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",
|
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}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: awayFromS1InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
{Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelAzAz1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelAzAz1}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{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
|
// 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",
|
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}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1", Affinity: awayFromS2InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1", Affinity: awayFromS2InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2", Affinity: awayFromS1InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
{Spec: v1.PodSpec{NodeName: "node2", Affinity: awayFromS1InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelAzAz1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelAzAz1}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelAzAz2}},
|
{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
|
// Test both affinity and anti-affinity
|
||||||
{
|
{
|
||||||
name: "Affinity and Anti Affinity: considered only preferredDuringSchedulingIgnoredDuringExecution in both pod affinity & 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}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: stayWithS1InRegionAwayFromS2InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelAzAz1}},
|
{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),
|
// 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,
|
// 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
|
// 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",
|
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}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: stayWithS1InRegionAwayFromS2InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node3"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine4"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node4"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine5"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node5"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChinaAzAz1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChinaAzAz1}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine4", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node4", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine5", Labels: labelRgIndia}},
|
{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.
|
// Consider Affinity, Anti Affinity and symmetry together.
|
||||||
// for Affinity, the weights are: 8, 0, 0, 0
|
// 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",
|
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}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: stayWithS1InRegionAwayFromS2InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
{Spec: v1.PodSpec{NodeName: "node2"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine3", Affinity: stayWithS1InRegionAwayFromS2InAz}},
|
{Spec: v1.PodSpec{NodeName: "node3", Affinity: stayWithS1InRegionAwayFromS2InAz}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine4", Affinity: awayFromS1InAz}},
|
{Spec: v1.PodSpec{NodeName: "node4", Affinity: awayFromS1InAz}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelAzAz1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelAzAz1}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelRgIndia}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelRgIndia}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine4", Labels: labelAzAz2}},
|
{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:
|
// 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.
|
// 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",
|
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}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1"}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2", Affinity: stayWithS1InRegionAwayFromS2InAz}},
|
{Spec: v1.PodSpec{NodeName: "node2", Affinity: stayWithS1InRegionAwayFromS2InAz}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", 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",
|
name: "invalid Affinity fails PreScore",
|
||||||
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: invalidAffinityLabels}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: invalidAffinityLabels}},
|
||||||
wantStatus: framework.NewStatus(framework.Error, `Invalid value: "{{.bad-value.}}"`),
|
wantStatus: framework.NewStatus(framework.Error, `Invalid value: "{{.bad-value.}}"`),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", 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}},
|
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: "", Affinity: invalidAntiAffinityLabels}},
|
||||||
wantStatus: framework.NewStatus(framework.Error, `Invalid value: "{{.bad-value.}}"`),
|
wantStatus: framework.NewStatus(framework.Error, `Invalid value: "{{.bad-value.}}"`),
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgChina}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Affinity with pods matching NamespaceSelector",
|
name: "Affinity with pods matching NamespaceSelector",
|
||||||
pod: &v1.Pod{Spec: v1.PodSpec{Affinity: affinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}},
|
pod: &v1.Pod{Spec: v1.PodSpec{Affinity: affinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1"}, 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: "machine1"}, 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: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team2", Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1"}, 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: "node2"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team1", Labels: podLabelSecurityS1}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{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",
|
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}},
|
pod: &v1.Pod{Spec: v1.PodSpec{Affinity: affinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1"}, 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: "machine1"}, 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: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team2", Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1"}, 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: "node2"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team1", Labels: podLabelSecurityS1}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{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",
|
name: "Affinity with pods matching NamespaceSelector",
|
||||||
pod: &v1.Pod{Spec: v1.PodSpec{Affinity: antiAffinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}},
|
pod: &v1.Pod{Spec: v1.PodSpec{Affinity: antiAffinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1"}, 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: "machine1"}, 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: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team2", Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1"}, 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: "node2"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team1", Labels: podLabelSecurityS1}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{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",
|
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}},
|
pod: &v1.Pod{Spec: v1.PodSpec{Affinity: antiAffinityNamespaceSelector}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelSecurityS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1"}, 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: "machine1"}, 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: "machine1"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team2", Labels: podLabelSecurityS1}},
|
{Spec: v1.PodSpec{NodeName: "node1"}, 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: "node2"}, ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team1", Labels: podLabelSecurityS1}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{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 {
|
for _, test := range tests {
|
||||||
@ -826,76 +826,76 @@ func TestPreferredAffinityWithHardPodAffinitySymmetricWeight(t *testing.T) {
|
|||||||
name: "with default weight",
|
name: "with default weight",
|
||||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: podLabelServiceS1}},
|
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: podLabelServiceS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1", Affinity: hardPodAffinity}},
|
{Spec: v1.PodSpec{NodeName: "node1", Affinity: hardPodAffinity}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2", Affinity: hardPodAffinity}},
|
{Spec: v1.PodSpec{NodeName: "node2", Affinity: hardPodAffinity}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelAzAz1}},
|
||||||
},
|
},
|
||||||
hardPodAffinityWeight: v1.DefaultHardPodAffinitySymmetricWeight,
|
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",
|
name: "with zero weight",
|
||||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: podLabelServiceS1}},
|
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: podLabelServiceS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1", Affinity: hardPodAffinity}},
|
{Spec: v1.PodSpec{NodeName: "node1", Affinity: hardPodAffinity}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2", Affinity: hardPodAffinity}},
|
{Spec: v1.PodSpec{NodeName: "node2", Affinity: hardPodAffinity}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelAzAz1}},
|
||||||
},
|
},
|
||||||
hardPodAffinityWeight: 0,
|
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",
|
name: "with no matching namespace",
|
||||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team2", Labels: podLabelServiceS1}},
|
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team2", Labels: podLabelServiceS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1", Affinity: hardPodAffinity}},
|
{Spec: v1.PodSpec{NodeName: "node1", Affinity: hardPodAffinity}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2", Affinity: hardPodAffinity}},
|
{Spec: v1.PodSpec{NodeName: "node2", Affinity: hardPodAffinity}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelAzAz1}},
|
||||||
},
|
},
|
||||||
hardPodAffinityWeight: v1.DefaultHardPodAffinitySymmetricWeight,
|
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",
|
name: "with matching NamespaceSelector",
|
||||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelServiceS1}},
|
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "subteam1.team1", Labels: podLabelServiceS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1", Affinity: hardPodAffinity}},
|
{Spec: v1.PodSpec{NodeName: "node1", Affinity: hardPodAffinity}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2", Affinity: hardPodAffinity}},
|
{Spec: v1.PodSpec{NodeName: "node2", Affinity: hardPodAffinity}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelAzAz1}},
|
||||||
},
|
},
|
||||||
hardPodAffinityWeight: v1.DefaultHardPodAffinitySymmetricWeight,
|
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",
|
name: "with matching Namespaces",
|
||||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team2", Labels: podLabelServiceS1}},
|
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "subteam2.team2", Labels: podLabelServiceS1}},
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: v1.PodSpec{NodeName: "machine1", Affinity: hardPodAffinity}},
|
{Spec: v1.PodSpec{NodeName: "node1", Affinity: hardPodAffinity}},
|
||||||
{Spec: v1.PodSpec{NodeName: "machine2", Affinity: hardPodAffinity}},
|
{Spec: v1.PodSpec{NodeName: "node2", Affinity: hardPodAffinity}},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: labelRgChina}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: labelRgIndia}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: labelAzAz1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node3", Labels: labelAzAz1}},
|
||||||
},
|
},
|
||||||
hardPodAffinityWeight: v1.DefaultHardPodAffinitySymmetricWeight,
|
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 {
|
for _, test := range tests {
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/scheduler/framework"
|
"k8s.io/kubernetes/pkg/scheduler/framework"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework/runtime"
|
"k8s.io/kubernetes/pkg/scheduler/framework/runtime"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/internal/cache"
|
"k8s.io/kubernetes/pkg/scheduler/internal/cache"
|
||||||
|
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Add test case for RequiredDuringSchedulingRequiredDuringExecution after it's implemented.
|
// TODO: Add test case for RequiredDuringSchedulingRequiredDuringExecution after it's implemented.
|
||||||
@ -49,37 +50,25 @@ func TestNodeAffinity(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing labels",
|
name: "missing labels",
|
||||||
pod: &v1.Pod{
|
pod: st.MakePod().NodeSelector(map[string]string{
|
||||||
Spec: v1.PodSpec{
|
"foo": "bar",
|
||||||
NodeSelector: map[string]string{
|
}).Obj(),
|
||||||
"foo": "bar",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
wantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReasonPod),
|
wantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReasonPod),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "same labels",
|
name: "same labels",
|
||||||
pod: &v1.Pod{
|
pod: st.MakePod().NodeSelector(map[string]string{
|
||||||
Spec: v1.PodSpec{
|
"foo": "bar",
|
||||||
NodeSelector: map[string]string{
|
}).Obj(),
|
||||||
"foo": "bar",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
labels: map[string]string{
|
labels: map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "node labels are superset",
|
name: "node labels are superset",
|
||||||
pod: &v1.Pod{
|
pod: st.MakePod().NodeSelector(map[string]string{
|
||||||
Spec: v1.PodSpec{
|
"foo": "bar",
|
||||||
NodeSelector: map[string]string{
|
}).Obj(),
|
||||||
"foo": "bar",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
labels: map[string]string{
|
labels: map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
"baz": "blah",
|
"baz": "blah",
|
||||||
@ -87,14 +76,10 @@ func TestNodeAffinity(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "node labels are subset",
|
name: "node labels are subset",
|
||||||
pod: &v1.Pod{
|
pod: st.MakePod().NodeSelector(map[string]string{
|
||||||
Spec: v1.PodSpec{
|
"foo": "bar",
|
||||||
NodeSelector: map[string]string{
|
"baz": "blah",
|
||||||
"foo": "bar",
|
}).Obj(),
|
||||||
"baz": "blah",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
labels: map[string]string{
|
labels: map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
},
|
},
|
||||||
@ -1029,69 +1014,69 @@ func TestNodeAffinityPriority(t *testing.T) {
|
|||||||
disablePreScore bool
|
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{
|
pod: &v1.Pod{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Annotations: map[string]string{},
|
Annotations: map[string]string{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: label1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: label1}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: label2}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: label2}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: label3}},
|
{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{
|
pod: &v1.Pod{
|
||||||
Spec: v1.PodSpec{
|
Spec: v1.PodSpec{
|
||||||
Affinity: affinity1,
|
Affinity: affinity1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: label4}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: label4}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: label2}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: label2}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: label3}},
|
{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{
|
pod: &v1.Pod{
|
||||||
Spec: v1.PodSpec{
|
Spec: v1.PodSpec{
|
||||||
Affinity: affinity1,
|
Affinity: affinity1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: label1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: label1}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: label2}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: label2}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: label3}},
|
{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{
|
pod: &v1.Pod{
|
||||||
Spec: v1.PodSpec{
|
Spec: v1.PodSpec{
|
||||||
Affinity: affinity2,
|
Affinity: affinity2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: label1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: label1}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine5", Labels: label5}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node5", Labels: label5}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: label2}},
|
{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",
|
name: "added affinity",
|
||||||
pod: &v1.Pod{},
|
pod: &v1.Pod{},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: label1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: label1}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: label2}},
|
{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{
|
args: config.NodeAffinityArgs{
|
||||||
AddedAffinity: affinity1.NodeAffinity,
|
AddedAffinity: affinity1.NodeAffinity,
|
||||||
},
|
},
|
||||||
@ -1104,11 +1089,11 @@ func TestNodeAffinityPriority(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: label1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: label1}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: label2}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: label2}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine3", Labels: label5}},
|
{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{
|
args: config.NodeAffinityArgs{
|
||||||
AddedAffinity: &v1.NodeAffinity{
|
AddedAffinity: &v1.NodeAffinity{
|
||||||
PreferredDuringSchedulingIgnoredDuringExecution: []v1.PreferredSchedulingTerm{
|
PreferredDuringSchedulingIgnoredDuringExecution: []v1.PreferredSchedulingTerm{
|
||||||
@ -1136,11 +1121,11 @@ func TestNodeAffinityPriority(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
nodes: []*v1.Node{
|
nodes: []*v1.Node{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine1", Labels: label1}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: label1}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine5", Labels: label5}},
|
{ObjectMeta: metav1.ObjectMeta{Name: "node5", Labels: label5}},
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "machine2", Labels: label2}},
|
{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,
|
disablePreScore: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework"
|
"k8s.io/kubernetes/pkg/scheduler/framework"
|
||||||
|
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNodeName(t *testing.T) {
|
func TestNodeName(t *testing.T) {
|
||||||
@ -39,29 +39,13 @@ func TestNodeName(t *testing.T) {
|
|||||||
name: "no host specified",
|
name: "no host specified",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pod: &v1.Pod{
|
pod: st.MakePod().Node("foo").Obj(),
|
||||||
Spec: v1.PodSpec{
|
node: st.MakeNode().Name("foo").Obj(),
|
||||||
NodeName: "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
node: &v1.Node{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
name: "host matches",
|
name: "host matches",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pod: &v1.Pod{
|
pod: st.MakePod().Node("bar").Obj(),
|
||||||
Spec: v1.PodSpec{
|
node: st.MakeNode().Name("foo").Obj(),
|
||||||
NodeName: "bar",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
node: &v1.Node{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
name: "host doesn't match",
|
name: "host doesn't match",
|
||||||
wantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReason),
|
wantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReason),
|
||||||
},
|
},
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/diff"
|
"k8s.io/apimachinery/pkg/util/diff"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework"
|
"k8s.io/kubernetes/pkg/scheduler/framework"
|
||||||
|
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newPod(host string, hostPortInfos ...string) *v1.Pod {
|
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]),
|
Protocol: v1.Protocol(splited[0]),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return &v1.Pod{
|
return st.MakePod().Node(host).ContainerPort(networkPorts).Obj()
|
||||||
Spec: v1.PodSpec{
|
|
||||||
NodeName: host,
|
|
||||||
Containers: []v1.Container{
|
|
||||||
{
|
|
||||||
Ports: networkPorts,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNodePorts(t *testing.T) {
|
func TestNodePorts(t *testing.T) {
|
||||||
@ -184,66 +176,42 @@ func TestGetContainerPorts(t *testing.T) {
|
|||||||
expected []*v1.ContainerPort
|
expected []*v1.ContainerPort
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
pod1: &v1.Pod{
|
pod1: st.MakePod().ContainerPort([]v1.ContainerPort{
|
||||||
Spec: v1.PodSpec{
|
{
|
||||||
Containers: []v1.Container{
|
ContainerPort: 8001,
|
||||||
{
|
Protocol: v1.ProtocolTCP,
|
||||||
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,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
pod2: &v1.Pod{
|
ContainerPort: 8002,
|
||||||
Spec: v1.PodSpec{
|
Protocol: v1.ProtocolTCP,
|
||||||
Containers: []v1.Container{
|
}}).ContainerPort([]v1.ContainerPort{
|
||||||
{
|
{
|
||||||
Ports: []v1.ContainerPort{
|
ContainerPort: 8003,
|
||||||
{
|
Protocol: v1.ProtocolTCP,
|
||||||
ContainerPort: 8011,
|
|
||||||
Protocol: v1.ProtocolTCP,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ContainerPort: 8012,
|
|
||||||
Protocol: v1.ProtocolTCP,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Ports: []v1.ContainerPort{
|
|
||||||
{
|
|
||||||
ContainerPort: 8013,
|
|
||||||
Protocol: v1.ProtocolTCP,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ContainerPort: 8014,
|
|
||||||
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{
|
expected: []*v1.ContainerPort{
|
||||||
{
|
{
|
||||||
ContainerPort: 8001,
|
ContainerPort: 8001,
|
||||||
|
@ -29,6 +29,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature"
|
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework/runtime"
|
"k8s.io/kubernetes/pkg/scheduler/framework/runtime"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/internal/cache"
|
"k8s.io/kubernetes/pkg/scheduler/internal/cache"
|
||||||
|
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNodeResourcesBalancedAllocation(t *testing.T) {
|
func TestNodeResourcesBalancedAllocation(t *testing.T) {
|
||||||
@ -52,7 +53,7 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
NodeName: "machine1",
|
NodeName: "node1",
|
||||||
}
|
}
|
||||||
labels1 := map[string]string{
|
labels1 := map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
@ -62,17 +63,8 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) {
|
|||||||
"bar": "foo",
|
"bar": "foo",
|
||||||
"baz": "blah",
|
"baz": "blah",
|
||||||
}
|
}
|
||||||
machine1Spec := v1.PodSpec{
|
|
||||||
NodeName: "machine1",
|
|
||||||
}
|
|
||||||
machine2Spec := v1.PodSpec{
|
|
||||||
NodeName: "machine2",
|
|
||||||
}
|
|
||||||
noResources := v1.PodSpec{
|
|
||||||
Containers: []v1.Container{},
|
|
||||||
}
|
|
||||||
cpuOnly := v1.PodSpec{
|
cpuOnly := v1.PodSpec{
|
||||||
NodeName: "machine1",
|
NodeName: "node1",
|
||||||
Containers: []v1.Container{
|
Containers: []v1.Container{
|
||||||
{
|
{
|
||||||
Resources: v1.ResourceRequirements{
|
Resources: v1.ResourceRequirements{
|
||||||
@ -93,9 +85,9 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
cpuOnly2 := cpuOnly
|
cpuOnly2 := cpuOnly
|
||||||
cpuOnly2.NodeName = "machine2"
|
cpuOnly2.NodeName = "node2"
|
||||||
cpuAndMemory := v1.PodSpec{
|
cpuAndMemory := v1.PodSpec{
|
||||||
NodeName: "machine2",
|
NodeName: "node2",
|
||||||
Containers: []v1.Container{
|
Containers: []v1.Container{
|
||||||
{
|
{
|
||||||
Resources: v1.ResourceRequirements{
|
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{
|
defaultResourceBalancedAllocationSet := []config.ResourceSpec{
|
||||||
{Name: string(v1.ResourceCPU), Weight: 1},
|
{Name: string(v1.ResourceCPU), Weight: 1},
|
||||||
@ -148,9 +133,9 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) {
|
|||||||
// CPU Fraction: 0 / 4000 = 0 %
|
// CPU Fraction: 0 / 4000 = 0 %
|
||||||
// Memory Fraction: 0 / 10000 = 0%
|
// Memory Fraction: 0 / 10000 = 0%
|
||||||
// Node2 Score: (1-0) * MaxNodeScore = MaxNodeScore
|
// Node2 Score: (1-0) * MaxNodeScore = MaxNodeScore
|
||||||
pod: &v1.Pod{Spec: noResources},
|
pod: st.MakePod().Obj(),
|
||||||
nodes: []*v1.Node{makeNode("machine1", 4000, 10000, nil), makeNode("machine2", 4000, 10000, nil)},
|
nodes: []*v1.Node{makeNode("node1", 4000, 10000, nil), makeNode("node2", 4000, 10000, nil)},
|
||||||
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: "nothing scheduled, nothing requested",
|
name: "nothing scheduled, nothing requested",
|
||||||
args: config.NodeResourcesBalancedAllocationArgs{Resources: defaultResourceBalancedAllocationSet},
|
args: config.NodeResourcesBalancedAllocationArgs{Resources: defaultResourceBalancedAllocationSet},
|
||||||
},
|
},
|
||||||
@ -166,9 +151,9 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) {
|
|||||||
// Node2 std: 0
|
// Node2 std: 0
|
||||||
// Node2 Score: (1-0) * MaxNodeScore = MaxNodeScore
|
// Node2 Score: (1-0) * MaxNodeScore = MaxNodeScore
|
||||||
pod: &v1.Pod{Spec: cpuAndMemory},
|
pod: &v1.Pod{Spec: cpuAndMemory},
|
||||||
nodes: []*v1.Node{makeNode("machine1", 4000, 10000, nil), makeNode("machine2", 6000, 10000, nil)},
|
nodes: []*v1.Node{makeNode("node1", 4000, 10000, nil), makeNode("node2", 6000, 10000, nil)},
|
||||||
expectedList: []framework.NodeScore{{Name: "machine1", Score: 87}, {Name: "machine2", Score: framework.MaxNodeScore}},
|
expectedList: []framework.NodeScore{{Name: "node1", Score: 87}, {Name: "node2", Score: framework.MaxNodeScore}},
|
||||||
name: "nothing scheduled, resources requested, differently sized machines",
|
name: "nothing scheduled, resources requested, differently sized nodes",
|
||||||
args: config.NodeResourcesBalancedAllocationArgs{Resources: defaultResourceBalancedAllocationSet},
|
args: config.NodeResourcesBalancedAllocationArgs{Resources: defaultResourceBalancedAllocationSet},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -182,15 +167,15 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) {
|
|||||||
// Memory Fraction: 0 / 10000 = 0%
|
// Memory Fraction: 0 / 10000 = 0%
|
||||||
// Node2 std: 0
|
// Node2 std: 0
|
||||||
// Node2 Score: (1-0) * MaxNodeScore = MaxNodeScore
|
// Node2 Score: (1-0) * MaxNodeScore = MaxNodeScore
|
||||||
pod: &v1.Pod{Spec: noResources},
|
pod: st.MakePod().Obj(),
|
||||||
nodes: []*v1.Node{makeNode("machine1", 4000, 10000, nil), makeNode("machine2", 4000, 10000, nil)},
|
nodes: []*v1.Node{makeNode("node1", 4000, 10000, nil), makeNode("node2", 4000, 10000, nil)},
|
||||||
expectedList: []framework.NodeScore{{Name: "machine1", Score: framework.MaxNodeScore}, {Name: "machine2", Score: framework.MaxNodeScore}},
|
expectedList: []framework.NodeScore{{Name: "node2", Score: framework.MaxNodeScore}, {Name: "node2", Score: framework.MaxNodeScore}},
|
||||||
name: "no resources requested, pods without container scheduled",
|
name: "no resources requested, pods without container scheduled",
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: machine1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}},
|
st.MakePod().Node("node1").Labels(labels2).Obj(),
|
||||||
{Spec: machine1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
st.MakePod().Node("node1").Labels(labels1).Obj(),
|
||||||
{Spec: machine2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
st.MakePod().Node("node2").Labels(labels1).Obj(),
|
||||||
{Spec: machine2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
st.MakePod().Node("node2").Labels(labels1).Obj(),
|
||||||
},
|
},
|
||||||
args: config.NodeResourcesBalancedAllocationArgs{Resources: defaultResourceBalancedAllocationSet},
|
args: config.NodeResourcesBalancedAllocationArgs{Resources: defaultResourceBalancedAllocationSet},
|
||||||
},
|
},
|
||||||
@ -205,13 +190,13 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) {
|
|||||||
// Memory Fraction: 0 / 1000 = 0%
|
// Memory Fraction: 0 / 1000 = 0%
|
||||||
// Node2 std: (0 - 0) / 2 = 0
|
// Node2 std: (0 - 0) / 2 = 0
|
||||||
// Node2 Score: (1 - 0)*MaxNodeScore = 100
|
// Node2 Score: (1 - 0)*MaxNodeScore = 100
|
||||||
pod: &v1.Pod{Spec: nonZeroContainer},
|
pod: st.MakePod().Obj(),
|
||||||
nodes: []*v1.Node{makeNode("machine1", 250, 1000*1024*1024, nil), makeNode("machine2", 250, 1000*1024*1024, nil)},
|
nodes: []*v1.Node{makeNode("node1", 250, 1000*1024*1024, nil), makeNode("node2", 250, 1000*1024*1024, nil)},
|
||||||
expectedList: []framework.NodeScore{{Name: "machine1", Score: 100}, {Name: "machine2", Score: 100}},
|
expectedList: []framework.NodeScore{{Name: "node1", Score: 100}, {Name: "node2", Score: 100}},
|
||||||
name: "no resources requested, pods with container scheduled",
|
name: "no resources requested, pods with container scheduled",
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: nonZeroContainer1},
|
st.MakePod().Node("node1").Obj(),
|
||||||
{Spec: nonZeroContainer1},
|
st.MakePod().Node("node1").Obj(),
|
||||||
},
|
},
|
||||||
args: config.NodeResourcesBalancedAllocationArgs{Resources: defaultResourceBalancedAllocationSet},
|
args: config.NodeResourcesBalancedAllocationArgs{Resources: defaultResourceBalancedAllocationSet},
|
||||||
},
|
},
|
||||||
@ -226,9 +211,9 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) {
|
|||||||
// Memory Fraction: 5000 / 20000 = 25%
|
// Memory Fraction: 5000 / 20000 = 25%
|
||||||
// Node2 std: (0.6 - 0.25) / 2 = 0.175
|
// Node2 std: (0.6 - 0.25) / 2 = 0.175
|
||||||
// Node2 Score: (1 - 0.175)*MaxNodeScore = 82
|
// Node2 Score: (1 - 0.175)*MaxNodeScore = 82
|
||||||
pod: &v1.Pod{Spec: noResources},
|
pod: st.MakePod().Obj(),
|
||||||
nodes: []*v1.Node{makeNode("machine1", 10000, 20000, nil), makeNode("machine2", 10000, 20000, nil)},
|
nodes: []*v1.Node{makeNode("node1", 10000, 20000, nil), makeNode("node2", 10000, 20000, nil)},
|
||||||
expectedList: []framework.NodeScore{{Name: "machine1", Score: 70}, {Name: "machine2", Score: 82}},
|
expectedList: []framework.NodeScore{{Name: "node1", Score: 70}, {Name: "node2", Score: 82}},
|
||||||
name: "no resources requested, pods scheduled with resources",
|
name: "no resources requested, pods scheduled with resources",
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: cpuOnly, ObjectMeta: metav1.ObjectMeta{Labels: labels2}},
|
{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 std: (0.6 - 0.5) / 2 = 0.05
|
||||||
// Node2 Score: (1 - 0.05)*MaxNodeScore = 95
|
// Node2 Score: (1 - 0.05)*MaxNodeScore = 95
|
||||||
pod: &v1.Pod{Spec: cpuAndMemory},
|
pod: &v1.Pod{Spec: cpuAndMemory},
|
||||||
nodes: []*v1.Node{makeNode("machine1", 10000, 20000, nil), makeNode("machine2", 10000, 20000, nil)},
|
nodes: []*v1.Node{makeNode("node1", 10000, 20000, nil), makeNode("node2", 10000, 20000, nil)},
|
||||||
expectedList: []framework.NodeScore{{Name: "machine1", Score: 82}, {Name: "machine2", Score: 95}},
|
expectedList: []framework.NodeScore{{Name: "node1", Score: 82}, {Name: "node2", Score: 95}},
|
||||||
name: "resources requested, pods scheduled with resources",
|
name: "resources requested, pods scheduled with resources",
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: cpuOnly},
|
{Spec: cpuOnly},
|
||||||
@ -271,9 +256,9 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) {
|
|||||||
// Node2 std: (0.6 - 0.2) / 2 = 0.2
|
// Node2 std: (0.6 - 0.2) / 2 = 0.2
|
||||||
// Node2 Score: (1 - 0.2)*MaxNodeScore = 80
|
// Node2 Score: (1 - 0.2)*MaxNodeScore = 80
|
||||||
pod: &v1.Pod{Spec: cpuAndMemory},
|
pod: &v1.Pod{Spec: cpuAndMemory},
|
||||||
nodes: []*v1.Node{makeNode("machine1", 10000, 20000, nil), makeNode("machine2", 10000, 50000, nil)},
|
nodes: []*v1.Node{makeNode("node1", 10000, 20000, nil), makeNode("node2", 10000, 50000, nil)},
|
||||||
expectedList: []framework.NodeScore{{Name: "machine1", Score: 82}, {Name: "machine2", Score: 80}},
|
expectedList: []framework.NodeScore{{Name: "node1", Score: 82}, {Name: "node2", Score: 80}},
|
||||||
name: "resources requested, pods scheduled with resources, differently sized machines",
|
name: "resources requested, pods scheduled with resources, differently sized nodes",
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: cpuOnly},
|
{Spec: cpuOnly},
|
||||||
{Spec: cpuAndMemory},
|
{Spec: cpuAndMemory},
|
||||||
@ -293,8 +278,8 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) {
|
|||||||
// Node2 std: (1 - 0.5) / 2 = 0.25
|
// Node2 std: (1 - 0.5) / 2 = 0.25
|
||||||
// Node2 Score: (1 - 0.25)*MaxNodeScore = 75
|
// Node2 Score: (1 - 0.25)*MaxNodeScore = 75
|
||||||
pod: &v1.Pod{Spec: cpuOnly},
|
pod: &v1.Pod{Spec: cpuOnly},
|
||||||
nodes: []*v1.Node{makeNode("machine1", 6000, 10000, nil), makeNode("machine2", 6000, 10000, nil)},
|
nodes: []*v1.Node{makeNode("node1", 6000, 10000, nil), makeNode("node2", 6000, 10000, nil)},
|
||||||
expectedList: []framework.NodeScore{{Name: "machine1", Score: 50}, {Name: "machine2", Score: 75}},
|
expectedList: []framework.NodeScore{{Name: "node1", Score: 50}, {Name: "node2", Score: 75}},
|
||||||
name: "requested resources at node capacity",
|
name: "requested resources at node capacity",
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: cpuOnly},
|
{Spec: cpuOnly},
|
||||||
@ -303,9 +288,9 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) {
|
|||||||
args: config.NodeResourcesBalancedAllocationArgs{Resources: defaultResourceBalancedAllocationSet},
|
args: config.NodeResourcesBalancedAllocationArgs{Resources: defaultResourceBalancedAllocationSet},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pod: &v1.Pod{Spec: noResources},
|
pod: st.MakePod().Obj(),
|
||||||
nodes: []*v1.Node{makeNode("machine1", 0, 0, nil), makeNode("machine2", 0, 0, nil)},
|
nodes: []*v1.Node{makeNode("node1", 0, 0, nil), makeNode("node2", 0, 0, nil)},
|
||||||
expectedList: []framework.NodeScore{{Name: "machine1", Score: 100}, {Name: "machine2", Score: 100}},
|
expectedList: []framework.NodeScore{{Name: "node1", Score: 100}, {Name: "node2", Score: 100}},
|
||||||
name: "zero node resources, pods scheduled with resources",
|
name: "zero node resources, pods scheduled with resources",
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: cpuOnly},
|
{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 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
|
// Node2 Score: (1 - 0.358)*MaxNodeScore = 65
|
||||||
{
|
{
|
||||||
pod: &v1.Pod{
|
pod: st.MakePod().Req(map[v1.ResourceName]string{
|
||||||
Spec: v1.PodSpec{
|
v1.ResourceMemory: "0",
|
||||||
Containers: []v1.Container{
|
"nvidia.com/gpu": "1",
|
||||||
{
|
}).Obj(),
|
||||||
Resources: v1.ResourceRequirements{
|
nodes: []*v1.Node{makeNode("node1", 3500, 40000, scalarResource), makeNode("node2", 3500, 40000, scalarResource)},
|
||||||
Requests: v1.ResourceList{
|
expectedList: []framework.NodeScore{{Name: "node1", Score: 70}, {Name: "node2", Score: 65}},
|
||||||
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}},
|
|
||||||
name: "include scalar resource on a node for balanced resource allocation",
|
name: "include scalar resource on a node for balanced resource allocation",
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: cpuAndMemory},
|
{Spec: cpuAndMemory},
|
||||||
@ -353,13 +328,13 @@ func TestNodeResourcesBalancedAllocation(t *testing.T) {
|
|||||||
{Name: "nvidia.com/gpu", Weight: 1},
|
{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
|
// Node1: std = 0, score = 100
|
||||||
// Node2: std = 0, score = 100
|
// Node2: std = 0, score = 100
|
||||||
{
|
{
|
||||||
pod: &v1.Pod{Spec: v1.PodSpec{Containers: []v1.Container{{}}}},
|
pod: st.MakePod().Obj(),
|
||||||
nodes: []*v1.Node{makeNode("machine1", 3500, 40000, scalarResource), makeNode("machine2", 3500, 40000, nil)},
|
nodes: []*v1.Node{makeNode("node1", 3500, 40000, scalarResource), makeNode("node2", 3500, 40000, nil)},
|
||||||
expectedList: []framework.NodeScore{{Name: "machine1", Score: 100}, {Name: "machine2", Score: 100}},
|
expectedList: []framework.NodeScore{{Name: "node1", Score: 100}, {Name: "node2", Score: 100}},
|
||||||
name: "node without the scalar resource results to a higher score",
|
name: "node without the scalar resource results to a higher score",
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: cpuOnly},
|
{Spec: cpuOnly},
|
||||||
|
@ -81,7 +81,7 @@ func TestLeastAllocatedScoringStrategy(t *testing.T) {
|
|||||||
// CPU Score: ((6000 - 3000) * MaxNodeScore) / 6000 = 50
|
// CPU Score: ((6000 - 3000) * MaxNodeScore) / 6000 = 50
|
||||||
// Memory Score: ((10000 - 5000) * MaxNodeScore) / 10000 = 50
|
// Memory Score: ((10000 - 5000) * MaxNodeScore) / 10000 = 50
|
||||||
// Node2 Score: (50 + 50) / 2 = 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().
|
requestedPod: st.MakePod().
|
||||||
Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}).
|
Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}).
|
||||||
Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}).
|
Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}).
|
||||||
@ -95,7 +95,7 @@ func TestLeastAllocatedScoringStrategy(t *testing.T) {
|
|||||||
resources: defaultResources,
|
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().
|
requestedPod: st.MakePod().
|
||||||
Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}).
|
Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}).
|
||||||
Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}).
|
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
|
// CPU Score: ((10000 - 6000) * MaxNodeScore) / 10000 = 40
|
||||||
// Memory Score: ((50000 - 10000) * MaxNodeScore) / 50000 = 80
|
// Memory Score: ((50000 - 10000) * MaxNodeScore) / 50000 = 80
|
||||||
// Node2 Score: (40 + 80) / 2 = 60
|
// 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().
|
requestedPod: st.MakePod().
|
||||||
Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}).
|
Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}).
|
||||||
Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}).
|
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
|
// CPU Score: ((6000 - 3000) *100) / 6000 = 50
|
||||||
// Memory Score: ((10000 - 5000) *100) / 10000 = 50
|
// Memory Score: ((10000 - 5000) *100) / 10000 = 50
|
||||||
// Node2 Score: (50 * 1 + 50 * 2) / (1 + 2) = 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").
|
requestedPod: st.MakePod().Node("node1").
|
||||||
Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}).
|
Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}).
|
||||||
Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}).
|
Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}).
|
||||||
|
@ -80,7 +80,7 @@ func TestMostAllocatedScoringStrategy(t *testing.T) {
|
|||||||
// CPU Score: (3000 * MaxNodeScore) / 6000 = 50
|
// CPU Score: (3000 * MaxNodeScore) / 6000 = 50
|
||||||
// Memory Score: (5000 * MaxNodeScore) / 10000 = 50
|
// Memory Score: (5000 * MaxNodeScore) / 10000 = 50
|
||||||
// Node2 Score: (50 + 50) / 2 = 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().
|
requestedPod: st.MakePod().
|
||||||
Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}).
|
Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}).
|
||||||
Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}).
|
Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}).
|
||||||
@ -94,7 +94,7 @@ func TestMostAllocatedScoringStrategy(t *testing.T) {
|
|||||||
resources: defaultResources,
|
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().
|
requestedPod: st.MakePod().
|
||||||
Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}).
|
Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}).
|
||||||
Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}).
|
Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}).
|
||||||
@ -185,7 +185,7 @@ func TestMostAllocatedScoringStrategy(t *testing.T) {
|
|||||||
// CPU Score: (3000 *100) / 6000 = 50
|
// CPU Score: (3000 *100) / 6000 = 50
|
||||||
// Memory Score: (5000 *100) / 10000 = 50
|
// Memory Score: (5000 *100) / 10000 = 50
|
||||||
// Node2 Score: (50 * 1 + 50 * 2) / (1 + 2) = 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().
|
requestedPod: st.MakePod().
|
||||||
Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}).
|
Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}).
|
||||||
Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}).
|
Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}).
|
||||||
|
@ -24,7 +24,6 @@ import (
|
|||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
|
||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework"
|
"k8s.io/kubernetes/pkg/scheduler/framework"
|
||||||
@ -73,7 +72,7 @@ func TestRequestedToCapacityRatioScoringStrategy(t *testing.T) {
|
|||||||
shape: shape,
|
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().
|
requestedPod: st.MakePod().
|
||||||
Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}).
|
Req(map[v1.ResourceName]string{"cpu": "1000", "memory": "2000"}).
|
||||||
Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}).
|
Req(map[v1.ResourceName]string{"cpu": "2000", "memory": "3000"}).
|
||||||
@ -213,38 +212,19 @@ func TestBrokenLinearFunction(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestResourceBinPackingSingleExtended(t *testing.T) {
|
func TestResourceBinPackingSingleExtended(t *testing.T) {
|
||||||
extendedResource := "intel.com/foo"
|
|
||||||
extendedResource1 := map[string]int64{
|
extendedResource1 := map[string]int64{
|
||||||
"intel.com/foo": 4,
|
"intel.com/foo": 4,
|
||||||
}
|
}
|
||||||
extendedResource2 := map[string]int64{
|
extendedResource2 := map[string]int64{
|
||||||
"intel.com/foo": 8,
|
"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 {
|
tests := []struct {
|
||||||
pod *v1.Pod
|
pod *v1.Pod
|
||||||
pods []*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.
|
// Node1 Score = Node2 Score = 0 as the incoming Pod doesn't request extended resource.
|
||||||
pod: st.MakePod().Obj(),
|
pod: st.MakePod().Obj(),
|
||||||
nodes: []*v1.Node{makeNode("machine1", 4000, 10000*1024*1024, extendedResource2), makeNode("machine2", 4000, 10000*1024*1024, extendedResource1)},
|
nodes: []*v1.Node{makeNode("node1", 4000, 10000*1024*1024, extendedResource2), makeNode("node2", 4000, 10000*1024*1024, extendedResource1)},
|
||||||
expectedScores: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}},
|
expectedScores: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}},
|
||||||
name: "nothing scheduled, nothing requested",
|
name: "nothing scheduled, nothing requested",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -271,13 +251,11 @@ func TestResourceBinPackingSingleExtended(t *testing.T) {
|
|||||||
// resourceScoringFunction((0+2),4)
|
// resourceScoringFunction((0+2),4)
|
||||||
// = 2/4 * maxUtilization = 50 = rawScoringFunction(50)
|
// = 2/4 * maxUtilization = 50 = rawScoringFunction(50)
|
||||||
// Node2 Score: 5
|
// Node2 Score: 5
|
||||||
pod: &v1.Pod{Spec: extendedResourcePod1},
|
pod: st.MakePod().Req(extendedResource3).Obj(),
|
||||||
nodes: []*v1.Node{makeNode("machine1", 4000, 10000*1024*1024, extendedResource2), makeNode("machine2", 4000, 10000*1024*1024, extendedResource1)},
|
nodes: []*v1.Node{makeNode("node1", 4000, 10000*1024*1024, extendedResource2), makeNode("node2", 4000, 10000*1024*1024, extendedResource1)},
|
||||||
expectedScores: []framework.NodeScore{{Name: "machine1", Score: 2}, {Name: "machine2", Score: 5}},
|
expectedScores: []framework.NodeScore{{Name: "node1", Score: 2}, {Name: "node2", Score: 5}},
|
||||||
name: "resources requested, pods scheduled with less resources",
|
name: "resources requested, pods scheduled with less resources",
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{st.MakePod().Obj()},
|
||||||
st.MakePod().Obj(),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Node1 scores (used resources) on 0-MaxNodeScore scale
|
// Node1 scores (used resources) on 0-MaxNodeScore scale
|
||||||
@ -291,13 +269,11 @@ func TestResourceBinPackingSingleExtended(t *testing.T) {
|
|||||||
// resourceScoringFunction((2+2),4)
|
// resourceScoringFunction((2+2),4)
|
||||||
// = 4/4 * maxUtilization = maxUtilization = rawScoringFunction(maxUtilization)
|
// = 4/4 * maxUtilization = maxUtilization = rawScoringFunction(maxUtilization)
|
||||||
// Node2 Score: 10
|
// Node2 Score: 10
|
||||||
pod: &v1.Pod{Spec: extendedResourcePod1},
|
pod: st.MakePod().Req(extendedResource3).Obj(),
|
||||||
nodes: []*v1.Node{makeNode("machine1", 4000, 10000*1024*1024, extendedResource2), makeNode("machine2", 4000, 10000*1024*1024, extendedResource1)},
|
nodes: []*v1.Node{makeNode("node1", 4000, 10000*1024*1024, extendedResource2), makeNode("node2", 4000, 10000*1024*1024, extendedResource1)},
|
||||||
expectedScores: []framework.NodeScore{{Name: "machine1", Score: 2}, {Name: "machine2", Score: 10}},
|
expectedScores: []framework.NodeScore{{Name: "node1", Score: 2}, {Name: "node2", Score: 10}},
|
||||||
name: "resources requested, pods scheduled with resources, on node with existing pod running ",
|
name: "resources requested, pods scheduled with resources, on node with existing pod running ",
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{st.MakePod().Req(extendedResource3).Node("node2").Obj()},
|
||||||
{Spec: machine2Pod},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Node1 scores (used resources) on 0-MaxNodeScore scale
|
// Node1 scores (used resources) on 0-MaxNodeScore scale
|
||||||
@ -311,9 +287,9 @@ func TestResourceBinPackingSingleExtended(t *testing.T) {
|
|||||||
// resourceScoringFunction((0+4),4)
|
// resourceScoringFunction((0+4),4)
|
||||||
// = 4/4 * maxUtilization = maxUtilization = rawScoringFunction(maxUtilization)
|
// = 4/4 * maxUtilization = maxUtilization = rawScoringFunction(maxUtilization)
|
||||||
// Node2 Score: 10
|
// Node2 Score: 10
|
||||||
pod: &v1.Pod{Spec: extendedResourcePod2},
|
pod: st.MakePod().Req(extendedResource4).Obj(),
|
||||||
nodes: []*v1.Node{makeNode("machine1", 4000, 10000*1024*1024, extendedResource2), makeNode("machine2", 4000, 10000*1024*1024, extendedResource1)},
|
nodes: []*v1.Node{makeNode("node1", 4000, 10000*1024*1024, extendedResource2), makeNode("node2", 4000, 10000*1024*1024, extendedResource1)},
|
||||||
expectedScores: []framework.NodeScore{{Name: "machine1", Score: 5}, {Name: "machine2", Score: 10}},
|
expectedScores: []framework.NodeScore{{Name: "node1", Score: 5}, {Name: "node2", Score: 10}},
|
||||||
name: "resources requested, pods scheduled with more resources",
|
name: "resources requested, pods scheduled with more resources",
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
st.MakePod().Obj(),
|
st.MakePod().Obj(),
|
||||||
@ -362,44 +338,24 @@ func TestResourceBinPackingSingleExtended(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestResourceBinPackingMultipleExtended(t *testing.T) {
|
func TestResourceBinPackingMultipleExtended(t *testing.T) {
|
||||||
extendedResource1 := "intel.com/foo"
|
|
||||||
extendedResource2 := "intel.com/bar"
|
|
||||||
extendedResources1 := map[string]int64{
|
extendedResources1 := map[string]int64{
|
||||||
"intel.com/foo": 4,
|
"intel.com/foo": 4,
|
||||||
"intel.com/bar": 8,
|
"intel.com/bar": 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
extendedResources2 := map[string]int64{
|
extendedResources2 := map[string]int64{
|
||||||
"intel.com/foo": 8,
|
"intel.com/foo": 8,
|
||||||
"intel.com/bar": 4,
|
"intel.com/bar": 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
extnededResourcePod1 := v1.PodSpec{
|
extendedResourcePod1 := map[v1.ResourceName]string{
|
||||||
Containers: []v1.Container{
|
"intel.com/foo": "2",
|
||||||
{
|
"intel.com/bar": "2",
|
||||||
Resources: v1.ResourceRequirements{
|
|
||||||
Requests: v1.ResourceList{
|
|
||||||
v1.ResourceName(extendedResource1): resource.MustParse("2"),
|
|
||||||
v1.ResourceName(extendedResource2): resource.MustParse("2"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
extnededResourcePod2 := v1.PodSpec{
|
extendedResourcePod2 := map[v1.ResourceName]string{
|
||||||
Containers: []v1.Container{
|
"intel.com/foo": "4",
|
||||||
{
|
"intel.com/bar": "2",
|
||||||
Resources: v1.ResourceRequirements{
|
|
||||||
Requests: v1.ResourceList{
|
|
||||||
v1.ResourceName(extendedResource1): resource.MustParse("4"),
|
|
||||||
v1.ResourceName(extendedResource2): resource.MustParse("2"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
machine2Pod := extnededResourcePod1
|
|
||||||
machine2Pod.NodeName = "machine2"
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
pod *v1.Pod
|
pod *v1.Pod
|
||||||
pods []*v1.Pod
|
pods []*v1.Pod
|
||||||
@ -436,11 +392,10 @@ func TestResourceBinPackingMultipleExtended(t *testing.T) {
|
|||||||
// Node2 Score: (0 * 3) + (0 * 5) / 8 = 0
|
// Node2 Score: (0 * 3) + (0 * 5) / 8 = 0
|
||||||
|
|
||||||
pod: st.MakePod().Obj(),
|
pod: st.MakePod().Obj(),
|
||||||
nodes: []*v1.Node{makeNode("machine1", 4000, 10000*1024*1024, extendedResources2), makeNode("machine2", 4000, 10000*1024*1024, extendedResources1)},
|
nodes: []*v1.Node{makeNode("node1", 4000, 10000*1024*1024, extendedResources2), makeNode("node2", 4000, 10000*1024*1024, extendedResources1)},
|
||||||
expectedScores: []framework.NodeScore{{Name: "machine1", Score: 0}, {Name: "machine2", Score: 0}},
|
expectedScores: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}},
|
||||||
name: "nothing scheduled, nothing requested",
|
name: "nothing scheduled, nothing requested",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
// resources["intel.com/foo"] = 3
|
// resources["intel.com/foo"] = 3
|
||||||
@ -469,15 +424,14 @@ func TestResourceBinPackingMultipleExtended(t *testing.T) {
|
|||||||
// = 2/8 * 100 = 25 = rawScoringFunction(25)
|
// = 2/8 * 100 = 25 = rawScoringFunction(25)
|
||||||
// Node2 Score: (5 * 3) + (2 * 5) / 8 = 3
|
// Node2 Score: (5 * 3) + (2 * 5) / 8 = 3
|
||||||
|
|
||||||
pod: &v1.Pod{Spec: extnededResourcePod1},
|
pod: st.MakePod().Req(extendedResourcePod1).Obj(),
|
||||||
nodes: []*v1.Node{makeNode("machine1", 4000, 10000*1024*1024, extendedResources2), makeNode("machine2", 4000, 10000*1024*1024, extendedResources1)},
|
nodes: []*v1.Node{makeNode("node1", 4000, 10000*1024*1024, extendedResources2), makeNode("node2", 4000, 10000*1024*1024, extendedResources1)},
|
||||||
expectedScores: []framework.NodeScore{{Name: "machine1", Score: 4}, {Name: "machine2", Score: 3}},
|
expectedScores: []framework.NodeScore{{Name: "node1", Score: 4}, {Name: "node2", Score: 3}},
|
||||||
name: "resources requested, pods scheduled with less resources",
|
name: "resources requested, pods scheduled with less resources",
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
st.MakePod().Obj(),
|
st.MakePod().Obj(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
// resources["intel.com/foo"] = 3
|
// resources["intel.com/foo"] = 3
|
||||||
@ -505,15 +459,12 @@ func TestResourceBinPackingMultipleExtended(t *testing.T) {
|
|||||||
// = 4/8 *100 = 50 = rawScoringFunction(50)
|
// = 4/8 *100 = 50 = rawScoringFunction(50)
|
||||||
// Node2 Score: (10 * 3) + (5 * 5) / 8 = 7
|
// Node2 Score: (10 * 3) + (5 * 5) / 8 = 7
|
||||||
|
|
||||||
pod: &v1.Pod{Spec: extnededResourcePod1},
|
pod: st.MakePod().Req(extendedResourcePod1).Obj(),
|
||||||
nodes: []*v1.Node{makeNode("machine1", 4000, 10000*1024*1024, extendedResources2), makeNode("machine2", 4000, 10000*1024*1024, extendedResources1)},
|
nodes: []*v1.Node{makeNode("node1", 4000, 10000*1024*1024, extendedResources2), makeNode("node2", 4000, 10000*1024*1024, extendedResources1)},
|
||||||
expectedScores: []framework.NodeScore{{Name: "machine1", Score: 4}, {Name: "machine2", Score: 7}},
|
expectedScores: []framework.NodeScore{{Name: "node1", Score: 4}, {Name: "node2", Score: 7}},
|
||||||
name: "resources requested, pods scheduled with resources, on node with existing pod running ",
|
name: "resources requested, pods scheduled with resources, on node with existing pod running ",
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{st.MakePod().Req(extendedResourcePod2).Node("node2").Obj()},
|
||||||
{Spec: machine2Pod},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
// resources["intel.com/foo"] = 3
|
// resources["intel.com/foo"] = 3
|
||||||
@ -556,9 +507,9 @@ func TestResourceBinPackingMultipleExtended(t *testing.T) {
|
|||||||
// = 2/8 * 100 = 25 = rawScoringFunction(25)
|
// = 2/8 * 100 = 25 = rawScoringFunction(25)
|
||||||
// Node2 Score: (10 * 3) + (2 * 5) / 8 = 5
|
// Node2 Score: (10 * 3) + (2 * 5) / 8 = 5
|
||||||
|
|
||||||
pod: &v1.Pod{Spec: extnededResourcePod2},
|
pod: st.MakePod().Req(extendedResourcePod2).Obj(),
|
||||||
nodes: []*v1.Node{makeNode("machine1", 4000, 10000*1024*1024, extendedResources2), makeNode("machine2", 4000, 10000*1024*1024, extendedResources1)},
|
nodes: []*v1.Node{makeNode("node1", 4000, 10000*1024*1024, extendedResources2), makeNode("node2", 4000, 10000*1024*1024, extendedResources1)},
|
||||||
expectedScores: []framework.NodeScore{{Name: "machine1", Score: 5}, {Name: "machine2", Score: 5}},
|
expectedScores: []framework.NodeScore{{Name: "node1", Score: 5}, {Name: "node2", Score: 5}},
|
||||||
name: "resources requested, pods scheduled with more resources",
|
name: "resources requested, pods scheduled with more resources",
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
st.MakePod().Obj(),
|
st.MakePod().Obj(),
|
||||||
|
@ -36,6 +36,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/features"
|
"k8s.io/kubernetes/pkg/features"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework"
|
"k8s.io/kubernetes/pkg/scheduler/framework"
|
||||||
fakeframework "k8s.io/kubernetes/pkg/scheduler/framework/fake"
|
fakeframework "k8s.io/kubernetes/pkg/scheduler/framework/fake"
|
||||||
|
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
||||||
utilpointer "k8s.io/utils/pointer"
|
utilpointer "k8s.io/utils/pointer"
|
||||||
)
|
)
|
||||||
@ -68,195 +69,35 @@ func getVolumeLimitKey(filterType string) v1.ResourceName {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCSILimits(t *testing.T) {
|
func TestCSILimits(t *testing.T) {
|
||||||
runningPod := &v1.Pod{
|
runningPod := st.MakePod().PVC("csi-ebs.csi.aws.com-3").Obj()
|
||||||
Spec: v1.PodSpec{
|
pendingVolumePod := st.MakePod().PVC("csi-4").Obj()
|
||||||
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",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Different pod than pendingVolumePod, but using the same unbound PVC
|
// Different pod than pendingVolumePod, but using the same unbound PVC
|
||||||
unboundPVCPod2 := &v1.Pod{
|
unboundPVCPod2 := st.MakePod().PVC("csi-4").Obj()
|
||||||
Spec: v1.PodSpec{
|
|
||||||
Volumes: []v1.Volume{
|
|
||||||
{
|
|
||||||
VolumeSource: v1.VolumeSource{
|
|
||||||
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
|
|
||||||
ClaimName: "csi-4",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
missingPVPod := &v1.Pod{
|
missingPVPod := st.MakePod().PVC("csi-6").Obj()
|
||||||
Spec: v1.PodSpec{
|
noSCPVCPod := st.MakePod().PVC("csi-5").Obj()
|
||||||
Volumes: []v1.Volume{
|
|
||||||
{
|
gceTwoVolPod := st.MakePod().PVC("csi-pd.csi.storage.gke.io-1").PVC("csi-pd.csi.storage.gke.io-2").Obj()
|
||||||
VolumeSource: v1.VolumeSource{
|
|
||||||
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
|
|
||||||
ClaimName: "csi-6",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
// In-tree volumes
|
||||||
inTreeOneVolPod := &v1.Pod{
|
inTreeOneVolPod := st.MakePod().PVC("csi-kubernetes.io/aws-ebs-0").Obj()
|
||||||
Spec: v1.PodSpec{
|
inTreeTwoVolPod := st.MakePod().PVC("csi-kubernetes.io/aws-ebs-1").PVC("csi-kubernetes.io/aws-ebs-2").Obj()
|
||||||
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",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
ephemeralVolumePod := &v1.Pod{
|
// pods with matching csi driver names
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
csiEBSOneVolPod := st.MakePod().PVC("csi-ebs.csi.aws.com-0").Obj()
|
||||||
Namespace: "test",
|
csiEBSTwoVolPod := st.MakePod().PVC("csi-ebs.csi.aws.com-1").PVC("csi-ebs.csi.aws.com-2").Obj()
|
||||||
Name: "abc",
|
|
||||||
UID: "12345",
|
inTreeNonMigratableOneVolPod := st.MakePod().PVC("csi-kubernetes.io/hostpath-0").Obj()
|
||||||
},
|
|
||||||
Spec: v1.PodSpec{
|
ephemeralVolumePod := st.MakePod().Name("abc").Namespace("test").UID("12345").Volume(
|
||||||
Volumes: []v1.Volume{
|
v1.Volume{
|
||||||
{
|
Name: "xyz",
|
||||||
Name: "xyz",
|
VolumeSource: v1.VolumeSource{
|
||||||
VolumeSource: v1.VolumeSource{
|
Ephemeral: &v1.EphemeralVolumeSource{},
|
||||||
Ephemeral: &v1.EphemeralVolumeSource{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
}).Obj()
|
||||||
}
|
|
||||||
controller := true
|
controller := true
|
||||||
ephemeralClaim := &v1.PersistentVolumeClaim{
|
ephemeralClaim := &v1.PersistentVolumeClaim{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@ -278,29 +119,18 @@ func TestCSILimits(t *testing.T) {
|
|||||||
conflictingClaim := ephemeralClaim.DeepCopy()
|
conflictingClaim := ephemeralClaim.DeepCopy()
|
||||||
conflictingClaim.OwnerReferences = nil
|
conflictingClaim.OwnerReferences = nil
|
||||||
|
|
||||||
ephemeralTwoVolumePod := &v1.Pod{
|
ephemeralTwoVolumePod := st.MakePod().Name("abc").Namespace("test").UID("12345II").Volume(v1.Volume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
Name: "x",
|
||||||
Namespace: "test",
|
VolumeSource: v1.VolumeSource{
|
||||||
Name: "abc",
|
Ephemeral: &v1.EphemeralVolumeSource{},
|
||||||
UID: "12345II",
|
|
||||||
},
|
},
|
||||||
Spec: v1.PodSpec{
|
}).Volume(v1.Volume{
|
||||||
Volumes: []v1.Volume{
|
Name: "y",
|
||||||
{
|
VolumeSource: v1.VolumeSource{
|
||||||
Name: "x",
|
Ephemeral: &v1.EphemeralVolumeSource{},
|
||||||
VolumeSource: v1.VolumeSource{
|
|
||||||
Ephemeral: &v1.EphemeralVolumeSource{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "y",
|
|
||||||
VolumeSource: v1.VolumeSource{
|
|
||||||
Ephemeral: &v1.EphemeralVolumeSource{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}).Obj()
|
||||||
|
|
||||||
ephemeralClaimX := &v1.PersistentVolumeClaim{
|
ephemeralClaimX := &v1.PersistentVolumeClaim{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Namespace: ephemeralTwoVolumePod.Namespace,
|
Namespace: ephemeralTwoVolumePod.Namespace,
|
||||||
|
@ -18,6 +18,7 @@ package nodevolumelimits
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
@ -29,32 +30,67 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/scheduler/framework"
|
"k8s.io/kubernetes/pkg/scheduler/framework"
|
||||||
fakeframework "k8s.io/kubernetes/pkg/scheduler/framework/fake"
|
fakeframework "k8s.io/kubernetes/pkg/scheduler/framework/fake"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature"
|
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature"
|
||||||
|
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||||
utilpointer "k8s.io/utils/pointer"
|
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) {
|
func TestEphemeralLimits(t *testing.T) {
|
||||||
// We have to specify a valid filter and arbitrarily pick Cinder here.
|
// We have to specify a valid filter and arbitrarily pick Cinder here.
|
||||||
// It doesn't matter for the test cases.
|
// It doesn't matter for the test cases.
|
||||||
filterName := gcePDVolumeFilterType
|
filterName := gcePDVolumeFilterType
|
||||||
driverName := csilibplugins.GCEPDInTreePluginName
|
driverName := csilibplugins.GCEPDInTreePluginName
|
||||||
|
|
||||||
ephemeralVolumePod := &v1.Pod{
|
ephemeralVolumePod := st.MakePod().Name("abc").Namespace("test").UID("12345").Volume(v1.Volume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
Name: "xyz",
|
||||||
Namespace: "test",
|
VolumeSource: v1.VolumeSource{
|
||||||
Name: "abc",
|
Ephemeral: &v1.EphemeralVolumeSource{},
|
||||||
UID: "12345",
|
|
||||||
},
|
},
|
||||||
Spec: v1.PodSpec{
|
}).Obj()
|
||||||
Volumes: []v1.Volume{
|
|
||||||
{
|
|
||||||
Name: "xyz",
|
|
||||||
VolumeSource: v1.VolumeSource{
|
|
||||||
Ephemeral: &v1.EphemeralVolumeSource{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
controller := true
|
controller := true
|
||||||
ephemeralClaim := &v1.PersistentVolumeClaim{
|
ephemeralClaim := &v1.PersistentVolumeClaim{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@ -130,180 +166,6 @@ func TestEphemeralLimits(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAzureDiskLimits(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 {
|
tests := []struct {
|
||||||
newPod *v1.Pod
|
newPod *v1.Pod
|
||||||
existingPods []*v1.Pod
|
existingPods []*v1.Pod
|
||||||
@ -468,205 +330,8 @@ func TestAzureDiskLimits(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestEBSLimits(t *testing.T) {
|
func TestEBSLimits(t *testing.T) {
|
||||||
oneVolPod := &v1.Pod{
|
unboundPVCWithInvalidSCPod := st.MakePod().PVC("unboundPVCWithInvalidSCPod").Obj()
|
||||||
Spec: v1.PodSpec{
|
unboundPVCWithDefaultSCPod := st.MakePod().PVC("unboundPVCWithDefaultSCPod").Obj()
|
||||||
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",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
newPod *v1.Pod
|
newPod *v1.Pod
|
||||||
@ -777,7 +442,7 @@ func TestEBSLimits(t *testing.T) {
|
|||||||
test: "two missing PVCs are not counted towards the PV limit twice",
|
test: "two missing PVCs are not counted towards the PV limit twice",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
newPod: unboundPVCwithInvalidSCPod,
|
newPod: unboundPVCWithInvalidSCPod,
|
||||||
existingPods: []*v1.Pod{oneVolPod},
|
existingPods: []*v1.Pod{oneVolPod},
|
||||||
filterName: ebsVolumeFilterType,
|
filterName: ebsVolumeFilterType,
|
||||||
driverName: csilibplugins.AWSEBSInTreePluginName,
|
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",
|
test: "unbound PVC with invalid SC is not counted towards the PV limit",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
newPod: unboundPVCwithDefaultSCPod,
|
newPod: unboundPVCWithDefaultSCPod,
|
||||||
existingPods: []*v1.Pod{oneVolPod},
|
existingPods: []*v1.Pod{oneVolPod},
|
||||||
filterName: ebsVolumeFilterType,
|
filterName: ebsVolumeFilterType,
|
||||||
driverName: csilibplugins.AWSEBSInTreePluginName,
|
driverName: csilibplugins.AWSEBSInTreePluginName,
|
||||||
maxVols: 1,
|
maxVols: 1,
|
||||||
test: "unbound PVC from different provisioner is not counted towards the PV limit",
|
test: "unbound PVC from different provisioner is not counted towards the PV limit",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
newPod: onePVCPod(ebsVolumeFilterType),
|
newPod: onePVCPod(ebsVolumeFilterType),
|
||||||
existingPods: []*v1.Pod{oneVolPod, deletedPVPod},
|
existingPods: []*v1.Pod{oneVolPod, deletedPVPod},
|
||||||
@ -876,180 +540,6 @@ func TestEBSLimits(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGCEPDLimits(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 {
|
tests := []struct {
|
||||||
newPod *v1.Pod
|
newPod *v1.Pod
|
||||||
existingPods []*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{
|
Spec: v1.PersistentVolumeClaimSpec{
|
||||||
VolumeName: "",
|
VolumeName: "",
|
||||||
StorageClassName: utilpointer.StringPtr("standard-sc"),
|
StorageClassName: utilpointer.StringPtr("standard-sc"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "unboundPVCwithInvalidSCPod"},
|
ObjectMeta: metav1.ObjectMeta{Name: "unboundPVCWithInvalidSCPod"},
|
||||||
Spec: v1.PersistentVolumeClaimSpec{
|
Spec: v1.PersistentVolumeClaimSpec{
|
||||||
VolumeName: "",
|
VolumeName: "",
|
||||||
StorageClassName: utilpointer.StringPtr("invalid-sc"),
|
StorageClassName: utilpointer.StringPtr("invalid-sc"),
|
||||||
@ -1335,40 +825,9 @@ func getFakePVLister(filterName string) fakeframework.PersistentVolumeLister {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func onePVCPod(filterName string) *v1.Pod {
|
func onePVCPod(filterName string) *v1.Pod {
|
||||||
return &v1.Pod{
|
return st.MakePod().PVC(fmt.Sprintf("some%sVol", filterName)).Obj()
|
||||||
Spec: v1.PodSpec{
|
|
||||||
Volumes: []v1.Volume{
|
|
||||||
{
|
|
||||||
VolumeSource: v1.VolumeSource{
|
|
||||||
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
|
|
||||||
ClaimName: "some" + filterName + "Vol",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitPVCPod(filterName string) *v1.Pod {
|
func splitPVCPod(filterName string) *v1.Pod {
|
||||||
return &v1.Pod{
|
return st.MakePod().PVC(fmt.Sprintf("someNon%sVol", filterName)).PVC(fmt.Sprintf("some%sVol", filterName)).Obj()
|
||||||
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",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,10 +17,11 @@ limitations under the License.
|
|||||||
package queuesort
|
package queuesort
|
||||||
|
|
||||||
import (
|
import (
|
||||||
v1 "k8s.io/api/core/v1"
|
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/scheduler/framework"
|
||||||
|
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLess(t *testing.T) {
|
func TestLess(t *testing.T) {
|
||||||
@ -37,55 +38,31 @@ func TestLess(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "p1.priority less than p2.priority",
|
name: "p1.priority less than p2.priority",
|
||||||
p1: &framework.QueuedPodInfo{
|
p1: &framework.QueuedPodInfo{
|
||||||
PodInfo: framework.NewPodInfo(&v1.Pod{
|
PodInfo: framework.NewPodInfo(st.MakePod().Priority(lowPriority).Obj()),
|
||||||
Spec: v1.PodSpec{
|
|
||||||
Priority: &lowPriority,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
p2: &framework.QueuedPodInfo{
|
p2: &framework.QueuedPodInfo{
|
||||||
PodInfo: framework.NewPodInfo(&v1.Pod{
|
PodInfo: framework.NewPodInfo(st.MakePod().Priority(highPriority).Obj()),
|
||||||
Spec: v1.PodSpec{
|
|
||||||
Priority: &highPriority,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
expected: false, // p2 should be ahead of p1 in the queue
|
expected: false, // p2 should be ahead of p1 in the queue
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "p1.priority greater than p2.priority",
|
name: "p1.priority greater than p2.priority",
|
||||||
p1: &framework.QueuedPodInfo{
|
p1: &framework.QueuedPodInfo{
|
||||||
PodInfo: framework.NewPodInfo(&v1.Pod{
|
PodInfo: framework.NewPodInfo(st.MakePod().Priority(highPriority).Obj()),
|
||||||
Spec: v1.PodSpec{
|
|
||||||
Priority: &highPriority,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
p2: &framework.QueuedPodInfo{
|
p2: &framework.QueuedPodInfo{
|
||||||
PodInfo: framework.NewPodInfo(&v1.Pod{
|
PodInfo: framework.NewPodInfo(st.MakePod().Priority(lowPriority).Obj()),
|
||||||
Spec: v1.PodSpec{
|
|
||||||
Priority: &lowPriority,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
expected: true, // p1 should be ahead of p2 in the queue
|
expected: true, // p1 should be ahead of p2 in the queue
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "equal priority. p1 is added to schedulingQ earlier than p2",
|
name: "equal priority. p1 is added to schedulingQ earlier than p2",
|
||||||
p1: &framework.QueuedPodInfo{
|
p1: &framework.QueuedPodInfo{
|
||||||
PodInfo: framework.NewPodInfo(&v1.Pod{
|
PodInfo: framework.NewPodInfo(st.MakePod().Priority(highPriority).Obj()),
|
||||||
Spec: v1.PodSpec{
|
|
||||||
Priority: &highPriority,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
Timestamp: t1,
|
Timestamp: t1,
|
||||||
},
|
},
|
||||||
p2: &framework.QueuedPodInfo{
|
p2: &framework.QueuedPodInfo{
|
||||||
PodInfo: framework.NewPodInfo(&v1.Pod{
|
PodInfo: framework.NewPodInfo(st.MakePod().Priority(highPriority).Obj()),
|
||||||
Spec: v1.PodSpec{
|
|
||||||
Priority: &highPriority,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
Timestamp: t2,
|
Timestamp: t2,
|
||||||
},
|
},
|
||||||
expected: true, // p1 should be ahead of p2 in the queue
|
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",
|
name: "equal priority. p2 is added to schedulingQ earlier than p1",
|
||||||
p1: &framework.QueuedPodInfo{
|
p1: &framework.QueuedPodInfo{
|
||||||
PodInfo: framework.NewPodInfo(&v1.Pod{
|
PodInfo: framework.NewPodInfo(st.MakePod().Priority(highPriority).Obj()),
|
||||||
Spec: v1.PodSpec{
|
|
||||||
Priority: &highPriority,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
Timestamp: t2,
|
Timestamp: t2,
|
||||||
},
|
},
|
||||||
p2: &framework.QueuedPodInfo{
|
p2: &framework.QueuedPodInfo{
|
||||||
PodInfo: framework.NewPodInfo(&v1.Pod{
|
PodInfo: framework.NewPodInfo(st.MakePod().Priority(highPriority).Obj()),
|
||||||
Spec: v1.PodSpec{
|
|
||||||
Priority: &highPriority,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
Timestamp: t1,
|
Timestamp: t1,
|
||||||
},
|
},
|
||||||
expected: false, // p2 should be ahead of p1 in the queue
|
expected: false, // p2 should be ahead of p1 in the queue
|
||||||
|
@ -33,6 +33,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/scheduler/framework"
|
"k8s.io/kubernetes/pkg/scheduler/framework"
|
||||||
frameworkruntime "k8s.io/kubernetes/pkg/scheduler/framework/runtime"
|
frameworkruntime "k8s.io/kubernetes/pkg/scheduler/framework/runtime"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/internal/cache"
|
"k8s.io/kubernetes/pkg/scheduler/internal/cache"
|
||||||
|
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||||
"k8s.io/utils/pointer"
|
"k8s.io/utils/pointer"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -63,10 +64,10 @@ func TestSelectorSpreadScore(t *testing.T) {
|
|||||||
"baz": "blah",
|
"baz": "blah",
|
||||||
}
|
}
|
||||||
zone1Spec := v1.PodSpec{
|
zone1Spec := v1.PodSpec{
|
||||||
NodeName: "machine1",
|
NodeName: "node1",
|
||||||
}
|
}
|
||||||
zone2Spec := v1.PodSpec{
|
zone2Spec := v1.PodSpec{
|
||||||
NodeName: "machine2",
|
NodeName: "node2",
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
pod *v1.Pod
|
pod *v1.Pod
|
||||||
@ -81,122 +82,122 @@ func TestSelectorSpreadScore(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
pod: new(v1.Pod),
|
pod: new(v1.Pod),
|
||||||
nodes: []string{"machine1", "machine2"},
|
nodes: []string{"node1", "node2"},
|
||||||
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: "nothing scheduled",
|
name: "nothing scheduled",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
pod: st.MakePod().Labels(labels1).Obj(),
|
||||||
pods: []*v1.Pod{{Spec: zone1Spec}},
|
pods: []*v1.Pod{st.MakePod().Node("node1").Obj()},
|
||||||
nodes: []string{"machine1", "machine2"},
|
nodes: []string{"node1", "node2"},
|
||||||
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: "no services",
|
name: "no 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}}},
|
pods: []*v1.Pod{st.MakePod().Labels(labels2).Node("node1").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{"key": "value"}}}},
|
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",
|
name: "different services",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
pod: st.MakePod().Labels(labels1).Obj(),
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}},
|
st.MakePod().Labels(labels2).Node("node1").Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
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}}},
|
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",
|
name: "two pods, one service pod",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
pod: st.MakePod().Labels(labels1).Obj(),
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}},
|
st.MakePod().Labels(labels2).Node("node1").Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1, Namespace: metav1.NamespaceDefault}},
|
st.MakePod().Labels(labels1).Node("node1").Namespace(metav1.NamespaceDefault).Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1, Namespace: "ns1"}},
|
st.MakePod().Labels(labels1).Node("node1").Namespace("ns1").Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
st.MakePod().Labels(labels1).Node("node2").Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}},
|
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}}},
|
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",
|
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{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1, Namespace: "ns1"}},
|
{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: labels1, Namespace: metav1.NamespaceDefault}},
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}},
|
{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}}},
|
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",
|
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{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
st.MakePod().Labels(labels2).Node("node1").Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1, Namespace: metav1.NamespaceDefault}},
|
st.MakePod().Labels(labels1).Node("node1").Namespace(metav1.NamespaceDefault).Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1, Namespace: "ns2"}},
|
st.MakePod().Labels(labels1).Node("node1").Namespace("ns2").Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1, Namespace: "ns1"}},
|
st.MakePod().Labels(labels1).Node("node2").Namespace("ns1").Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}},
|
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"}}},
|
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",
|
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{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}},
|
st.MakePod().Labels(labels2).Node("node1").Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
st.MakePod().Labels(labels1).Node("node1").Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
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}}},
|
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}},
|
expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}},
|
||||||
name: "three pods, two service pods on different machines",
|
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{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}},
|
st.MakePod().Labels(labels2).Node("node1").Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
st.MakePod().Labels(labels1).Node("node1").Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
st.MakePod().Labels(labels1).Node("node2").Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
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}}},
|
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",
|
name: "four pods, three service pods",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pod: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
pod: st.MakePod().Labels(labels1).Obj(),
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels2}},
|
st.MakePod().Labels(labels2).Node("node1").Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
st.MakePod().Labels(labels1).Node("node1").Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Labels: labels1}},
|
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"}}}},
|
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",
|
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{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2}},
|
st.MakePod().Node("node1").Namespace(metav1.NamespaceDefault).Labels(labels2).Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1}},
|
st.MakePod().Node("node1").Namespace(metav1.NamespaceDefault).Labels(labels1).Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1}},
|
st.MakePod().Node("node2").Namespace(metav1.NamespaceDefault).Labels(labels1).Obj(),
|
||||||
},
|
},
|
||||||
nodes: []string{"machine1", "machine2"},
|
nodes: []string{"node1", "node2"},
|
||||||
rcs: []*v1.ReplicationController{
|
rcs: []*v1.ReplicationController{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "rc1", Namespace: metav1.NamespaceDefault}, Spec: v1.ReplicationControllerSpec{Selector: map[string]string{"foo": "bar"}}},
|
{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"}}},
|
{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"}}}},
|
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
|
// "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.
|
// 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",
|
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{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2}},
|
st.MakePod().Node("node1").Namespace(metav1.NamespaceDefault).Labels(labels2).Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1}},
|
st.MakePod().Node("node1").Namespace(metav1.NamespaceDefault).Labels(labels1).Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1}},
|
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"}}}},
|
services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Name: "s1", Namespace: metav1.NamespaceDefault}, Spec: v1.ServiceSpec{Selector: map[string]string{"baz": "blah"}}}},
|
||||||
rss: []*apps.ReplicaSet{
|
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: "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"}}}},
|
{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.
|
// 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",
|
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{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2}},
|
st.MakePod().Node("node1").Namespace(metav1.NamespaceDefault).Labels(labels2).Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1}},
|
st.MakePod().Node("node1").Namespace(metav1.NamespaceDefault).Labels(labels1).Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1}},
|
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"}}}},
|
services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Name: "s1", Namespace: metav1.NamespaceDefault}, Spec: v1.ServiceSpec{Selector: map[string]string{"baz": "blah"}}}},
|
||||||
sss: []*apps.StatefulSet{
|
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: "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"}}}},
|
{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",
|
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{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("rc2", rcKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("rc2", rcKind).Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rc1", rcKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("rc1", rcKind).Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rc1", rcKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node2").Labels(labels1).OwnerReference("rc1", rcKind).Obj(),
|
||||||
},
|
},
|
||||||
nodes: []string{"machine1", "machine2"},
|
nodes: []string{"node1", "node2"},
|
||||||
rcs: []*v1.ReplicationController{{
|
rcs: []*v1.ReplicationController{{
|
||||||
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "rc3"},
|
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "rc3"},
|
||||||
Spec: v1.ReplicationControllerSpec{Selector: map[string]string{"foo": "bar"}}}},
|
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"}}}},
|
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.
|
// 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",
|
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"},
|
pod: st.MakePod().Namespace(metav1.NamespaceDefault).Labels(map[string]string{"foo": "bar", "bar": "foo"}).OwnerReference("rs3", rsKind).Obj(),
|
||||||
OwnerReferences: controllerRef("rs3", rsKind)}},
|
|
||||||
pods: []*v1.Pod{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("rs2", rsKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("rs2", rsKind).Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rs1", rsKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("rs1", rsKind).Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rs1", rsKind)}},
|
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"}}}},
|
services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Name: "s1", Namespace: metav1.NamespaceDefault}, Spec: v1.ServiceSpec{Selector: map[string]string{"bar": "foo"}}}},
|
||||||
rss: []*apps.ReplicaSet{
|
rss: []*apps.ReplicaSet{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "rs3", Namespace: metav1.NamespaceDefault}, Spec: apps.ReplicaSetSpec{Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}}}},
|
{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.
|
// 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",
|
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{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("ss2", ssKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("ss2", ssKind).Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("ss1", ssKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("ss1", ssKind).Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("ss1", ssKind)}},
|
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"}}}},
|
services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Name: "s1", Namespace: metav1.NamespaceDefault}, Spec: v1.ServiceSpec{Selector: map[string]string{"bar": "foo"}}}},
|
||||||
sss: []*apps.StatefulSet{
|
sss: []*apps.StatefulSet{
|
||||||
{ObjectMeta: metav1.ObjectMeta{Name: "ss3", Namespace: metav1.NamespaceDefault}, Spec: apps.StatefulSetSpec{Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}}}},
|
{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",
|
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{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("rc2", rcKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("rc2", rcKind).Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rc1", rcKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("rc1", rcKind).Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rc1", rcKind)}},
|
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"}}}},
|
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.
|
// 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",
|
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{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("rs2", rsKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("rs2", rsKind).Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rs1", rsKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("rs1", rsKind).Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rs1", rsKind)}},
|
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"}}}}},
|
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.
|
// 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",
|
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{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("ss2", ssKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("ss2", ssKind).Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("ss1", ssKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("ss1", ssKind).Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("ss1", ssKind)}},
|
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"}}}}},
|
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.
|
// 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",
|
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{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("rc2", rcKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("rc2", rcKind).Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rc1", rcKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("rc1", rcKind).Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rc1", rcKind)}},
|
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"}}}},
|
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",
|
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{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("rs2", rsKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("rs2", rsKind).Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rs1", rsKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("rs1", rsKind).Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("rs1", rsKind)}},
|
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"}}}}},
|
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.
|
// 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",
|
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{
|
pods: []*v1.Pod{
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels2, OwnerReferences: controllerRef("ss2", ssKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels2).OwnerReference("ss2", ssKind).Obj(),
|
||||||
{Spec: zone1Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("ss1", ssKind)}},
|
st.MakePod().Namespace(metav1.NamespaceDefault).Node("node1").Labels(labels1).OwnerReference("ss1", ssKind).Obj(),
|
||||||
{Spec: zone2Spec, ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Labels: labels1, OwnerReferences: controllerRef("ss1", ssKind)}},
|
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"}}}}},
|
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.
|
// 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",
|
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: 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)}},
|
{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"}}}}},
|
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",
|
name: "Another statefulset with TopologySpreadConstraints set in pod",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -458,12 +458,12 @@ func TestZoneSelectorSpreadPriority(t *testing.T) {
|
|||||||
"baz": "blah",
|
"baz": "blah",
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodeMachine1Zone1 = "machine1.zone1"
|
const nodeMachine1Zone1 = "node1.zone1"
|
||||||
const nodeMachine1Zone2 = "machine1.zone2"
|
const nodeMachine1Zone2 = "node1.zone2"
|
||||||
const nodeMachine2Zone2 = "machine2.zone2"
|
const nodeMachine2Zone2 = "node2.zone2"
|
||||||
const nodeMachine1Zone3 = "machine1.zone3"
|
const nodeMachine1Zone3 = "node1.zone3"
|
||||||
const nodeMachine2Zone3 = "machine2.zone3"
|
const nodeMachine2Zone3 = "node2.zone3"
|
||||||
const nodeMachine3Zone3 = "machine3.zone3"
|
const nodeMachine3Zone3 = "node3.zone3"
|
||||||
|
|
||||||
buildNodeLabels := func(failureDomain string) map[string]string {
|
buildNodeLabels := func(failureDomain string) map[string]string {
|
||||||
labels := 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}}},
|
services: []*v1.Service{{ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceDefault, Name: "s1"}, Spec: v1.ServiceSpec{Selector: labels1}}},
|
||||||
expectedList: []framework.NodeScore{
|
expectedList: []framework.NodeScore{
|
||||||
{Name: nodeMachine1Zone1, Score: framework.MaxNodeScore},
|
{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: nodeMachine2Zone2, Score: 33}, // Already have pod in zone
|
||||||
{Name: nodeMachine1Zone3, Score: framework.MaxNodeScore},
|
{Name: nodeMachine1Zone3, Score: framework.MaxNodeScore},
|
||||||
{Name: nodeMachine2Zone3, Score: framework.MaxNodeScore},
|
{Name: nodeMachine2Zone3, Score: framework.MaxNodeScore},
|
||||||
|
@ -32,28 +32,21 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature"
|
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature"
|
||||||
plugintesting "k8s.io/kubernetes/pkg/scheduler/framework/plugins/testing"
|
plugintesting "k8s.io/kubernetes/pkg/scheduler/framework/plugins/testing"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/internal/cache"
|
"k8s.io/kubernetes/pkg/scheduler/internal/cache"
|
||||||
|
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGCEDiskConflicts(t *testing.T) {
|
func TestGCEDiskConflicts(t *testing.T) {
|
||||||
volState := v1.PodSpec{
|
volState := v1.Volume{
|
||||||
Volumes: []v1.Volume{
|
VolumeSource: v1.VolumeSource{
|
||||||
{
|
GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{
|
||||||
VolumeSource: v1.VolumeSource{
|
PDName: "foo",
|
||||||
GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{
|
|
||||||
PDName: "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
volState2 := v1.PodSpec{
|
volState2 := v1.Volume{
|
||||||
Volumes: []v1.Volume{
|
VolumeSource: v1.VolumeSource{
|
||||||
{
|
GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{
|
||||||
VolumeSource: v1.VolumeSource{
|
PDName: "bar",
|
||||||
GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{
|
|
||||||
PDName: "bar",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -66,9 +59,9 @@ func TestGCEDiskConflicts(t *testing.T) {
|
|||||||
wantStatus *framework.Status
|
wantStatus *framework.Status
|
||||||
}{
|
}{
|
||||||
{&v1.Pod{}, framework.NewNodeInfo(), true, "nothing", nil},
|
{&v1.Pod{}, framework.NewNodeInfo(), true, "nothing", nil},
|
||||||
{&v1.Pod{}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), true, "one state", nil},
|
{&v1.Pod{}, framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), true, "one state", nil},
|
||||||
{&v1.Pod{Spec: volState}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), false, "same state", errStatus},
|
{st.MakePod().Volume(volState).Obj(), framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), false, "same state", errStatus},
|
||||||
{&v1.Pod{Spec: volState2}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), true, "different state", nil},
|
{st.MakePod().Volume(volState2).Obj(), framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), true, "different state", nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
@ -85,25 +78,17 @@ func TestGCEDiskConflicts(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAWSDiskConflicts(t *testing.T) {
|
func TestAWSDiskConflicts(t *testing.T) {
|
||||||
volState := v1.PodSpec{
|
volState := v1.Volume{
|
||||||
Volumes: []v1.Volume{
|
VolumeSource: v1.VolumeSource{
|
||||||
{
|
AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{
|
||||||
VolumeSource: v1.VolumeSource{
|
VolumeID: "foo",
|
||||||
AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{
|
|
||||||
VolumeID: "foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
volState2 := v1.PodSpec{
|
volState2 := v1.Volume{
|
||||||
Volumes: []v1.Volume{
|
VolumeSource: v1.VolumeSource{
|
||||||
{
|
AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{
|
||||||
VolumeSource: v1.VolumeSource{
|
VolumeID: "bar",
|
||||||
AWSElasticBlockStore: &v1.AWSElasticBlockStoreVolumeSource{
|
|
||||||
VolumeID: "bar",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -116,9 +101,9 @@ func TestAWSDiskConflicts(t *testing.T) {
|
|||||||
wantStatus *framework.Status
|
wantStatus *framework.Status
|
||||||
}{
|
}{
|
||||||
{&v1.Pod{}, framework.NewNodeInfo(), true, "nothing", nil},
|
{&v1.Pod{}, framework.NewNodeInfo(), true, "nothing", nil},
|
||||||
{&v1.Pod{}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), true, "one state", nil},
|
{&v1.Pod{}, framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), true, "one state", nil},
|
||||||
{&v1.Pod{Spec: volState}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), false, "same state", errStatus},
|
{st.MakePod().Volume(volState).Obj(), framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), false, "same state", errStatus},
|
||||||
{&v1.Pod{Spec: volState2}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), true, "different state", nil},
|
{st.MakePod().Volume(volState2).Obj(), framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), true, "different state", nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
@ -135,31 +120,23 @@ func TestAWSDiskConflicts(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRBDDiskConflicts(t *testing.T) {
|
func TestRBDDiskConflicts(t *testing.T) {
|
||||||
volState := v1.PodSpec{
|
volState := v1.Volume{
|
||||||
Volumes: []v1.Volume{
|
VolumeSource: v1.VolumeSource{
|
||||||
{
|
RBD: &v1.RBDVolumeSource{
|
||||||
VolumeSource: v1.VolumeSource{
|
CephMonitors: []string{"a", "b"},
|
||||||
RBD: &v1.RBDVolumeSource{
|
RBDPool: "foo",
|
||||||
CephMonitors: []string{"a", "b"},
|
RBDImage: "bar",
|
||||||
RBDPool: "foo",
|
FSType: "ext4",
|
||||||
RBDImage: "bar",
|
|
||||||
FSType: "ext4",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
volState2 := v1.PodSpec{
|
volState2 := v1.Volume{
|
||||||
Volumes: []v1.Volume{
|
VolumeSource: v1.VolumeSource{
|
||||||
{
|
RBD: &v1.RBDVolumeSource{
|
||||||
VolumeSource: v1.VolumeSource{
|
CephMonitors: []string{"c", "d"},
|
||||||
RBD: &v1.RBDVolumeSource{
|
RBDPool: "foo",
|
||||||
CephMonitors: []string{"c", "d"},
|
RBDImage: "bar",
|
||||||
RBDPool: "foo",
|
FSType: "ext4",
|
||||||
RBDImage: "bar",
|
|
||||||
FSType: "ext4",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -172,9 +149,9 @@ func TestRBDDiskConflicts(t *testing.T) {
|
|||||||
wantStatus *framework.Status
|
wantStatus *framework.Status
|
||||||
}{
|
}{
|
||||||
{&v1.Pod{}, framework.NewNodeInfo(), true, "nothing", nil},
|
{&v1.Pod{}, framework.NewNodeInfo(), true, "nothing", nil},
|
||||||
{&v1.Pod{}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), true, "one state", nil},
|
{&v1.Pod{}, framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), true, "one state", nil},
|
||||||
{&v1.Pod{Spec: volState}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), false, "same state", errStatus},
|
{st.MakePod().Volume(volState).Obj(), framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), false, "same state", errStatus},
|
||||||
{&v1.Pod{Spec: volState2}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), true, "different state", nil},
|
{st.MakePod().Volume(volState2).Obj(), framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), true, "different state", nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
@ -191,31 +168,23 @@ func TestRBDDiskConflicts(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestISCSIDiskConflicts(t *testing.T) {
|
func TestISCSIDiskConflicts(t *testing.T) {
|
||||||
volState := v1.PodSpec{
|
volState := v1.Volume{
|
||||||
Volumes: []v1.Volume{
|
VolumeSource: v1.VolumeSource{
|
||||||
{
|
ISCSI: &v1.ISCSIVolumeSource{
|
||||||
VolumeSource: v1.VolumeSource{
|
TargetPortal: "127.0.0.1:3260",
|
||||||
ISCSI: &v1.ISCSIVolumeSource{
|
IQN: "iqn.2016-12.server:storage.target01",
|
||||||
TargetPortal: "127.0.0.1:3260",
|
FSType: "ext4",
|
||||||
IQN: "iqn.2016-12.server:storage.target01",
|
Lun: 0,
|
||||||
FSType: "ext4",
|
|
||||||
Lun: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
volState2 := v1.PodSpec{
|
volState2 := v1.Volume{
|
||||||
Volumes: []v1.Volume{
|
VolumeSource: v1.VolumeSource{
|
||||||
{
|
ISCSI: &v1.ISCSIVolumeSource{
|
||||||
VolumeSource: v1.VolumeSource{
|
TargetPortal: "127.0.0.1:3260",
|
||||||
ISCSI: &v1.ISCSIVolumeSource{
|
IQN: "iqn.2017-12.server:storage.target01",
|
||||||
TargetPortal: "127.0.0.1:3260",
|
FSType: "ext4",
|
||||||
IQN: "iqn.2017-12.server:storage.target01",
|
Lun: 0,
|
||||||
FSType: "ext4",
|
|
||||||
Lun: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -228,9 +197,9 @@ func TestISCSIDiskConflicts(t *testing.T) {
|
|||||||
wantStatus *framework.Status
|
wantStatus *framework.Status
|
||||||
}{
|
}{
|
||||||
{&v1.Pod{}, framework.NewNodeInfo(), true, "nothing", nil},
|
{&v1.Pod{}, framework.NewNodeInfo(), true, "nothing", nil},
|
||||||
{&v1.Pod{}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), true, "one state", nil},
|
{&v1.Pod{}, framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), true, "one state", nil},
|
||||||
{&v1.Pod{Spec: volState}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), false, "same state", errStatus},
|
{st.MakePod().Volume(volState).Obj(), framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), false, "same state", errStatus},
|
||||||
{&v1.Pod{Spec: volState2}, framework.NewNodeInfo(&v1.Pod{Spec: volState}), true, "different state", nil},
|
{st.MakePod().Volume(volState2).Obj(), framework.NewNodeInfo(st.MakePod().Volume(volState).Obj()), true, "different state", nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
@ -249,44 +218,10 @@ func TestISCSIDiskConflicts(t *testing.T) {
|
|||||||
func TestAccessModeConflicts(t *testing.T) {
|
func TestAccessModeConflicts(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, true)()
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, true)()
|
||||||
|
|
||||||
podWithReadWriteOncePodPVC := &v1.Pod{
|
// Required for querying lister for PVCs in the same namespace.
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
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.
|
// Required for querying lister for PVCs in the same namespace.
|
||||||
Namespace: "default",
|
podWithReadWriteManyPVC := st.MakePod().Name("pod-with-rwx").Namespace(metav1.NamespaceDefault).PVC("claim-with-rwx").Node("node-1").Obj()
|
||||||
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",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
node := &v1.Node{
|
node := &v1.Node{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
@ -26,24 +26,11 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework"
|
"k8s.io/kubernetes/pkg/scheduler/framework"
|
||||||
fakeframework "k8s.io/kubernetes/pkg/scheduler/framework/fake"
|
fakeframework "k8s.io/kubernetes/pkg/scheduler/framework/fake"
|
||||||
|
st "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func createPodWithVolume(pod, pv, pvc string) *v1.Pod {
|
func createPodWithVolume(pod, pv, pvc string) *v1.Pod {
|
||||||
return &v1.Pod{
|
return st.MakePod().Name(pod).Namespace(metav1.NamespaceDefault).PVC(pvc).Obj()
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: pod, Namespace: "default"},
|
|
||||||
Spec: v1.PodSpec{
|
|
||||||
Volumes: []v1.Volume{
|
|
||||||
{
|
|
||||||
Name: pv,
|
|
||||||
VolumeSource: v1.VolumeSource{
|
|
||||||
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
|
|
||||||
ClaimName: pvc,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSingleZone(t *testing.T) {
|
func TestSingleZone(t *testing.T) {
|
||||||
@ -100,9 +87,7 @@ func TestSingleZone(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "pod without volume",
|
name: "pod without volume",
|
||||||
Pod: &v1.Pod{
|
Pod: st.MakePod().Name("pod_1").Namespace(metav1.NamespaceDefault).Obj(),
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "pod_1", Namespace: "default"},
|
|
||||||
},
|
|
||||||
Node: &v1.Node{
|
Node: &v1.Node{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "host1",
|
Name: "host1",
|
||||||
|
Loading…
Reference in New Issue
Block a user