clean up e2e test and sorting code

This commit is contained in:
Natasha Sarkar 2025-07-10 22:30:21 +00:00
parent e8b914c4b8
commit 237fbde8b1
3 changed files with 128 additions and 146 deletions

View file

@ -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

View file

@ -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")

View file

@ -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
}))
}