mirror of
https://github.com/kubernetes/kubernetes.git
synced 2026-05-28 04:04:39 -04:00
clean up e2e test and sorting code
This commit is contained in:
parent
e8b914c4b8
commit
237fbde8b1
3 changed files with 128 additions and 146 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}))
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue