1
0
mirror of https://github.com/kubernetes-sigs/descheduler.git synced 2026-01-26 13:29:11 +01:00

Merge pull request #1795 from ingvagabund/podantiaffinity-unit-test

refactor(TestPodAntiAffinity): inline object creation
This commit is contained in:
Kubernetes Prow Robot
2025-12-15 05:53:45 -08:00
committed by GitHub

View File

@@ -33,84 +33,75 @@ import (
"sigs.k8s.io/descheduler/test"
)
func TestPodAntiAffinity(t *testing.T) {
node1 := test.BuildTestNode("n1", 2000, 3000, 10, func(node *v1.Node) {
node.ObjectMeta.Labels = map[string]string{
"region": "main-region",
}
})
node2 := test.BuildTestNode("n2", 2000, 3000, 10, func(node *v1.Node) {
node.ObjectMeta.Labels = map[string]string{
"datacenter": "east",
}
})
node3 := test.BuildTestNode("n3", 2000, 3000, 10, func(node *v1.Node) {
node.Spec = v1.NodeSpec{
Unschedulable: true,
}
})
node4 := test.BuildTestNode("n4", 2, 2, 1, nil)
node5 := test.BuildTestNode("n5", 200, 3000, 10, func(node *v1.Node) {
node.ObjectMeta.Labels = map[string]string{
"region": "main-region",
}
})
const (
nodeName1 = "n1"
nodeName2 = "n2"
nodeName3 = "n3"
nodeName4 = "n4"
nodeName5 = "n5"
)
p1 := test.BuildTestPod("p1", 100, 0, node1.Name, nil)
p2 := test.BuildTestPod("p2", 100, 0, node1.Name, nil)
p3 := test.BuildTestPod("p3", 100, 0, node1.Name, nil)
p4 := test.BuildTestPod("p4", 100, 0, node1.Name, nil)
p5 := test.BuildTestPod("p5", 100, 0, node1.Name, nil)
p6 := test.BuildTestPod("p6", 100, 0, node1.Name, nil)
p7 := test.BuildTestPod("p7", 100, 0, node1.Name, nil)
p8 := test.BuildTestPod("p8", 100, 0, node1.Name, nil)
p9 := test.BuildTestPod("p9", 100, 0, node1.Name, nil)
p10 := test.BuildTestPod("p10", 100, 0, node1.Name, nil)
p11 := test.BuildTestPod("p11", 100, 0, node5.Name, nil)
p9.DeletionTimestamp = &metav1.Time{}
p10.DeletionTimestamp = &metav1.Time{}
func buildTestNode(name string, apply func(*v1.Node)) *v1.Node {
return test.BuildTestNode(name, 2000, 3000, 10, apply)
}
criticalPriority := utils.SystemCriticalPriority
nonEvictablePod := test.BuildTestPod("non-evict", 100, 0, node1.Name, func(pod *v1.Pod) {
pod.Spec.Priority = &criticalPriority
})
p2.Labels = map[string]string{"foo": "bar"}
p5.Labels = map[string]string{"foo": "bar"}
p6.Labels = map[string]string{"foo": "bar"}
p7.Labels = map[string]string{"foo1": "bar1"}
p11.Labels = map[string]string{"foo": "bar"}
nonEvictablePod.Labels = map[string]string{"foo": "bar"}
test.SetNormalOwnerRef(p1)
test.SetNormalOwnerRef(p2)
test.SetNormalOwnerRef(p3)
test.SetNormalOwnerRef(p4)
test.SetNormalOwnerRef(p5)
test.SetNormalOwnerRef(p6)
test.SetNormalOwnerRef(p7)
test.SetNormalOwnerRef(p9)
test.SetNormalOwnerRef(p10)
test.SetNormalOwnerRef(p11)
// set pod anti affinity
test.SetPodAntiAffinity(p1, "foo", "bar")
test.SetPodAntiAffinity(p3, "foo", "bar")
test.SetPodAntiAffinity(p4, "foo", "bar")
test.SetPodAntiAffinity(p5, "foo1", "bar1")
test.SetPodAntiAffinity(p6, "foo1", "bar1")
test.SetPodAntiAffinity(p7, "foo", "bar")
test.SetPodAntiAffinity(p9, "foo", "bar")
test.SetPodAntiAffinity(p10, "foo", "bar")
// set pod priority
test.SetPodPriority(p5, 100)
test.SetPodPriority(p6, 50)
test.SetPodPriority(p7, 0)
// Set pod node selectors
p8.Spec.NodeSelector = map[string]string{
"datacenter": "west",
func setNodeMainRegionLabel(node *v1.Node) {
node.ObjectMeta.Labels = map[string]string{
"region": "main-region",
}
}
func buildTestNode1() *v1.Node {
return buildTestNode(nodeName1, setNodeMainRegionLabel)
}
func buildTestPod(name, nodeName string, apply func(*v1.Pod)) *v1.Pod {
return test.BuildTestPod(name, 100, 0, nodeName, apply)
}
func buildTestPodForNode1(name string, apply func(*v1.Pod)) *v1.Pod {
return buildTestPod(name, nodeName1, apply)
}
func setPodAntiAffinityFooBar(pod *v1.Pod) {
test.SetPodAntiAffinity(pod, "foo", "bar")
}
func setPodAntiAffinityFoo1Bar1(pod *v1.Pod) {
test.SetPodAntiAffinity(pod, "foo1", "bar1")
}
func setLabelsFooBar(pod *v1.Pod) {
pod.Labels = map[string]string{"foo": "bar"}
}
func setLabelsFoo1Bar1(pod *v1.Pod) {
pod.Labels = map[string]string{"foo1": "bar1"}
}
func buildTestPodWithAntiAffinityForNode1(name string) *v1.Pod {
return buildTestPodForNode1(name, func(pod *v1.Pod) {
test.SetNormalOwnerRef(pod)
setPodAntiAffinityFooBar(pod)
})
}
func buildTestPodP2ForNode1() *v1.Pod {
return buildTestPodForNode1("p2", func(pod *v1.Pod) {
test.SetNormalOwnerRef(pod)
setLabelsFooBar(pod)
})
}
func buildTestPodNonEvictableForNode1() *v1.Pod {
criticalPriority := utils.SystemCriticalPriority
return buildTestPodForNode1("non-evict", func(pod *v1.Pod) {
pod.Spec.Priority = &criticalPriority
setLabelsFooBar(pod)
})
}
func TestPodAntiAffinity(t *testing.T) {
var uint1 uint = 1
var uint3 uint = 3
@@ -125,87 +116,204 @@ func TestPodAntiAffinity(t *testing.T) {
nodes []*v1.Node
}{
{
description: "Maximum pods to evict - 0",
pods: []*v1.Pod{p1, p2, p3, p4},
nodes: []*v1.Node{node1},
description: "Maximum pods to evict - 0",
pods: []*v1.Pod{
buildTestPodWithAntiAffinityForNode1("p1"),
buildTestPodP2ForNode1(),
buildTestPodWithAntiAffinityForNode1("p3"),
buildTestPodWithAntiAffinityForNode1("p4"),
},
nodes: []*v1.Node{
buildTestNode1(),
},
expectedEvictedPodCount: 3,
},
{
description: "Maximum pods to evict - 3",
maxPodsToEvictPerNode: &uint3,
pods: []*v1.Pod{p1, p2, p3, p4},
nodes: []*v1.Node{node1},
description: "Maximum pods to evict - 3",
maxPodsToEvictPerNode: &uint3,
pods: []*v1.Pod{
buildTestPodWithAntiAffinityForNode1("p1"),
buildTestPodP2ForNode1(),
buildTestPodWithAntiAffinityForNode1("p3"),
buildTestPodWithAntiAffinityForNode1("p4"),
},
nodes: []*v1.Node{
buildTestNode1(),
},
expectedEvictedPodCount: 3,
},
{
description: "Maximum pods to evict (maxPodsToEvictPerNamespace=3) - 3",
maxNoOfPodsToEvictPerNamespace: &uint3,
pods: []*v1.Pod{p1, p2, p3, p4},
nodes: []*v1.Node{node1},
expectedEvictedPodCount: 3,
pods: []*v1.Pod{
buildTestPodWithAntiAffinityForNode1("p1"),
buildTestPodP2ForNode1(),
buildTestPodWithAntiAffinityForNode1("p3"),
buildTestPodWithAntiAffinityForNode1("p4"),
},
nodes: []*v1.Node{
buildTestNode1(),
},
expectedEvictedPodCount: 3,
},
{
description: "Maximum pods to evict (maxNoOfPodsToEvictTotal)",
maxNoOfPodsToEvictPerNamespace: &uint3,
maxNoOfPodsToEvictTotal: &uint1,
pods: []*v1.Pod{p1, p2, p3, p4},
nodes: []*v1.Node{node1},
expectedEvictedPodCount: 1,
},
{
description: "Evict only 1 pod after sorting",
pods: []*v1.Pod{p5, p6, p7},
nodes: []*v1.Node{node1},
pods: []*v1.Pod{
buildTestPodWithAntiAffinityForNode1("p1"),
buildTestPodP2ForNode1(),
buildTestPodWithAntiAffinityForNode1("p3"),
buildTestPodWithAntiAffinityForNode1("p4"),
},
nodes: []*v1.Node{
buildTestNode1(),
},
expectedEvictedPodCount: 1,
},
{
description: "Evicts pod that conflicts with critical pod (but does not evict critical pod)",
maxPodsToEvictPerNode: &uint1,
pods: []*v1.Pod{p1, nonEvictablePod},
nodes: []*v1.Node{node1},
description: "Evict only 1 pod after sorting",
pods: []*v1.Pod{
buildTestPodForNode1("p5", func(pod *v1.Pod) {
test.SetNormalOwnerRef(pod)
setLabelsFooBar(pod)
setPodAntiAffinityFoo1Bar1(pod)
test.SetPodPriority(pod, 100)
}),
buildTestPodForNode1("p6", func(pod *v1.Pod) {
test.SetNormalOwnerRef(pod)
setLabelsFooBar(pod)
setPodAntiAffinityFoo1Bar1(pod)
test.SetPodPriority(pod, 50)
}),
buildTestPodForNode1("p7", func(pod *v1.Pod) {
test.SetNormalOwnerRef(pod)
setLabelsFoo1Bar1(pod)
setPodAntiAffinityFooBar(pod)
test.SetPodPriority(pod, 0)
}),
},
nodes: []*v1.Node{
buildTestNode1(),
},
expectedEvictedPodCount: 1,
},
{
description: "Evicts pod that conflicts with critical pod (but does not evict critical pod)",
maxPodsToEvictPerNode: &uint1,
pods: []*v1.Pod{p1, nonEvictablePod},
nodes: []*v1.Node{node1},
description: "Evicts pod that conflicts with critical pod (but does not evict critical pod)",
maxPodsToEvictPerNode: &uint1,
pods: []*v1.Pod{
buildTestPodWithAntiAffinityForNode1("p1"),
buildTestPodNonEvictableForNode1(),
},
nodes: []*v1.Node{
buildTestNode1(),
},
expectedEvictedPodCount: 1,
},
{
description: "Won't evict pods because node selectors don't match available nodes",
maxPodsToEvictPerNode: &uint1,
pods: []*v1.Pod{p8, nonEvictablePod},
nodes: []*v1.Node{node1, node2},
description: "Evicts pod that conflicts with critical pod (but does not evict critical pod)",
maxPodsToEvictPerNode: &uint1,
pods: []*v1.Pod{
buildTestPodWithAntiAffinityForNode1("p1"),
buildTestPodNonEvictableForNode1(),
},
nodes: []*v1.Node{
buildTestNode1(),
},
expectedEvictedPodCount: 1,
},
{
description: "Won't evict pods because node selectors don't match available nodes",
maxPodsToEvictPerNode: &uint1,
pods: []*v1.Pod{
buildTestPodForNode1("p8", func(pod *v1.Pod) {
pod.Spec.NodeSelector = map[string]string{
"datacenter": "west",
}
}),
buildTestPodNonEvictableForNode1(),
},
nodes: []*v1.Node{
buildTestNode1(),
buildTestNode(nodeName2, func(node *v1.Node) {
node.ObjectMeta.Labels = map[string]string{
"datacenter": "east",
}
}),
},
expectedEvictedPodCount: 0,
nodeFit: true,
},
{
description: "Won't evict pods because only other node is not schedulable",
maxPodsToEvictPerNode: &uint1,
pods: []*v1.Pod{p8, nonEvictablePod},
nodes: []*v1.Node{node1, node3},
description: "Won't evict pods because only other node is not schedulable",
maxPodsToEvictPerNode: &uint1,
pods: []*v1.Pod{
buildTestPodForNode1("p8", func(pod *v1.Pod) {
pod.Spec.NodeSelector = map[string]string{
"datacenter": "west",
}
}),
buildTestPodNonEvictableForNode1(),
},
nodes: []*v1.Node{
buildTestNode1(),
buildTestNode(nodeName3, func(node *v1.Node) {
node.Spec = v1.NodeSpec{
Unschedulable: true,
}
}),
},
expectedEvictedPodCount: 0,
nodeFit: true,
},
{
description: "No pod to evicted since all pod terminating",
pods: []*v1.Pod{p9, p10},
nodes: []*v1.Node{node1},
description: "No pod to evicted since all pod terminating",
pods: []*v1.Pod{
buildTestPodForNode1("p9", func(pod *v1.Pod) {
test.SetNormalOwnerRef(pod)
setPodAntiAffinityFooBar(pod)
pod.DeletionTimestamp = &metav1.Time{}
}),
buildTestPodForNode1("p10", func(pod *v1.Pod) {
test.SetNormalOwnerRef(pod)
setPodAntiAffinityFooBar(pod)
pod.DeletionTimestamp = &metav1.Time{}
}),
},
nodes: []*v1.Node{
buildTestNode1(),
},
expectedEvictedPodCount: 0,
},
{
description: "Won't evict pods because only other node doesn't have enough resources",
maxPodsToEvictPerNode: &uint3,
pods: []*v1.Pod{p1, p2, p3, p4},
nodes: []*v1.Node{node1, node4},
description: "Won't evict pods because only other node doesn't have enough resources",
maxPodsToEvictPerNode: &uint3,
pods: []*v1.Pod{
buildTestPodWithAntiAffinityForNode1("p1"),
buildTestPodP2ForNode1(),
buildTestPodWithAntiAffinityForNode1("p3"),
buildTestPodWithAntiAffinityForNode1("p4"),
},
nodes: []*v1.Node{
buildTestNode1(),
test.BuildTestNode(nodeName4, 2, 2, 1, nil),
},
expectedEvictedPodCount: 0,
nodeFit: true,
},
{
description: "Evict pod violating anti-affinity among different node (all pods have anti-affinity)",
pods: []*v1.Pod{p1, p11},
nodes: []*v1.Node{node1, node5},
description: "Evict pod violating anti-affinity among different node (all pods have anti-affinity)",
pods: []*v1.Pod{
buildTestPodWithAntiAffinityForNode1("p1"),
buildTestPod("p11", nodeName5, func(pod *v1.Pod) {
test.SetNormalOwnerRef(pod)
setLabelsFooBar(pod)
}),
},
nodes: []*v1.Node{
buildTestNode1(),
test.BuildTestNode(nodeName5, 200, 3000, 10, setNodeMainRegionLabel),
},
expectedEvictedPodCount: 1,
nodeFit: false,
},