From 237fbde8b1eec30f5ac4bd61940f2b64c2decc67 Mon Sep 17 00:00:00 2001 From: Natasha Sarkar Date: Thu, 10 Jul 2025 22:30:21 +0000 Subject: [PATCH] clean up e2e test and sorting code --- pkg/kubelet/allocation/allocation_manager.go | 78 +++++++------- .../allocation/allocation_manager_test.go | 94 ++++++++-------- test/e2e/node/pod_resize.go | 102 ++++++++---------- 3 files changed, 128 insertions(+), 146 deletions(-) diff --git a/pkg/kubelet/allocation/allocation_manager.go b/pkg/kubelet/allocation/allocation_manager.go index 3f3418446f7..9510b4d05b0 100644 --- a/pkg/kubelet/allocation/allocation_manager.go +++ b/pkg/kubelet/allocation/allocation_manager.go @@ -21,7 +21,6 @@ import ( "fmt" "path/filepath" "slices" - "sort" "sync" "time" @@ -31,6 +30,7 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" utilfeature "k8s.io/apiserver/pkg/util/feature" + resourcehelper "k8s.io/component-helpers/resource" "k8s.io/klog/v2" podutil "k8s.io/kubernetes/pkg/api/v1/pod" "k8s.io/kubernetes/pkg/api/v1/resource" @@ -288,25 +288,26 @@ func (m *manager) PushPendingResize(uid types.UID) { // - Third, based on the pod's QoS class. // - Last, prioritizing resizes that have been in the deferred state the longest. func (m *manager) sortPendingResizes() { - sort.Slice(m.podsWithPendingResizes, func(i, j int) bool { - firstPod, found := m.getPodByUID(m.podsWithPendingResizes[i]) + var pendingPods []*v1.Pod + for _, uid := range m.podsWithPendingResizes { + pod, found := m.getPodByUID(uid) if !found { - return false - } - secondPod, found := m.getPodByUID(m.podsWithPendingResizes[j]) - if !found { - return false + klog.V(4).InfoS("Pod not found; removing from pending resizes", "podUID", uid) + continue } + pendingPods = append(pendingPods, pod) + } + slices.SortFunc(pendingPods, func(firstPod, secondPod *v1.Pod) int { // First, resizes that don't increase requests will be prioritized. // These resizes are expected to always succeed. - firstPodIncreasing := m.isResizeIncreasingAnyRequests(firstPod) - secondPodIncreasing := m.isResizeIncreasingAnyRequests(secondPod) + firstPodIncreasing := m.isResizeIncreasingRequests(firstPod) + secondPodIncreasing := m.isResizeIncreasingRequests(secondPod) if !firstPodIncreasing { - return true + return -1 } if !secondPodIncreasing { - return false + return 1 } // Second, pods with a higher PriorityClass will be prioritized. @@ -319,10 +320,10 @@ func (m *manager) sortPendingResizes() { secondPodPriority = *secondPod.Spec.Priority } if firstPodPriority > secondPodPriority { - return true + return -1 } if secondPodPriority > firstPodPriority { - return false + return 1 } // Third, pods with a higher QoS class will be prioritized, where guaranteed > burstable. @@ -330,10 +331,10 @@ func (m *manager) sortPendingResizes() { firstPodQOS := v1qos.GetPodQOS(firstPod) secondPodQOS := v1qos.GetPodQOS(secondPod) if firstPodQOS == v1.PodQOSGuaranteed && secondPodQOS != v1.PodQOSGuaranteed { - return true + return -1 } if secondPodQOS == v1.PodQOSGuaranteed && firstPodQOS != v1.PodQOSGuaranteed { - return false + return 1 } // If all else is the same, resize requests that have been pending longer will be @@ -353,45 +354,38 @@ func (m *manager) sortPendingResizes() { } } if firstPodLastTransitionTime == nil { - return false + return 1 } if secondPodLastTransitionTime == nil { - return true + return -1 } - return firstPodLastTransitionTime.Before(secondPodLastTransitionTime) + if firstPodLastTransitionTime.Before(secondPodLastTransitionTime) { + return -1 + } + return 1 }) + + m.podsWithPendingResizes = make([]types.UID, len(pendingPods)) + for i, pod := range pendingPods { + m.podsWithPendingResizes[i] = pod.UID + } } -// isResizeIncreasingAnyRequests returns true if any of the resource requests are increasing. -func (m *manager) isResizeIncreasingAnyRequests(pod *v1.Pod) bool { +// isResizeIncreasingRequests returns true if any of the resource requests are increasing. +func (m *manager) isResizeIncreasingRequests(pod *v1.Pod) bool { allocatedPod, updated := m.UpdatePodFromAllocation(pod) if !updated { return false } - if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources) { - if isResizeIncreasingAnyRequestsForContainer(allocatedPod.Spec.Resources, pod.Spec.Resources) { - return true - } + opts := resourcehelper.PodResourcesOptions{ + SkipPodLevelResources: !utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources), } + oldRequest := resourcehelper.PodRequests(allocatedPod, opts) + newRequest := resourcehelper.PodRequests(pod, opts) - for c, cType := range podutil.ContainerIter(&pod.Spec, podutil.InitContainers|podutil.Containers) { - if !isResizableContainer(c, cType) { - continue - } - allocatedContainer, found := m.GetContainerResourceAllocation(pod.UID, c.Name) - if !found || isResizeIncreasingAnyRequestsForContainer(&allocatedContainer, &c.Resources) { - return true - } - } - - return false -} - -// isResizeNonIncreasingForContainer returns true only if none of the resources requests are increasing. -// Resource limits are not considered for pod admission, so they are left out of the check here. -func isResizeIncreasingAnyRequestsForContainer(old *v1.ResourceRequirements, new *v1.ResourceRequirements) bool { - return new.Requests.Cpu().Cmp(*old.Requests.Cpu()) > 0 || new.Requests.Memory().Cmp(*old.Requests.Memory()) > 0 + return newRequest.Memory().Cmp(*oldRequest.Memory()) > 0 || + newRequest.Cpu().Cmp(*oldRequest.Cpu()) > 0 } // GetContainerResourceAllocation returns the last checkpointed AllocatedResources values diff --git a/pkg/kubelet/allocation/allocation_manager_test.go b/pkg/kubelet/allocation/allocation_manager_test.go index 5feb3e466bb..8fba78200e5 100644 --- a/pkg/kubelet/allocation/allocation_manager_test.go +++ b/pkg/kubelet/allocation/allocation_manager_test.go @@ -1020,7 +1020,7 @@ func TestHandlePodResourcesResizeWithSwap(t *testing.T) { } } -func TestIsResizeIncreasingAnyRequests(t *testing.T) { +func TestIsResizeIncreasingRequests(t *testing.T) { cpu500m := resource.MustParse("500m") cpu1000m := resource.MustParse("1") cpu1500m := resource.MustParse("1500m") @@ -1028,48 +1028,6 @@ func TestIsResizeIncreasingAnyRequests(t *testing.T) { mem1000M := resource.MustParse("1Gi") mem1500M := resource.MustParse("1500Mi") - testPod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - UID: "1111", - Name: "pod1", - Namespace: "ns1", - }, - Spec: v1.PodSpec{ - Containers: []v1.Container{ - { - Name: "c1", - Image: "i1", - Resources: v1.ResourceRequirements{ - Requests: v1.ResourceList{v1.ResourceCPU: cpu1000m, v1.ResourceMemory: mem1000M}, - }, - }, - { - Name: "c2", - Image: "i2", - Resources: v1.ResourceRequirements{ - Requests: v1.ResourceList{v1.ResourceCPU: cpu1000m, v1.ResourceMemory: mem1000M}, - }, - }, - { - Name: "c3", - Image: "i3", - Resources: v1.ResourceRequirements{ - Requests: v1.ResourceList{}, - }, - }, - { - Name: "c4", - Image: "i4", - Resources: v1.ResourceRequirements{ - Requests: nil, - }, - }, - }, - }, - } - allocationManager := makeAllocationManager(t, &containertest.FakeRuntime{}, []*v1.Pod{testPod}) - require.NoError(t, allocationManager.SetAllocatedResources(testPod)) - tests := []struct { name string newRequests map[int]v1.ResourceList @@ -1096,12 +1054,12 @@ func TestIsResizeIncreasingAnyRequests(t *testing.T) { expected: true, }, { - name: "increase one container, decrease another container", + name: "increase one container, decrease another container, net neutral", newRequests: map[int]v1.ResourceList{ 0: {v1.ResourceCPU: cpu1500m, v1.ResourceMemory: mem1500M}, 1: {v1.ResourceCPU: cpu500m, v1.ResourceMemory: mem500M}, }, - expected: true, + expected: false, }, { name: "decrease requests, two containers", @@ -1135,15 +1093,57 @@ func TestIsResizeIncreasingAnyRequests(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { + testPod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + UID: "1111", + Name: "pod1", + Namespace: "ns1", + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "c1", + Image: "i1", + Resources: v1.ResourceRequirements{ + Requests: v1.ResourceList{v1.ResourceCPU: cpu1000m, v1.ResourceMemory: mem1000M}, + }, + }, + { + Name: "c2", + Image: "i2", + Resources: v1.ResourceRequirements{ + Requests: v1.ResourceList{v1.ResourceCPU: cpu1000m, v1.ResourceMemory: mem1000M}, + }, + }, + { + Name: "c3", + Image: "i3", + Resources: v1.ResourceRequirements{ + Requests: v1.ResourceList{}, + }, + }, + { + Name: "c4", + Image: "i4", + Resources: v1.ResourceRequirements{ + Requests: nil, + }, + }, + }, + }, + } + allocationManager := makeAllocationManager(t, &containertest.FakeRuntime{}, []*v1.Pod{testPod}) + require.NoError(t, allocationManager.SetAllocatedResources(testPod)) + for k, v := range tc.newRequests { testPod.Spec.Containers[k].Resources.Requests = v } - require.Equal(t, tc.expected, allocationManager.(*manager).isResizeIncreasingAnyRequests(testPod)) + require.Equal(t, tc.expected, allocationManager.(*manager).isResizeIncreasingRequests(testPod)) }) } } -func TestSortPendingPodsByPriority(t *testing.T) { +func TestSortPendingResizes(t *testing.T) { cpu500m := resource.MustParse("500m") cpu1000m := resource.MustParse("1") cpu1500m := resource.MustParse("1500m") diff --git a/test/e2e/node/pod_resize.go b/test/e2e/node/pod_resize.go index 3ac05695abb..99375702f96 100644 --- a/test/e2e/node/pod_resize.go +++ b/test/e2e/node/pod_resize.go @@ -378,9 +378,7 @@ func doPodResizeSchedulerTests(f *framework.Framework) { testPod1.Name, types.StrategicMergePatchType, []byte(patchTestpod1ExceedNodeAvailable), metav1.PatchOptions{}, "resize") framework.ExpectNoError(p1Err, "failed to patch pod for resize") gomega.Expect(testPod1.Generation).To(gomega.BeEquivalentTo(3)) - framework.ExpectNoError(e2epod.WaitForPodCondition(ctx, f.ClientSet, testPod1.Namespace, testPod1.Name, "display pod resize status as deferred", f.Timeouts.PodStart, func(pod *v1.Pod) (bool, error) { - return helpers.IsPodResizeDeferred(pod), nil - })) + waitForPodDeferred(ctx, f, testPod1) ginkgo.By("deleting pods 2 and 3") delErr2 := e2epod.DeletePodWithWait(ctx, f.ClientSet, testPod2) @@ -415,18 +413,18 @@ func doPodResizeSchedulerTests(f *framework.Framework) { } func doPodResizeRetryDeferredTests(f *framework.Framework) { - ginkgo.It("pod-resize-retry-deferred-tests", func(ctx context.Context) { + ginkgo.It("pod-resize-retry-deferred-test-1", func(ctx context.Context) { + // Deferred resize E2E test case #1: + // 1. Create pod1 and pod2 and pod3 on node. + // 2. Resize pod3 to request more cpu than available, verify the resize is deferred. + // 3. Resize pod1 down to make space for pod3, verify pod3's resize has completed. + podClient := e2epod.NewPodClient(f) nodes, err := e2enode.GetReadySchedulableNodes(ctx, f.ClientSet) framework.ExpectNoError(err, "failed to get running nodes") gomega.Expect(nodes.Items).ShouldNot(gomega.BeEmpty()) framework.Logf("Found %d schedulable nodes", len(nodes.Items)) - // Deferred resize E2E test case #1: - // 1. Create pod1 and pod2 and pod3 on node. - // 2. Resize pod3 to request more cpu than available, verify the resize is deferred. - // 3. Resize pod1 down to make space for pod3, verify pod3's resize has completed. - ginkgo.By("Find node CPU resources available for allocation!") node := nodes.Items[0] nodeAllocatableMilliCPU, nodeAvailableMilliCPU := getNodeAllocatableAndAvailableMilliCPUValues(ctx, f, &node) @@ -520,9 +518,7 @@ func doPodResizeRetryDeferredTests(f *framework.Framework) { testPod3, p3Err := f.ClientSet.CoreV1().Pods(testPod3.Namespace).Patch(ctx, testPod3.Name, types.StrategicMergePatchType, []byte(patchTestpod3ToDeferred), metav1.PatchOptions{}, "resize") framework.ExpectNoError(p3Err, "failed to patch pod for resize") - framework.ExpectNoError(e2epod.WaitForPodCondition(ctx, f.ClientSet, testPod3.Namespace, testPod3.Name, "display pod resize status as deferred", f.Timeouts.PodStart, func(pod *v1.Pod) (bool, error) { - return helpers.IsPodResizeDeferred(pod), nil - })) + waitForPodDeferred(ctx, f, testPod3) ginkgo.By(fmt.Sprintf("Resize pod '%s' to make enough space for pod '%s'", testPod1.Name, testPod3.Name)) testPod1, p1Err := f.ClientSet.CoreV1().Pods(testPod1.Namespace).Patch(ctx, @@ -547,7 +543,9 @@ func doPodResizeRetryDeferredTests(f *framework.Framework) { framework.ExpectNoError(delErr2, "failed to delete pod %s", testPod2.Name) delErr3 := e2epod.DeletePodWithWait(ctx, f.ClientSet, testPod3) framework.ExpectNoError(delErr3, "failed to delete pod %s", testPod3.Name) + }) + ginkgo.It("pod-resize-retry-deferred-test-2", func(ctx context.Context) { // Deferred resize E2E test case #2: // 1. Create 5 pods on the node, where the first one has 2/3 of the node allocatable CPU, // and the remaining ones each have 1/16 of the node allocatable CPU. @@ -555,10 +553,16 @@ func doPodResizeRetryDeferredTests(f *framework.Framework) { // 3. Delete the first pod, verify the pod with the highest priority has its resize accepted. // 4. Repeat step 3 until all but the last pod has been deleted. - ginkgo.By("Find node CPU and memory resources available for allocation!") - node = nodes.Items[0] + podClient := e2epod.NewPodClient(f) + nodes, err := e2enode.GetReadySchedulableNodes(ctx, f.ClientSet) + framework.ExpectNoError(err, "failed to get running nodes") + gomega.Expect(nodes.Items).ShouldNot(gomega.BeEmpty()) + framework.Logf("Found %d schedulable nodes", len(nodes.Items)) - nodeAllocatableMilliCPU, nodeAvailableMilliCPU = getNodeAllocatableAndAvailableMilliCPUValues(ctx, f, &node) + ginkgo.By("Find node CPU and memory resources available for allocation!") + node := nodes.Items[0] + + nodeAllocatableMilliCPU, nodeAvailableMilliCPU := getNodeAllocatableAndAvailableMilliCPUValues(ctx, f, &node) framework.Logf("Node '%s': NodeAllocatable MilliCPUs = %dm. MilliCPUs currently available to allocate = %dm.", node.Name, nodeAllocatableMilliCPU, nodeAvailableMilliCPU) framework.Logf("Node '%s': NodeAllocatable MilliCPUs = %dm. MilliCPUs currently available to allocate = %dm.", @@ -590,8 +594,8 @@ func doPodResizeRetryDeferredTests(f *framework.Framework) { }, } - tStamp = strconv.Itoa(time.Now().Nanosecond()) - testPod1 = podresize.MakePodWithResizableContainers(f.Namespace.Name, "testpod1", tStamp, containerWithMajorityCPU) + tStamp := strconv.Itoa(time.Now().Nanosecond()) + testPod1 := podresize.MakePodWithResizableContainers(f.Namespace.Name, "testpod1", tStamp, containerWithMajorityCPU) testPod1 = e2epod.MustMixinRestrictedPodSecurity(testPod1) e2epod.SetNodeAffinity(&testPod1.Spec, node.Name) @@ -600,7 +604,7 @@ func doPodResizeRetryDeferredTests(f *framework.Framework) { gomega.Expect(testPod1.Status.Phase).To(gomega.Equal(v1.PodRunning)) // Create pod2 with 1/16 of the node allocatable CPU, with high priority based on priority class. - testPod2 = podresize.MakePodWithResizableContainers(f.Namespace.Name, "testpod2", tStamp, containerWithLittleCPU) + testPod2 := podresize.MakePodWithResizableContainers(f.Namespace.Name, "testpod2", tStamp, containerWithLittleCPU) testPod2 = e2epod.MustMixinRestrictedPodSecurity(testPod2) pc, err := f.ClientSet.SchedulingV1().PriorityClasses().Create(ctx, &schedulingv1.PriorityClass{ ObjectMeta: metav1.ObjectMeta{ @@ -612,6 +616,7 @@ func doPodResizeRetryDeferredTests(f *framework.Framework) { defer func() { framework.ExpectNoError(f.ClientSet.SchedulingV1().PriorityClasses().Delete(ctx, pc.Name, metav1.DeleteOptions{})) }() + testPod2.Spec.PriorityClassName = pc.Name e2epod.SetNodeAffinity(&testPod2.Spec, node.Name) @@ -620,7 +625,7 @@ func doPodResizeRetryDeferredTests(f *framework.Framework) { gomega.Expect(testPod2.Status.Phase).To(gomega.Equal(v1.PodRunning)) // Create pod3 with 1/16 of the node allocatable CPU, that is a "guaranteed" pod (all others should be "burstable"). - testPod3 = podresize.MakePodWithResizableContainers(f.Namespace.Name, "testpod3", tStamp, containerWithLittleCPUGuaranteedQoS) + testPod3 := podresize.MakePodWithResizableContainers(f.Namespace.Name, "testpod3", tStamp, containerWithLittleCPUGuaranteedQoS) testPod3 = e2epod.MustMixinRestrictedPodSecurity(testPod3) e2epod.SetNodeAffinity(&testPod3.Spec, node.Name) @@ -665,65 +670,50 @@ func doPodResizeRetryDeferredTests(f *framework.Framework) { testPod4, err = f.ClientSet.CoreV1().Pods(testPod4.Namespace).Patch(ctx, testPod4.Name, types.StrategicMergePatchType, []byte(patchTestPod), metav1.PatchOptions{}, "resize") framework.ExpectNoError(err, "failed to patch pod for resize") - framework.ExpectNoError(e2epod.WaitForPodCondition(ctx, f.ClientSet, testPod4.Namespace, testPod4.Name, "display pod resize status as deferred", f.Timeouts.PodStart, func(pod *v1.Pod) (bool, error) { - return helpers.IsPodResizeDeferred(pod), nil - })) + waitForPodDeferred(ctx, f, testPod4) // Attempt pod3 resize request to 2/3 of the node allocatable CPU, verify deferred. ginkgo.By(fmt.Sprintf("Resize pod '%s'", testPod3.Name)) testPod3, err = f.ClientSet.CoreV1().Pods(testPod3.Namespace).Patch(ctx, testPod3.Name, types.StrategicMergePatchType, []byte(patchTestPod), metav1.PatchOptions{}, "resize") framework.ExpectNoError(err, "failed to patch pod for resize") - framework.ExpectNoError(e2epod.WaitForPodCondition(ctx, f.ClientSet, testPod3.Namespace, testPod3.Name, "display pod resize status as deferred", f.Timeouts.PodStart, func(pod *v1.Pod) (bool, error) { - return helpers.IsPodResizeDeferred(pod), nil - })) + waitForPodDeferred(ctx, f, testPod3) // Attempt pod2 resize request to 2/3 of the node allocatable CPU, verify deferred. ginkgo.By(fmt.Sprintf("Resize pod '%s'", testPod2.Name)) testPod2, err = f.ClientSet.CoreV1().Pods(testPod2.Namespace).Patch(ctx, testPod2.Name, types.StrategicMergePatchType, []byte(patchTestPod), metav1.PatchOptions{}, "resize") framework.ExpectNoError(err, "failed to patch pod for resize") - framework.ExpectNoError(e2epod.WaitForPodCondition(ctx, f.ClientSet, testPod2.Namespace, testPod2.Name, "display pod resize status as deferred", f.Timeouts.PodStart, func(pod *v1.Pod) (bool, error) { - return helpers.IsPodResizeDeferred(pod), nil - })) + waitForPodDeferred(ctx, f, testPod2) // Attempt pod5 resize request to 2/3 of the node allocatable CPU, verify deferred. ginkgo.By(fmt.Sprintf("Resize pod '%s'", testPod5.Name)) testPod5, err = f.ClientSet.CoreV1().Pods(testPod5.Namespace).Patch(ctx, testPod5.Name, types.StrategicMergePatchType, []byte(patchTestPod), metav1.PatchOptions{}, "resize") framework.ExpectNoError(err, "failed to patch pod for resize") - framework.ExpectNoError(e2epod.WaitForPodCondition(ctx, f.ClientSet, testPod5.Namespace, testPod5.Name, "display pod resize status as deferred", f.Timeouts.PodStart, func(pod *v1.Pod) (bool, error) { - return helpers.IsPodResizeDeferred(pod), nil - })) + waitForPodDeferred(ctx, f, testPod5) // Delete pod1. Verify pod2's resize has completed, while the others are still deferred. ginkgo.By("deleting pod1") - delErr1 = e2epod.DeletePodWithWait(ctx, f.ClientSet, testPod1) + delErr1 := e2epod.DeletePodWithWait(ctx, f.ClientSet, testPod1) framework.ExpectNoError(delErr1, "failed to delete pod %s", testPod1.Name) ginkgo.By(fmt.Sprintf("Verify pod '%s' is resized successfully after pod '%s' deleted", testPod2.Name, testPod1.Name)) - expected = []podresize.ResizableContainerInfo{ + expected := []podresize.ResizableContainerInfo{ { Name: "c", Resources: &cgroups.ContainerResources{CPUReq: majorityCPUQuantity.String(), CPULim: majorityCPUQuantity.String()}, }, } - resizedPod = podresize.WaitForPodResizeActuation(ctx, f, podClient, testPod2, expected) + resizedPod := podresize.WaitForPodResizeActuation(ctx, f, podClient, testPod2, expected) podresize.ExpectPodResized(ctx, f, resizedPod, expected) - - framework.ExpectNoError(e2epod.WaitForPodCondition(ctx, f.ClientSet, testPod3.Namespace, testPod3.Name, "display pod resize status as deferred", f.Timeouts.PodStart, func(pod *v1.Pod) (bool, error) { - return helpers.IsPodResizeDeferred(pod), nil - })) - framework.ExpectNoError(e2epod.WaitForPodCondition(ctx, f.ClientSet, testPod4.Namespace, testPod4.Name, "display pod resize status as deferred", f.Timeouts.PodStart, func(pod *v1.Pod) (bool, error) { - return helpers.IsPodResizeDeferred(pod), nil - })) - framework.ExpectNoError(e2epod.WaitForPodCondition(ctx, f.ClientSet, testPod5.Namespace, testPod5.Name, "display pod resize status as deferred", f.Timeouts.PodStart, func(pod *v1.Pod) (bool, error) { - return helpers.IsPodResizeDeferred(pod), nil - })) + waitForPodDeferred(ctx, f, testPod3) + waitForPodDeferred(ctx, f, testPod4) + waitForPodDeferred(ctx, f, testPod5) // Delete pod2. Verify pod3's resize has completed, while the others are still deferred. ginkgo.By("deleting pod2") - delErr2 = e2epod.DeletePodWithWait(ctx, f.ClientSet, testPod2) + delErr2 := e2epod.DeletePodWithWait(ctx, f.ClientSet, testPod2) framework.ExpectNoError(delErr2, "failed to delete pod %s", testPod2.Name) ginkgo.By(fmt.Sprintf("Verify pod '%s' is resized successfully after pod '%s' deleted", testPod3.Name, testPod2.Name)) @@ -740,17 +730,12 @@ func doPodResizeRetryDeferredTests(f *framework.Framework) { } resizedPod = podresize.WaitForPodResizeActuation(ctx, f, podClient, testPod3, expected) podresize.ExpectPodResized(ctx, f, resizedPod, expected) - - framework.ExpectNoError(e2epod.WaitForPodCondition(ctx, f.ClientSet, testPod4.Namespace, testPod4.Name, "display pod resize status as deferred", f.Timeouts.PodStart, func(pod *v1.Pod) (bool, error) { - return helpers.IsPodResizeDeferred(pod), nil - })) - framework.ExpectNoError(e2epod.WaitForPodCondition(ctx, f.ClientSet, testPod5.Namespace, testPod5.Name, "display pod resize status as deferred", f.Timeouts.PodStart, func(pod *v1.Pod) (bool, error) { - return helpers.IsPodResizeDeferred(pod), nil - })) + waitForPodDeferred(ctx, f, testPod4) + waitForPodDeferred(ctx, f, testPod5) // Delete pod3. Verify pod4's resize has completed, while the others are still deferred. ginkgo.By("deleting pod3") - delErr3 = e2epod.DeletePodWithWait(ctx, f.ClientSet, testPod3) + delErr3 := e2epod.DeletePodWithWait(ctx, f.ClientSet, testPod3) framework.ExpectNoError(delErr3, "failed to delete pod %s", testPod3.Name) ginkgo.By(fmt.Sprintf("Verify pod '%s' is resized successfully after pod '%s' deleted", testPod4.Name, testPod3.Name)) @@ -762,10 +747,7 @@ func doPodResizeRetryDeferredTests(f *framework.Framework) { } resizedPod = podresize.WaitForPodResizeActuation(ctx, f, podClient, testPod4, expected) podresize.ExpectPodResized(ctx, f, resizedPod, expected) - - framework.ExpectNoError(e2epod.WaitForPodCondition(ctx, f.ClientSet, testPod5.Namespace, testPod5.Name, "display pod resize status as deferred", f.Timeouts.PodStart, func(pod *v1.Pod) (bool, error) { - return helpers.IsPodResizeDeferred(pod), nil - })) + waitForPodDeferred(ctx, f, testPod5) // Delete pod4. Verify pod5's resize has completed. ginkgo.By("deleting pod4") @@ -855,3 +837,9 @@ func getNodeAllocatableAndAvailableMilliCPUValues(ctx context.Context, f *framew nodeAvailableMilliCPU := nodeAllocatableMilliCPU - podAllocatedMilliCPU return nodeAllocatableMilliCPU, nodeAvailableMilliCPU } + +func waitForPodDeferred(ctx context.Context, f *framework.Framework, testPod *v1.Pod) { + framework.ExpectNoError(e2epod.WaitForPodCondition(ctx, f.ClientSet, testPod.Namespace, testPod.Name, "display pod resize status as deferred", f.Timeouts.PodStart, func(pod *v1.Pod) (bool, error) { + return helpers.IsPodResizeDeferred(pod), nil + })) +}