mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	add integration test for podtopologyspread in requeueing scenarios
This commit is contained in:
		@@ -378,27 +378,6 @@ func TestCoreResourceEnqueue(t *testing.T) {
 | 
			
		||||
				return nil
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:         "Pods with PodTopologySpread should be requeued when a Pod with matching label is scheduled",
 | 
			
		||||
			initialNodes: []*v1.Node{st.MakeNode().Name("fake-node").Label("node", "fake-node").Capacity(map[v1.ResourceName]string{v1.ResourceCPU: "2"}).Obj()},
 | 
			
		||||
			initialPods: []*v1.Pod{
 | 
			
		||||
				st.MakePod().Name("pod1").Label("key", "val").Container("image").Node("fake-node").Obj(),
 | 
			
		||||
			},
 | 
			
		||||
			pods: []*v1.Pod{
 | 
			
		||||
				// - Pod2 will be rejected by the PodTopologySpread plugin.
 | 
			
		||||
				st.MakePod().Name("pod2").Label("key", "val").SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("key").Obj(), ptr.To(int32(3)), nil, nil, nil).Container("image").Obj(),
 | 
			
		||||
			},
 | 
			
		||||
			triggerFn: func(testCtx *testutils.TestContext) error {
 | 
			
		||||
				// Trigger an assigned Pod add event.
 | 
			
		||||
				pod := st.MakePod().Name("pod3").Label("key", "val").Node("fake-node").Container("image").Obj()
 | 
			
		||||
				if _, err := testCtx.ClientSet.CoreV1().Pods(testCtx.NS.Name).Create(testCtx.Ctx, pod, metav1.CreateOptions{}); err != nil {
 | 
			
		||||
					return fmt.Errorf("failed to create Pod %q: %w", pod.Name, err)
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return nil
 | 
			
		||||
			},
 | 
			
		||||
			wantRequeuedPods: sets.New("pod2"),
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:         "Pod rejected by the PodAffinity plugin is requeued when deleting the existed pod's label to make it match the podAntiAffinity",
 | 
			
		||||
			initialNodes: []*v1.Node{st.MakeNode().Name("fake-node").Label("node", "fake-node").Obj()},
 | 
			
		||||
@@ -507,6 +486,160 @@ func TestCoreResourceEnqueue(t *testing.T) {
 | 
			
		||||
			wantRequeuedPods:          sets.New("pod2"),
 | 
			
		||||
			enableSchedulingQueueHint: []bool{true},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:         "Pods with PodTopologySpread should be requeued when a Pod with matching label is scheduled",
 | 
			
		||||
			initialNodes: []*v1.Node{st.MakeNode().Name("fake-node").Label("node", "fake-node").Capacity(map[v1.ResourceName]string{v1.ResourceCPU: "2"}).Obj()},
 | 
			
		||||
			initialPods: []*v1.Pod{
 | 
			
		||||
				st.MakePod().Name("pod1").Label("key1", "val").Container("image").Node("fake-node").Obj(),
 | 
			
		||||
				st.MakePod().Name("pod2").Label("key2", "val").Container("image").Node("fake-node").Obj(),
 | 
			
		||||
			},
 | 
			
		||||
			pods: []*v1.Pod{
 | 
			
		||||
				// - Pod3 and Pod4 will be rejected by the PodTopologySpread plugin.
 | 
			
		||||
				st.MakePod().Name("pod3").Label("key1", "val").SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("key1").Obj(), ptr.To(int32(3)), nil, nil, nil).Container("image").Obj(),
 | 
			
		||||
				st.MakePod().Name("pod4").Label("key2", "val").SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("key2").Obj(), ptr.To(int32(3)), nil, nil, nil).Container("image").Obj(),
 | 
			
		||||
			},
 | 
			
		||||
			triggerFn: func(testCtx *testutils.TestContext) error {
 | 
			
		||||
				// Trigger an assigned Pod add event.
 | 
			
		||||
				// It should requeue pod3 only because this pod only has key1 label that pod3's topologyspread checks, and doesn't have key2 label that pod4's one does.
 | 
			
		||||
				pod := st.MakePod().Name("pod5").Label("key1", "val").Node("fake-node").Container("image").Obj()
 | 
			
		||||
				if _, err := testCtx.ClientSet.CoreV1().Pods(testCtx.NS.Name).Create(testCtx.Ctx, pod, metav1.CreateOptions{}); err != nil {
 | 
			
		||||
					return fmt.Errorf("failed to create Pod %q: %w", pod.Name, err)
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return nil
 | 
			
		||||
			},
 | 
			
		||||
			wantRequeuedPods:          sets.New("pod3"),
 | 
			
		||||
			enableSchedulingQueueHint: []bool{true},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:         "Pods with PodTopologySpread should be requeued when a scheduled Pod label is updated to match the selector",
 | 
			
		||||
			initialNodes: []*v1.Node{st.MakeNode().Name("fake-node").Label("node", "fake-node").Capacity(map[v1.ResourceName]string{v1.ResourceCPU: "2"}).Obj()},
 | 
			
		||||
			initialPods: []*v1.Pod{
 | 
			
		||||
				st.MakePod().Name("pod1").Label("key1", "val").Container("image").Node("fake-node").Obj(),
 | 
			
		||||
				st.MakePod().Name("pod2").Label("key2", "val").Container("image").Node("fake-node").Obj(),
 | 
			
		||||
			},
 | 
			
		||||
			pods: []*v1.Pod{
 | 
			
		||||
				// - Pod3 and Pod4 will be rejected by the PodTopologySpread plugin.
 | 
			
		||||
				st.MakePod().Name("pod3").Label("key1", "val").SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("key1").Obj(), ptr.To(int32(3)), nil, nil, nil).Container("image").Obj(),
 | 
			
		||||
				st.MakePod().Name("pod4").Label("key2", "val").SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("key2").Obj(), ptr.To(int32(3)), nil, nil, nil).Container("image").Obj(),
 | 
			
		||||
			},
 | 
			
		||||
			triggerFn: func(testCtx *testutils.TestContext) error {
 | 
			
		||||
				// Trigger an assigned Pod update event.
 | 
			
		||||
				// It should requeue pod3 only because this updated pod had key1 label,
 | 
			
		||||
				// and it's related only to the label selector that pod3's topologyspread has.
 | 
			
		||||
				if _, err := testCtx.ClientSet.CoreV1().Pods(testCtx.NS.Name).Update(testCtx.Ctx, st.MakePod().Name("pod1").Label("key3", "val").Container("image").Node("fake-node").Obj(), metav1.UpdateOptions{}); err != nil {
 | 
			
		||||
					return fmt.Errorf("failed to update the pod: %w", err)
 | 
			
		||||
				}
 | 
			
		||||
				return nil
 | 
			
		||||
			},
 | 
			
		||||
			wantRequeuedPods:          sets.New("pod3"),
 | 
			
		||||
			enableSchedulingQueueHint: []bool{true},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:         "Pods with PodTopologySpread should be requeued when a scheduled Pod with matching label is deleted",
 | 
			
		||||
			initialNodes: []*v1.Node{st.MakeNode().Name("fake-node").Label("node", "fake-node").Capacity(map[v1.ResourceName]string{v1.ResourceCPU: "2"}).Obj()},
 | 
			
		||||
			initialPods: []*v1.Pod{
 | 
			
		||||
				st.MakePod().Name("pod1").Label("key1", "val").Container("image").Node("fake-node").Obj(),
 | 
			
		||||
				st.MakePod().Name("pod2").Label("key2", "val").Container("image").Node("fake-node").Obj(),
 | 
			
		||||
			},
 | 
			
		||||
			pods: []*v1.Pod{
 | 
			
		||||
				// - Pod3 and Pod4 will be rejected by the PodTopologySpread plugin.
 | 
			
		||||
				st.MakePod().Name("pod3").Label("key1", "val").SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("key1").Obj(), ptr.To(int32(2)), nil, nil, nil).Container("image").Obj(),
 | 
			
		||||
				st.MakePod().Name("pod4").Label("key2", "val").SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("key2").Obj(), ptr.To(int32(3)), nil, nil, nil).Container("image").Obj(),
 | 
			
		||||
			},
 | 
			
		||||
			triggerFn: func(testCtx *testutils.TestContext) error {
 | 
			
		||||
				// Trigger an assigned Pod delete event.
 | 
			
		||||
				// It should requeue pod3 only because this pod only has key1 label that pod3's topologyspread checks, and doesn't have key2 label that pod4's one does.
 | 
			
		||||
				if err := testCtx.ClientSet.CoreV1().Pods(testCtx.NS.Name).Delete(testCtx.Ctx, "pod1", metav1.DeleteOptions{GracePeriodSeconds: new(int64)}); err != nil {
 | 
			
		||||
					return fmt.Errorf("failed to delete Pod: %w", err)
 | 
			
		||||
				}
 | 
			
		||||
				return nil
 | 
			
		||||
			},
 | 
			
		||||
			wantRequeuedPods:          sets.New("pod3"),
 | 
			
		||||
			enableSchedulingQueueHint: []bool{true},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Pods with PodTopologySpread should be requeued when a Node with topology label is created",
 | 
			
		||||
			initialNodes: []*v1.Node{
 | 
			
		||||
				st.MakeNode().Name("fake-node1").Label("node", "fake-node").Obj(),
 | 
			
		||||
				st.MakeNode().Name("fake-node2").Label("zone", "fake-zone").Obj(),
 | 
			
		||||
			},
 | 
			
		||||
			initialPods: []*v1.Pod{
 | 
			
		||||
				st.MakePod().Name("pod1").Label("key1", "val").Container("image").Node("fake-node1").Obj(),
 | 
			
		||||
				st.MakePod().Name("pod2").Label("key1", "val").Container("image").Node("fake-node2").Obj(),
 | 
			
		||||
			},
 | 
			
		||||
			pods: []*v1.Pod{
 | 
			
		||||
				// - Pod3 and Pod4 will be rejected by the PodTopologySpread plugin.
 | 
			
		||||
				st.MakePod().Name("pod3").Label("key1", "val").SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("key1").Obj(), ptr.To(int32(2)), nil, nil, nil).Container("image").Obj(),
 | 
			
		||||
				st.MakePod().Name("pod4").Label("key1", "val").SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("key1").Obj(), ptr.To(int32(2)), nil, nil, nil).Container("image").Obj(),
 | 
			
		||||
			},
 | 
			
		||||
			triggerFn: func(testCtx *testutils.TestContext) error {
 | 
			
		||||
				// Trigger an assigned Node add event.
 | 
			
		||||
				// It should requeue pod3 only because this node only has node label, and doesn't have zone label that pod4's topologyspread requires.
 | 
			
		||||
				node := st.MakeNode().Name("fake-node3").Label("node", "fake-node").Obj()
 | 
			
		||||
				if _, err := testCtx.ClientSet.CoreV1().Nodes().Create(testCtx.Ctx, node, metav1.CreateOptions{}); err != nil {
 | 
			
		||||
					return fmt.Errorf("failed to create a new node: %w", err)
 | 
			
		||||
				}
 | 
			
		||||
				return nil
 | 
			
		||||
			},
 | 
			
		||||
			wantRequeuedPods:          sets.New("pod3"),
 | 
			
		||||
			enableSchedulingQueueHint: []bool{true},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Pods with PodTopologySpread should be requeued when a Node is updated to have the topology label",
 | 
			
		||||
			initialNodes: []*v1.Node{
 | 
			
		||||
				st.MakeNode().Name("fake-node1").Label("node", "fake-node").Obj(),
 | 
			
		||||
				st.MakeNode().Name("fake-node2").Label("node", "fake-node").Obj(),
 | 
			
		||||
			},
 | 
			
		||||
			initialPods: []*v1.Pod{
 | 
			
		||||
				st.MakePod().Name("pod1").Label("key1", "val").SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("key1").Obj(), nil, nil, nil, nil).Container("image").Node("fake-node1").Obj(),
 | 
			
		||||
				st.MakePod().Name("pod2").Label("key1", "val").SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("key1").Obj(), nil, nil, nil, nil).Container("image").Node("fake-node2").Obj(),
 | 
			
		||||
			},
 | 
			
		||||
			pods: []*v1.Pod{
 | 
			
		||||
				// - Pod3 and Pod4 will be rejected by the PodTopologySpread plugin.
 | 
			
		||||
				st.MakePod().Name("pod3").Label("key1", "val").SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("key1").Obj(), ptr.To(int32(3)), nil, nil, nil).Container("image").Obj(),
 | 
			
		||||
				st.MakePod().Name("pod4").Label("key1", "val").SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("key1").Obj(), ptr.To(int32(3)), nil, nil, nil).Container("image").Obj(),
 | 
			
		||||
			},
 | 
			
		||||
			triggerFn: func(testCtx *testutils.TestContext) error {
 | 
			
		||||
				// Trigger an assigned Node update event.
 | 
			
		||||
				// It should requeue pod4 only because this node only has zone label, and doesn't have node label that pod3 requires.
 | 
			
		||||
				node := st.MakeNode().Name("fake-node2").Label("zone", "fake-node").Obj()
 | 
			
		||||
				if _, err := testCtx.ClientSet.CoreV1().Nodes().Update(testCtx.Ctx, node, metav1.UpdateOptions{}); err != nil {
 | 
			
		||||
					return fmt.Errorf("failed to update node: %w", err)
 | 
			
		||||
				}
 | 
			
		||||
				return nil
 | 
			
		||||
			},
 | 
			
		||||
			wantRequeuedPods:          sets.New("pod4"),
 | 
			
		||||
			enableSchedulingQueueHint: []bool{true},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "Pods with PodTopologySpread should be requeued when a NodeTaint of a Node with a topology label has been updated",
 | 
			
		||||
			initialNodes: []*v1.Node{
 | 
			
		||||
				st.MakeNode().Name("fake-node1").Label("node", "fake-node").Obj(),
 | 
			
		||||
				st.MakeNode().Name("fake-node2").Label("zone", "fake-node").Obj(),
 | 
			
		||||
				st.MakeNode().Name("fake-node3").Label("zone", "fake-node").Taints([]v1.Taint{{Key: v1.TaintNodeNotReady, Effect: v1.TaintEffectNoSchedule}}).Obj(),
 | 
			
		||||
			},
 | 
			
		||||
			initialPods: []*v1.Pod{
 | 
			
		||||
				st.MakePod().Name("pod1").Label("key1", "val").SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("key1").Obj(), nil, nil, nil, nil).Container("image").Node("fake-node1").Obj(),
 | 
			
		||||
				st.MakePod().Name("pod2").Label("key1", "val").SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("key1").Obj(), nil, nil, nil, nil).Container("image").Node("fake-node2").Obj(),
 | 
			
		||||
			},
 | 
			
		||||
			pods: []*v1.Pod{
 | 
			
		||||
				// - Pod3 and Pod4 will be rejected by the PodTopologySpread plugin.
 | 
			
		||||
				st.MakePod().Name("pod3").Label("key1", "val").SpreadConstraint(1, "node", v1.DoNotSchedule, st.MakeLabelSelector().Exists("key1").Obj(), ptr.To(int32(3)), nil, nil, nil).Container("image").Obj(),
 | 
			
		||||
				st.MakePod().Name("pod4").Label("key1", "val").SpreadConstraint(1, "zone", v1.DoNotSchedule, st.MakeLabelSelector().Exists("key1").Obj(), ptr.To(int32(3)), nil, nil, nil).Container("image").Toleration("aaa").Obj(),
 | 
			
		||||
			},
 | 
			
		||||
			triggerFn: func(testCtx *testutils.TestContext) error {
 | 
			
		||||
				// Trigger an assigned NodeTaint update event.
 | 
			
		||||
				// It should requeue pod4 only because this node only has zone label, and doesn't have node label that pod3 requires.
 | 
			
		||||
				node := st.MakeNode().Name("fake-node3").Label("zone", "fake-node").Taints([]v1.Taint{{Key: "aaa", Value: "bbb", Effect: v1.TaintEffectNoSchedule}}).Obj()
 | 
			
		||||
				if _, err := testCtx.ClientSet.CoreV1().Nodes().Update(testCtx.Ctx, node, metav1.UpdateOptions{}); err != nil {
 | 
			
		||||
					return fmt.Errorf("failed to update node: %w", err)
 | 
			
		||||
				}
 | 
			
		||||
				return nil
 | 
			
		||||
			},
 | 
			
		||||
			wantRequeuedPods:          sets.New("pod4"),
 | 
			
		||||
			enableSchedulingQueueHint: []bool{true},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user