unit tests to ensure pod metadata cannot be updated during resize.

This commit is contained in:
Anish Shah 2024-10-29 14:06:59 -07:00
parent 7ac302b47a
commit 3b91edb660
3 changed files with 424 additions and 440 deletions

View File

@ -27,6 +27,7 @@ import (
// Tweak is a function that modifies a Pod. // Tweak is a function that modifies a Pod.
type Tweak func(*api.Pod) type Tweak func(*api.Pod)
type TweakContainer func(*api.Container) type TweakContainer func(*api.Container)
type TweakPodStatus func(*api.PodStatus)
// MakePod helps construct Pod objects (which pass API validation) more // MakePod helps construct Pod objects (which pass API validation) more
// legibly and tersely than a Go struct definition. By default this produces // 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 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
}
}

View File

@ -247,7 +247,7 @@ var EphemeralContainersStrategy = podEphemeralContainersStrategy{Strategy}
// dropNonEphemeralContainerUpdates discards all changes except for pod.Spec.EphemeralContainers and certain metadata // dropNonEphemeralContainerUpdates discards all changes except for pod.Spec.EphemeralContainers and certain metadata
func dropNonEphemeralContainerUpdates(newPod, oldPod *api.Pod) *api.Pod { func dropNonEphemeralContainerUpdates(newPod, oldPod *api.Pod) *api.Pod {
pod := mungePod(newPod, oldPod) pod := dropPodUpdates(newPod, oldPod)
pod.Spec.EphemeralContainers = newPod.Spec.EphemeralContainers pod.Spec.EphemeralContainers = newPod.Spec.EphemeralContainers
return pod return pod
} }
@ -282,7 +282,7 @@ var ResizeStrategy = podResizeStrategy{Strategy}
// dropNonPodResizeUpdates discards all changes except for pod.Spec.Containers[*].Resources,ResizePolicy and certain metadata // dropNonPodResizeUpdates discards all changes except for pod.Spec.Containers[*].Resources,ResizePolicy and certain metadata
func dropNonPodResizeUpdates(newPod, oldPod *api.Pod) *api.Pod { func dropNonPodResizeUpdates(newPod, oldPod *api.Pod) *api.Pod {
pod := mungePod(newPod, oldPod) pod := dropPodUpdates(newPod, oldPod)
oldCtrToIndex := make(map[string]int) oldCtrToIndex := make(map[string]int)
for idx, ctr := range pod.Spec.Containers { for idx, ctr := range pod.Spec.Containers {
@ -321,8 +321,8 @@ func (podResizeStrategy) WarningsOnUpdate(ctx context.Context, obj, old runtime.
return nil return nil
} }
// mungePod mutates metadata information of old pod with the new pod. // dropPodUpdates drops any changes in the pod.
func mungePod(newPod, oldPod *api.Pod) *api.Pod { func dropPodUpdates(newPod, oldPod *api.Pod) *api.Pod {
pod := oldPod.DeepCopy() pod := oldPod.DeepCopy()
pod.Name = newPod.Name pod.Name = newPod.Name
pod.Namespace = newPod.Namespace pod.Namespace = newPod.Namespace

View File

@ -2461,498 +2461,450 @@ func TestPodResizePrepareForUpdate(t *testing.T) {
}{ }{
{ {
name: "no resize", name: "no resize",
oldPod: &api.Pod{ oldPod: podtest.MakePod("test-pod",
Spec: api.PodSpec{ podtest.SetResourceVersion("1"),
Containers: []api.Container{ podtest.SetContainers(podtest.MakeContainer("container1",
{ podtest.SetContainerResources(api.ResourceRequirements{
Name: "container1", Requests: api.ResourceList{
Resources: api.ResourceRequirements{ api.ResourceCPU: resource.MustParse("100m"),
Requests: api.ResourceList{ api.ResourceMemory: resource.MustParse("1Gi"),
api.ResourceCPU: resource.MustParse("100m"),
api.ResourceMemory: resource.MustParse("1Gi"),
},
},
}, },
}, }),
}, )),
Status: api.PodStatus{ podtest.SetStatus(podtest.MakePodStatus(
ContainerStatuses: []api.ContainerStatus{ podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1",
{ api.ResourceList{
Name: "container1", api.ResourceCPU: resource.MustParse("100m"),
AllocatedResources: api.ResourceList{ api.ResourceMemory: resource.MustParse("1Gi"),
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"),
}, },
}, }),
}, )),
}, podtest.SetStatus(podtest.MakePodStatus(
newPod: &api.Pod{ podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1",
Spec: api.PodSpec{ api.ResourceList{
Containers: []api.Container{ api.ResourceCPU: resource.MustParse("100m"),
{ api.ResourceMemory: resource.MustParse("1Gi"),
Name: "container1", }),
Resources: api.ResourceRequirements{ ),
Requests: 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{ podtest.SetStatus(podtest.MakePodStatus(
ContainerStatuses: []api.ContainerStatus{ podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1",
{ api.ResourceList{
Name: "container1", api.ResourceCPU: resource.MustParse("100m"),
AllocatedResources: api.ResourceList{ api.ResourceMemory: resource.MustParse("1Gi"),
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"),
},
},
},
},
},
}, },
{ {
name: "update resizepolicy", name: "update resizepolicy",
oldPod: &api.Pod{ oldPod: podtest.MakePod("test-pod",
Spec: api.PodSpec{ podtest.SetResourceVersion("1"),
Containers: []api.Container{ podtest.SetContainers(podtest.MakeContainer("container1",
{ podtest.SetContainerResources(api.ResourceRequirements{
Name: "container1", Requests: api.ResourceList{
Resources: api.ResourceRequirements{ api.ResourceCPU: resource.MustParse("100m"),
Requests: api.ResourceList{ api.ResourceMemory: resource.MustParse("1Gi"),
api.ResourceCPU: resource.MustParse("100m"),
api.ResourceMemory: resource.MustParse("1Gi"),
},
},
}, },
}, }),
}, )),
Status: api.PodStatus{ podtest.SetStatus(podtest.MakePodStatus(
ContainerStatuses: []api.ContainerStatus{ podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1",
{ api.ResourceList{
Name: "container1", api.ResourceCPU: resource.MustParse("100m"),
AllocatedResources: api.ResourceList{ api.ResourceMemory: resource.MustParse("1Gi"),
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"),
}, },
}, }),
}, podtest.SetContainerResizePolicy(
}, api.ContainerResizePolicy{ResourceName: "cpu", RestartPolicy: "NotRequired"},
newPod: &api.Pod{ api.ContainerResizePolicy{ResourceName: "memory", RestartPolicy: "RestartContainer"},
Spec: api.PodSpec{ ),
Containers: []api.Container{ )),
{ podtest.SetStatus(podtest.MakePodStatus(
Name: "container1", podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1",
Resources: api.ResourceRequirements{ api.ResourceList{
Requests: api.ResourceList{ api.ResourceCPU: resource.MustParse("100m"),
api.ResourceCPU: resource.MustParse("100m"), api.ResourceMemory: resource.MustParse("1Gi"),
api.ResourceMemory: resource.MustParse("1Gi"), })),
}, )),
}, ),
ResizePolicy: []api.ContainerResizePolicy{ expected: podtest.MakePod("test-pod",
{ResourceName: "cpu", RestartPolicy: "NotRequired"}, podtest.SetResourceVersion("2"),
{ResourceName: "memory", RestartPolicy: "RestartContainer"}, podtest.SetContainers(podtest.MakeContainer("container1",
}, podtest.SetContainerResources(api.ResourceRequirements{
Requests: api.ResourceList{
api.ResourceCPU: resource.MustParse("100m"),
api.ResourceMemory: resource.MustParse("1Gi"),
}, },
}, }),
}, podtest.SetContainerResizePolicy(
Status: api.PodStatus{ api.ContainerResizePolicy{ResourceName: "cpu", RestartPolicy: "NotRequired"},
ContainerStatuses: []api.ContainerStatus{ api.ContainerResizePolicy{ResourceName: "memory", RestartPolicy: "RestartContainer"},
{ ),
Name: "container1", )),
AllocatedResources: api.ResourceList{ podtest.SetStatus(podtest.MakePodStatus(
api.ResourceCPU: resource.MustParse("100m"), podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1",
api.ResourceMemory: resource.MustParse("1Gi"), 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"),
},
},
},
},
},
}, },
{ {
name: "add new container", name: "add new container",
oldPod: &api.Pod{ oldPod: podtest.MakePod("test-pod",
Spec: api.PodSpec{ podtest.SetResourceVersion("1"),
Containers: []api.Container{ podtest.SetContainers(podtest.MakeContainer("container1",
{ podtest.SetContainerResources(api.ResourceRequirements{
Name: "container1", Requests: api.ResourceList{
Resources: api.ResourceRequirements{ api.ResourceCPU: resource.MustParse("100m"),
Requests: api.ResourceList{ api.ResourceMemory: resource.MustParse("1Gi"),
api.ResourceCPU: resource.MustParse("100m"),
api.ResourceMemory: resource.MustParse("1Gi"),
},
},
}, },
}, }),
}, )),
Status: api.PodStatus{ podtest.SetStatus(podtest.MakePodStatus(
ContainerStatuses: []api.ContainerStatus{ podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1",
{ api.ResourceList{
Name: "container1", api.ResourceCPU: resource.MustParse("100m"),
AllocatedResources: api.ResourceList{ 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.ResourceCPU: resource.MustParse("100m"),
api.ResourceMemory: resource.MustParse("1Gi"), api.ResourceMemory: resource.MustParse("1Gi"),
}, },
}, }),
}, ),
}, podtest.MakeContainer("container2",
}, podtest.SetContainerResources(api.ResourceRequirements{
newPod: &api.Pod{ Requests: api.ResourceList{
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{
api.ResourceCPU: resource.MustParse("100m"), api.ResourceCPU: resource.MustParse("100m"),
api.ResourceMemory: resource.MustParse("1Gi"), 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"),
}, },
}, }),
}, )),
}, podtest.SetStatus(podtest.MakePodStatus(
expected: &api.Pod{ podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1",
Spec: api.PodSpec{ api.ResourceList{
Containers: []api.Container{ api.ResourceCPU: resource.MustParse("100m"),
{ api.ResourceMemory: resource.MustParse("1Gi"),
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"),
},
},
},
},
},
}, },
{ {
name: "add new container and update resources of existing container", name: "add new container and update resources of existing container",
oldPod: &api.Pod{ oldPod: podtest.MakePod("test-pod",
Spec: api.PodSpec{ podtest.SetResourceVersion("1"),
Containers: []api.Container{ podtest.SetContainers(podtest.MakeContainer("container1",
{ podtest.SetContainerResources(api.ResourceRequirements{
Name: "container1", Requests: api.ResourceList{
Resources: api.ResourceRequirements{ api.ResourceCPU: resource.MustParse("100m"),
Requests: api.ResourceList{ api.ResourceMemory: resource.MustParse("1Gi"),
api.ResourceCPU: resource.MustParse("100m"),
api.ResourceMemory: resource.MustParse("1Gi"),
},
},
}, },
}, }),
}, )),
Status: api.PodStatus{ podtest.SetStatus(podtest.MakePodStatus(
ContainerStatuses: []api.ContainerStatus{ podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1",
{ api.ResourceList{
Name: "container1", api.ResourceCPU: resource.MustParse("100m"),
AllocatedResources: api.ResourceList{ 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.ResourceCPU: resource.MustParse("100m"),
api.ResourceMemory: resource.MustParse("1Gi"), 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
}, },
}, }),
}, )),
}, podtest.SetStatus(podtest.MakePodStatus(
newPod: &api.Pod{ podtest.SetResizeStatus(api.PodResizeStatusProposed), // Resize status set
Spec: api.PodSpec{ podtest.SetContainerStatuses(podtest.MakeContainerStatus("container1",
Containers: []api.Container{ api.ResourceList{
{ api.ResourceCPU: resource.MustParse("100m"),
Name: "container1", api.ResourceMemory: resource.MustParse("1Gi"),
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"),
},
},
},
},
},
}, },
{ {
name: "change container order and update resources", name: "change container order and update resources",
oldPod: &api.Pod{ oldPod: podtest.MakePod("test-pod",
Spec: api.PodSpec{ podtest.SetResourceVersion("1"),
Containers: []api.Container{ podtest.SetContainers(
{ podtest.MakeContainer("container1",
Name: "container1", podtest.SetContainerResources(api.ResourceRequirements{
Resources: api.ResourceRequirements{ Requests: api.ResourceList{
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{
api.ResourceCPU: resource.MustParse("100m"), api.ResourceCPU: resource.MustParse("100m"),
api.ResourceMemory: resource.MustParse("1Gi"), api.ResourceMemory: resource.MustParse("1Gi"),
}, },
}, }),
{ ),
Name: "container2", podtest.MakeContainer("container2",
AllocatedResources: api.ResourceList{ podtest.SetContainerResources(api.ResourceRequirements{
Requests: api.ResourceList{
api.ResourceCPU: resource.MustParse("100m"), api.ResourceCPU: resource.MustParse("100m"),
api.ResourceMemory: resource.MustParse("1Gi"), api.ResourceMemory: resource.MustParse("1Gi"),
}, },
}, }),
}, ),
}, ),
}, podtest.SetStatus(podtest.MakePodStatus(
newPod: &api.Pod{ podtest.SetContainerStatuses(
Spec: api.PodSpec{ podtest.MakeContainerStatus("container1",
Containers: []api.Container{ api.ResourceList{
{ api.ResourceCPU: resource.MustParse("100m"),
Name: "container2", api.ResourceMemory: resource.MustParse("1Gi"),
Resources: api.ResourceRequirements{ }),
Requests: api.ResourceList{ podtest.MakeContainerStatus("container2",
api.ResourceCPU: resource.MustParse("200m"), api.ResourceList{
api.ResourceMemory: resource.MustParse("2Gi"), 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", podtest.MakeContainer("container1", // Order changed
Resources: api.ResourceRequirements{ podtest.SetContainerResources(api.ResourceRequirements{
Requests: api.ResourceList{ Requests: api.ResourceList{
api.ResourceCPU: resource.MustParse("200m"), api.ResourceCPU: resource.MustParse("200m"), // Updated resource
api.ResourceMemory: resource.MustParse("4Gi"), api.ResourceMemory: resource.MustParse("4Gi"), // Updated resource
},
}, },
}, }),
}, ),
}, ),
Status: api.PodStatus{ podtest.SetStatus(podtest.MakePodStatus(
ContainerStatuses: []api.ContainerStatus{ podtest.SetContainerStatuses(
{ podtest.MakeContainerStatus("container1",
Name: "container1", api.ResourceList{
AllocatedResources: 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.ResourceCPU: resource.MustParse("100m"),
api.ResourceMemory: resource.MustParse("1Gi"), 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.ResourceCPU: resource.MustParse("100m"),
api.ResourceMemory: resource.MustParse("1Gi"), api.ResourceMemory: resource.MustParse("1Gi"),
}, },
}, }),
}, ),
}, ),
}, podtest.SetStatus(podtest.MakePodStatus(
expected: &api.Pod{ podtest.SetContainerStatuses(
Spec: api.PodSpec{ podtest.MakeContainerStatus("container1",
Containers: []api.Container{ api.ResourceList{
{ api.ResourceCPU: resource.MustParse("100m"),
Name: "container1", api.ResourceMemory: resource.MustParse("1Gi"),
Resources: api.ResourceRequirements{ }),
Requests: api.ResourceList{ ),
api.ResourceCPU: resource.MustParse("200m"), )),
api.ResourceMemory: resource.MustParse("4Gi"), ),
}, expected: podtest.MakePod("test-pod",
}, podtest.SetResourceVersion("2"),
}, podtest.SetLabels(map[string]string{"foo": "bar"}),
{ podtest.SetContainers(
Name: "container2", podtest.MakeContainer("container1",
Resources: api.ResourceRequirements{ podtest.SetContainerResources(api.ResourceRequirements{
Requests: api.ResourceList{ 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{
api.ResourceCPU: resource.MustParse("100m"), api.ResourceCPU: resource.MustParse("100m"),
api.ResourceMemory: resource.MustParse("1Gi"), 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.ResourceCPU: resource.MustParse("100m"),
api.ResourceMemory: resource.MustParse("1Gi"), api.ResourceMemory: resource.MustParse("1Gi"),
}, }),
}, ),
}, )),
}, ),
},
}, },
} }
for _, tc := range tests { for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.InPlacePodVerticalScaling, true) 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() ctx := context.Background()
ResizeStrategy.PrepareForUpdate(ctx, tc.newPod, tc.oldPod) ResizeStrategy.PrepareForUpdate(ctx, tc.newPod, tc.oldPod)
if !cmp.Equal(tc.expected, tc.newPod) { if !cmp.Equal(tc.expected, tc.newPod) {