From 3b91edb6606585f1881397ed537eff30d5bd3a0d Mon Sep 17 00:00:00 2001 From: Anish Shah Date: Tue, 29 Oct 2024 14:06:59 -0700 Subject: [PATCH] unit tests to ensure pod metadata cannot be updated during resize. --- pkg/api/pod/testing/make.go | 32 + pkg/registry/core/pod/strategy.go | 8 +- pkg/registry/core/pod/strategy_test.go | 824 ++++++++++++------------- 3 files changed, 424 insertions(+), 440 deletions(-) diff --git a/pkg/api/pod/testing/make.go b/pkg/api/pod/testing/make.go index 8667f71060a..b73de5d1a11 100644 --- a/pkg/api/pod/testing/make.go +++ b/pkg/api/pod/testing/make.go @@ -27,6 +27,7 @@ import ( // Tweak is a function that modifies a Pod. type Tweak func(*api.Pod) type TweakContainer func(*api.Container) +type TweakPodStatus func(*api.PodStatus) // MakePod helps construct Pod objects (which pass API validation) more // legibly and tersely than a Go struct definition. By default this produces @@ -297,3 +298,34 @@ func SetContainerRestartPolicy(policy api.ContainerRestartPolicy) TweakContainer cnr.RestartPolicy = &policy } } + +func MakePodStatus(tweaks ...TweakPodStatus) api.PodStatus { + ps := api.PodStatus{} + + for _, tweak := range tweaks { + tweak(&ps) + } + + return ps +} + +func SetContainerStatuses(containerStatuses ...api.ContainerStatus) TweakPodStatus { + return func(podstatus *api.PodStatus) { + podstatus.ContainerStatuses = containerStatuses + } +} + +func MakeContainerStatus(name string, allocatedResources api.ResourceList) api.ContainerStatus { + cs := api.ContainerStatus{ + Name: name, + AllocatedResources: allocatedResources, + } + + return cs +} + +func SetResizeStatus(resizeStatus api.PodResizeStatus) TweakPodStatus { + return func(podstatus *api.PodStatus) { + podstatus.Resize = resizeStatus + } +} diff --git a/pkg/registry/core/pod/strategy.go b/pkg/registry/core/pod/strategy.go index de4d23ee70e..cd580e2c81e 100644 --- a/pkg/registry/core/pod/strategy.go +++ b/pkg/registry/core/pod/strategy.go @@ -247,7 +247,7 @@ var EphemeralContainersStrategy = podEphemeralContainersStrategy{Strategy} // dropNonEphemeralContainerUpdates discards all changes except for pod.Spec.EphemeralContainers and certain metadata func dropNonEphemeralContainerUpdates(newPod, oldPod *api.Pod) *api.Pod { - pod := mungePod(newPod, oldPod) + pod := dropPodUpdates(newPod, oldPod) pod.Spec.EphemeralContainers = newPod.Spec.EphemeralContainers return pod } @@ -282,7 +282,7 @@ var ResizeStrategy = podResizeStrategy{Strategy} // dropNonPodResizeUpdates discards all changes except for pod.Spec.Containers[*].Resources,ResizePolicy and certain metadata func dropNonPodResizeUpdates(newPod, oldPod *api.Pod) *api.Pod { - pod := mungePod(newPod, oldPod) + pod := dropPodUpdates(newPod, oldPod) oldCtrToIndex := make(map[string]int) for idx, ctr := range pod.Spec.Containers { @@ -321,8 +321,8 @@ func (podResizeStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime. return nil } -// mungePod mutates metadata information of old pod with the new pod. -func mungePod(newPod, oldPod *api.Pod) *api.Pod { +// dropPodUpdates drops any changes in the pod. +func dropPodUpdates(newPod, oldPod *api.Pod) *api.Pod { pod := oldPod.DeepCopy() pod.Name = newPod.Name pod.Namespace = newPod.Namespace diff --git a/pkg/registry/core/pod/strategy_test.go b/pkg/registry/core/pod/strategy_test.go index 6b1cd9a9bf5..92efa3025bc 100644 --- a/pkg/registry/core/pod/strategy_test.go +++ b/pkg/registry/core/pod/strategy_test.go @@ -2461,498 +2461,450 @@ func TestPodResizePrepareForUpdate(t *testing.T) { }{ { name: "no resize", - oldPod: &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "container1", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, + oldPod: podtest.MakePod("test-pod", + podtest.SetResourceVersion("1"), + podtest.SetContainers(podtest.MakeContainer("container1", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), }, - }, - }, - Status: api.PodStatus{ - ContainerStatuses: []api.ContainerStatus{ - { - Name: "container1", - AllocatedResources: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, + }), + )), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + }), + ), + )), + ), + newPod: podtest.MakePod("test-pod", + podtest.SetResourceVersion("1"), + podtest.SetContainers(podtest.MakeContainer("container1", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), }, - }, - }, - }, - newPod: &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "container1", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, + }), + )), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + }), + ), + )), + ), + expected: podtest.MakePod("test-pod", + podtest.SetResourceVersion("1"), + podtest.SetContainers(podtest.MakeContainer("container1", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), }, - }, - }, - Status: api.PodStatus{ - ContainerStatuses: []api.ContainerStatus{ - { - Name: "container1", - AllocatedResources: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, - }, - }, - }, - expected: &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "container1", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, - }, - }, - }, - Status: api.PodStatus{ - ContainerStatuses: []api.ContainerStatus{ - { - Name: "container1", - AllocatedResources: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, - }, - }, - }, + }), + )), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + }), + ), + )), + ), }, { name: "update resizepolicy", - oldPod: &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "container1", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, + oldPod: podtest.MakePod("test-pod", + podtest.SetResourceVersion("1"), + podtest.SetContainers(podtest.MakeContainer("container1", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), }, - }, - }, - Status: api.PodStatus{ - ContainerStatuses: []api.ContainerStatus{ - { - Name: "container1", - AllocatedResources: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, + }), + )), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + })), + )), + ), + newPod: podtest.MakePod("test-pod", + podtest.SetResourceVersion("2"), + podtest.SetContainers(podtest.MakeContainer("container1", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), }, - }, - }, - }, - newPod: &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "container1", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, - ResizePolicy: []api.ContainerResizePolicy{ - {ResourceName: "cpu", RestartPolicy: "NotRequired"}, - {ResourceName: "memory", RestartPolicy: "RestartContainer"}, - }, + }), + podtest.SetContainerResizePolicy( + api.ContainerResizePolicy{ResourceName: "cpu", RestartPolicy: "NotRequired"}, + api.ContainerResizePolicy{ResourceName: "memory", RestartPolicy: "RestartContainer"}, + ), + )), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + })), + )), + ), + expected: podtest.MakePod("test-pod", + podtest.SetResourceVersion("2"), + podtest.SetContainers(podtest.MakeContainer("container1", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), }, - }, - }, - Status: api.PodStatus{ - ContainerStatuses: []api.ContainerStatus{ - { - Name: "container1", - AllocatedResources: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, - }, - }, - }, - expected: &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "container1", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, - ResizePolicy: []api.ContainerResizePolicy{ - {ResourceName: "cpu", RestartPolicy: "NotRequired"}, - {ResourceName: "memory", RestartPolicy: "RestartContainer"}, - }, - }, - }, - }, - Status: api.PodStatus{ - ContainerStatuses: []api.ContainerStatus{ - { - Name: "container1", - AllocatedResources: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, - }, - }, - }, + }), + podtest.SetContainerResizePolicy( + api.ContainerResizePolicy{ResourceName: "cpu", RestartPolicy: "NotRequired"}, + api.ContainerResizePolicy{ResourceName: "memory", RestartPolicy: "RestartContainer"}, + ), + )), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + })), + )), + ), }, { name: "add new container", - oldPod: &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "container1", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, + oldPod: podtest.MakePod("test-pod", + podtest.SetResourceVersion("1"), + podtest.SetContainers(podtest.MakeContainer("container1", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), }, - }, - }, - Status: api.PodStatus{ - ContainerStatuses: []api.ContainerStatus{ - { - Name: "container1", - AllocatedResources: api.ResourceList{ + }), + )), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + })), + )), + ), + newPod: podtest.MakePod("test-pod", + podtest.SetResourceVersion("2"), + podtest.SetContainers( + podtest.MakeContainer("container1", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ api.ResourceCPU: resource.MustParse("100m"), api.ResourceMemory: resource.MustParse("1Gi"), }, - }, - }, - }, - }, - newPod: &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "container1", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, - }, - { - Name: "container2", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, - }, - }, - }, - Status: api.PodStatus{ - ContainerStatuses: []api.ContainerStatus{ - { - Name: "container1", - AllocatedResources: api.ResourceList{ + }), + ), + podtest.MakeContainer("container2", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ api.ResourceCPU: resource.MustParse("100m"), api.ResourceMemory: resource.MustParse("1Gi"), }, + }), + ), + ), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + })), + )), + ), + expected: podtest.MakePod("test-pod", + podtest.SetResourceVersion("2"), + podtest.SetContainers(podtest.MakeContainer("container1", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), }, - }, - }, - }, - expected: &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "container1", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, - }, - }, - }, - Status: api.PodStatus{ - ContainerStatuses: []api.ContainerStatus{ - { - Name: "container1", - AllocatedResources: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, - }, - }, - }, + }), + )), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + })), + )), + ), }, { name: "add new container and update resources of existing container", - oldPod: &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "container1", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, + oldPod: podtest.MakePod("test-pod", + podtest.SetResourceVersion("1"), + podtest.SetContainers(podtest.MakeContainer("container1", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), }, - }, - }, - Status: api.PodStatus{ - ContainerStatuses: []api.ContainerStatus{ - { - Name: "container1", - AllocatedResources: api.ResourceList{ + }), + )), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + })), + )), + ), + newPod: podtest.MakePod("test-pod", + podtest.SetResourceVersion("2"), + podtest.SetContainers( + podtest.MakeContainer("container1", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("2Gi"), // Updated resource + }, + }), + ), + podtest.MakeContainer("container2", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ api.ResourceCPU: resource.MustParse("100m"), api.ResourceMemory: resource.MustParse("1Gi"), }, + }), + ), + ), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + })), + )), + ), + expected: podtest.MakePod("test-pod", + podtest.SetResourceVersion("2"), + podtest.SetContainers(podtest.MakeContainer("container1", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("2Gi"), // Updated resource }, - }, - }, - }, - newPod: &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "container1", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("2Gi"), - }, - }, - }, - { - Name: "container2", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, - }, - }, - }, - Status: api.PodStatus{ - ContainerStatuses: []api.ContainerStatus{ - { - Name: "container1", - AllocatedResources: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, - }, - }, - }, - expected: &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "container1", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("2Gi"), - }, - }, - }, - }, - }, - Status: api.PodStatus{ - Resize: api.PodResizeStatusProposed, - ContainerStatuses: []api.ContainerStatus{ - { - Name: "container1", - AllocatedResources: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, - }, - }, - }, + }), + )), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetResizeStatus(api.PodResizeStatusProposed), // Resize status set + podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + })), + )), + ), }, { name: "change container order and update resources", - oldPod: &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "container1", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, - }, - { - Name: "container2", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("100m"), - api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, - }, - }, - }, - Status: api.PodStatus{ - ContainerStatuses: []api.ContainerStatus{ - { - Name: "container1", - AllocatedResources: api.ResourceList{ + oldPod: podtest.MakePod("test-pod", + podtest.SetResourceVersion("1"), + podtest.SetContainers( + podtest.MakeContainer("container1", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ api.ResourceCPU: resource.MustParse("100m"), api.ResourceMemory: resource.MustParse("1Gi"), }, - }, - { - Name: "container2", - AllocatedResources: api.ResourceList{ + }), + ), + podtest.MakeContainer("container2", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ api.ResourceCPU: resource.MustParse("100m"), api.ResourceMemory: resource.MustParse("1Gi"), }, - }, - }, - }, - }, - newPod: &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "container2", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("200m"), - api.ResourceMemory: resource.MustParse("2Gi"), - }, + }), + ), + ), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetContainerStatuses( + podtest.MakeContainerStatus("container1", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + }), + podtest.MakeContainerStatus("container2", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + }), + ), + )), + ), + newPod: podtest.MakePod("test-pod", + podtest.SetResourceVersion("2"), + podtest.SetContainers( + podtest.MakeContainer("container2", // Order changed + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ + api.ResourceCPU: resource.MustParse("200m"), // Updated resource + api.ResourceMemory: resource.MustParse("2Gi"), // Updated resource }, - }, - { - Name: "container1", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("200m"), - api.ResourceMemory: resource.MustParse("4Gi"), - }, + }), + ), + podtest.MakeContainer("container1", // Order changed + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ + api.ResourceCPU: resource.MustParse("200m"), // Updated resource + api.ResourceMemory: resource.MustParse("4Gi"), // Updated resource }, - }, - }, - }, - Status: api.PodStatus{ - ContainerStatuses: []api.ContainerStatus{ - { - Name: "container1", - AllocatedResources: api.ResourceList{ + }), + ), + ), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetContainerStatuses( + podtest.MakeContainerStatus("container1", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + }), + podtest.MakeContainerStatus("container2", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + }), + ), + )), + ), + expected: podtest.MakePod("test-pod", + podtest.SetResourceVersion("2"), + podtest.SetContainers( + podtest.MakeContainer("container1", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ + api.ResourceCPU: resource.MustParse("200m"), // Updated resource + api.ResourceMemory: resource.MustParse("4Gi"), // Updated resource + }, + }), + ), + podtest.MakeContainer("container2", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ + api.ResourceCPU: resource.MustParse("200m"), // Updated resource + api.ResourceMemory: resource.MustParse("2Gi"), // Updated resource + }, + }), + ), + ), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetResizeStatus(api.PodResizeStatusProposed), // Resize status set + podtest.SetContainerStatuses( + podtest.MakeContainerStatus("container1", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + }), + podtest.MakeContainerStatus("container2", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + }), + ), + )), + ), + }, + { + name: "change pod labels", + oldPod: podtest.MakePod("test-pod", + podtest.SetResourceVersion("1"), + podtest.SetLabels(map[string]string{"foo": "bar"}), + podtest.SetContainers( + podtest.MakeContainer("container1", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ api.ResourceCPU: resource.MustParse("100m"), api.ResourceMemory: resource.MustParse("1Gi"), }, - }, - { - Name: "container2", - AllocatedResources: api.ResourceList{ + }), + ), + ), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetContainerStatuses( + podtest.MakeContainerStatus("container1", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + }), + ), + )), + ), + newPod: podtest.MakePod("test-pod", + podtest.SetResourceVersion("2"), + podtest.SetLabels(map[string]string{"foo": "bar", "baz": "qux"}), + podtest.SetContainers( + podtest.MakeContainer("container1", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ api.ResourceCPU: resource.MustParse("100m"), api.ResourceMemory: resource.MustParse("1Gi"), }, - }, - }, - }, - }, - expected: &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: "container1", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("200m"), - api.ResourceMemory: resource.MustParse("4Gi"), - }, - }, - }, - { - Name: "container2", - Resources: api.ResourceRequirements{ - Requests: api.ResourceList{ - api.ResourceCPU: resource.MustParse("200m"), - api.ResourceMemory: resource.MustParse("2Gi"), - }, - }, - }, - }, - }, - Status: api.PodStatus{ - Resize: api.PodResizeStatusProposed, - ContainerStatuses: []api.ContainerStatus{ - { - Name: "container1", - AllocatedResources: api.ResourceList{ + }), + ), + ), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetContainerStatuses( + podtest.MakeContainerStatus("container1", + api.ResourceList{ + api.ResourceCPU: resource.MustParse("100m"), + api.ResourceMemory: resource.MustParse("1Gi"), + }), + ), + )), + ), + expected: podtest.MakePod("test-pod", + podtest.SetResourceVersion("2"), + podtest.SetLabels(map[string]string{"foo": "bar"}), + podtest.SetContainers( + podtest.MakeContainer("container1", + podtest.SetContainerResources(api.ResourceRequirements{ + Requests: api.ResourceList{ api.ResourceCPU: resource.MustParse("100m"), api.ResourceMemory: resource.MustParse("1Gi"), }, - }, - { - Name: "container2", - AllocatedResources: api.ResourceList{ + }), + ), + ), + podtest.SetStatus(podtest.MakePodStatus( + podtest.SetContainerStatuses( + podtest.MakeContainerStatus("container1", + api.ResourceList{ api.ResourceCPU: resource.MustParse("100m"), api.ResourceMemory: resource.MustParse("1Gi"), - }, - }, - }, - }, - }, + }), + ), + )), + ), }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.InPlacePodVerticalScaling, true) - tc.newPod.Name = "test-pod" - tc.newPod.Namespace = "test-ns" - tc.newPod.ResourceVersion = "123" - tc.newPod.UID = "abc" - tc.expected.Name = "test-pod" - tc.expected.Namespace = "test-ns" - tc.expected.ResourceVersion = "123" - tc.expected.UID = "abc" ctx := context.Background() ResizeStrategy.PrepareForUpdate(ctx, tc.newPod, tc.oldPod) if !cmp.Equal(tc.expected, tc.newPod) {