Skip to content

Commit

Permalink
VPA: Add e2e test for spliting recommendations when removing/renaming…
Browse files Browse the repository at this point in the history
… containers

Signed-off-by: Max Cao <[email protected]>
  • Loading branch information
maxcao13 committed Dec 3, 2024
1 parent f57de8e commit c3a1f0e
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 0 deletions.
7 changes: 7 additions & 0 deletions vertical-pod-autoscaler/e2e/v1/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,13 @@ func InstallVPA(f *framework.Framework, vpa *vpa_types.VerticalPodAutoscaler) {
}
}

func JSONPatchDeployment(f *framework.Framework, deployment *appsv1.Deployment, patch *patchRecord) {
patchBytes, err := json.Marshal([]patchRecord{*patch})
gomega.Expect(err).NotTo(gomega.HaveOccurred())
_, err = f.ClientSet.AppsV1().Deployments(f.Namespace.Name).Patch(context.TODO(), deployment.Name, types.JSONPatchType, patchBytes, metav1.PatchOptions{})
gomega.Expect(err).NotTo(gomega.HaveOccurred(), "unexpected error patching deployment")
}

func isStatusEmpty(status *vpa_types.VerticalPodAutoscalerStatus) bool {
if status == nil {
return true
Expand Down
97 changes: 97 additions & 0 deletions vertical-pod-autoscaler/e2e/v1/recommender.go
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,103 @@ var _ = RecommenderE2eDescribe("VPA CRD object", func() {
})
})

const recommendationLoopInterval = 1 * time.Minute

var _ = RecommenderE2eDescribe("VPA CRD object", func() {
f := framework.NewDefaultFramework("vertical-pod-autoscaling")
f.NamespacePodSecurityEnforceLevel = podsecurity.LevelBaseline

var vpaClientSet vpa_clientset.Interface

ginkgo.BeforeEach(func() {
vpaClientSet = getVpaClientSet(f)
})

ginkgo.It("only provides recommendation to containers that exist when renaming a container", func() {
ginkgo.By("Setting up a hamster deployment")
d := NewNHamstersDeployment(f, 1 /*number of containers*/)
_ = startDeploymentPods(f, d)

ginkgo.By("Setting up VPA CRD")
vpaCRD := test.VerticalPodAutoscaler().
WithName("hamster-vpa").
WithNamespace(f.Namespace.Name).
WithTargetRef(hamsterTargetRef).
WithContainer("*").
Get()

InstallVPA(f, vpaCRD)

ginkgo.By("Waiting for recommendation to be filled for the container")
vpa, err := WaitForRecommendationPresent(vpaClientSet, vpaCRD)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
gomega.Expect(vpa.Status.Recommendation.ContainerRecommendations).Should(gomega.HaveLen(1))
gomega.Expect(vpa.Status.Recommendation.ContainerRecommendations[0].ContainerName).To(gomega.Equal(GetHamsterContainerNameByIndex(0)))

ginkgo.By("Renaming the container")
newContainerName := "renamed-container"
patchRecord := &patchRecord{
Op: "replace",
Path: "/spec/template/spec/containers/0/name",
Value: newContainerName,
}
gomega.Expect(err).NotTo(gomega.HaveOccurred())
JSONPatchDeployment(f, d, patchRecord)

ginkgo.By("Waiting for recommendation to be filled for the renamed container and only the renamed container")
time.Sleep(recommendationLoopInterval)
vpa, err = WaitForRecommendationPresent(vpaClientSet, vpaCRD)

gomega.Expect(err).NotTo(gomega.HaveOccurred())
errMsg := fmt.Sprintf("%s is the only container in the VPA CR. There should not be any recommendations for %s",
newContainerName,
GetHamsterContainerNameByIndex(0))
gomega.Expect(vpa.Status.Recommendation.ContainerRecommendations).Should(gomega.HaveLen(1), errMsg)
gomega.Expect(vpa.Status.Recommendation.ContainerRecommendations[0].ContainerName).To(gomega.Equal(newContainerName), errMsg)
})

ginkgo.It("only provides recommendation to containers that exist when removing a container", func() {
ginkgo.By("Setting up a hamster deployment")
d := NewNHamstersDeployment(f, 2 /*number of containers*/)
_ = startDeploymentPods(f, d)

ginkgo.By("Setting up VPA CRD")
vpaCRD := test.VerticalPodAutoscaler().
WithName("hamster-vpa").
WithNamespace(f.Namespace.Name).
WithTargetRef(hamsterTargetRef).
WithContainer("*").
Get()

InstallVPA(f, vpaCRD)

ginkgo.By("Waiting for recommendation to be filled for both containers")
vpa, err := WaitForRecommendationPresent(vpaClientSet, vpaCRD)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
gomega.Expect(vpa.Status.Recommendation.ContainerRecommendations).Should(gomega.HaveLen(2))

ginkgo.By("Removing the second container")
patchRecord := &patchRecord{
Op: "remove",
Path: "/spec/template/spec/containers/0",
}
gomega.Expect(err).NotTo(gomega.HaveOccurred())
JSONPatchDeployment(f, d, patchRecord)

ginkgo.By("Waiting for recommendation to be filled for just one container")
time.Sleep(recommendationLoopInterval)
vpa, err = WaitForRecommendationPresent(vpaClientSet, vpaCRD)

gomega.Expect(err).NotTo(gomega.HaveOccurred())
errMsg := fmt.Sprintf("%s is now the only container in the VPA CR. There should not be any recommendations for %s",
GetHamsterContainerNameByIndex(0),
GetHamsterContainerNameByIndex(1))
gomega.Expect(vpa.Status.Recommendation.ContainerRecommendations).Should(gomega.HaveLen(1), errMsg)
gomega.Expect(vpa.Status.Recommendation.ContainerRecommendations[0].ContainerName).To(gomega.Equal(GetHamsterContainerNameByIndex(0)), errMsg)
})

})

func deleteRecommender(c clientset.Interface) error {
namespace := "kube-system"
listOptions := metav1.ListOptions{}
Expand Down

0 comments on commit c3a1f0e

Please sign in to comment.