From 45603efecb7b1ac3b7be15f9c98d9cfca471cb77 Mon Sep 17 00:00:00 2001 From: Stephen Heywood Date: Wed, 3 May 2023 12:11:11 +1200 Subject: [PATCH] Create e2e test for PodEphemeralcontainers endpoints e2e test validates the following 2 endpoints - readCoreV1NamespacedPodEphemeralcontainers - replaceCoreV1NamespacedPodEphemeralcontainers --- test/e2e/common/node/ephemeral_containers.go | 90 ++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/test/e2e/common/node/ephemeral_containers.go b/test/e2e/common/node/ephemeral_containers.go index 8a59476fc3a..d9f29f91f9d 100644 --- a/test/e2e/common/node/ephemeral_containers.go +++ b/test/e2e/common/node/ephemeral_containers.go @@ -18,10 +18,16 @@ package node import ( "context" + "fmt" "time" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + clientscheme "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/util/retry" "k8s.io/kubernetes/test/e2e/framework" e2epod "k8s.io/kubernetes/test/e2e/framework/pod" imageutils "k8s.io/kubernetes/test/utils/image" @@ -80,4 +86,88 @@ var _ = SIGDescribe("Ephemeral Containers [NodeConformance]", func() { framework.ExpectNoError(err, "Failed to get logs for pod %q ephemeral container %q", e2epod.FormatPod(pod), ecName) gomega.Expect(log).To(gomega.ContainSubstring("polo")) }) + + ginkgo.It("should update the ephemeral containers in an existing pod", func(ctx context.Context) { + ginkgo.By("creating a target pod") + pod := podClient.CreateSync(ctx, &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{Name: "ephemeral-containers-target-pod"}, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: "test-container-1", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"/bin/sleep"}, + Args: []string{"10000"}, + }, + }, + }, + }) + + ginkgo.By("adding an ephemeral container") + ecName := "debugger" + ec := &v1.EphemeralContainer{ + EphemeralContainerCommon: v1.EphemeralContainerCommon{ + Name: ecName, + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: e2epod.GenerateScriptCmd("while true; do echo polo; sleep 2; done"), + Stdin: true, + TTY: true, + }, + } + err := podClient.AddEphemeralContainerSync(ctx, pod, ec, time.Minute) + framework.ExpectNoError(err, "Failed to patch ephemeral containers in pod %q", e2epod.FormatPod(pod)) + + ginkgo.By("checking pod container endpoints") + // Can't use anything depending on kubectl here because it's not available in the node test environment + output := e2epod.ExecCommandInContainer(f, pod.Name, ecName, "/bin/echo", "marco") + gomega.Expect(output).To(gomega.ContainSubstring("marco")) + log, err := e2epod.GetPodLogs(ctx, f.ClientSet, pod.Namespace, pod.Name, ecName) + framework.ExpectNoError(err, "Failed to get logs for pod %q ephemeral container %q", e2epod.FormatPod(pod), ecName) + gomega.Expect(log).To(gomega.ContainSubstring("polo")) + + ginkgo.By(fmt.Sprintf("checking pod %q has only one ephemeralcontainer", pod.Name)) + podResource := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"} + unstruct, err := f.DynamicClient.Resource(podResource).Namespace(f.Namespace.Name).Get(ctx, "ephemeral-containers-target-pod", metav1.GetOptions{}, "ephemeralcontainers") + framework.ExpectNoError(err, "can't get ephermalcontainers") + verifyPod, err := unstructuredToPod(unstruct) + framework.ExpectNoError(err, "Getting the %q pod's ephemeralcontainers", verifyPod.Name) + gomega.Expect(verifyPod.Spec.EphemeralContainers).To(gomega.HaveLen(1), "checking ephemeralContainer count") + + ginkgo.By(fmt.Sprintf("adding another ephemeralcontainer to pod %q", pod.Name)) + var podToUpdate *v1.Pod + err = retry.RetryOnConflict(retry.DefaultRetry, func() error { + podToUpdate, err = podClient.Get(ctx, pod.Name, metav1.GetOptions{}) + framework.ExpectNoError(err, "Unable to retrieve pod %s", pod.Name) + + podToUpdate.Spec.EphemeralContainers = append(podToUpdate.Spec.EphemeralContainers, v1.EphemeralContainer{ + EphemeralContainerCommon: v1.EphemeralContainerCommon{ + Name: "debugger2", + Image: imageutils.GetE2EImage(imageutils.Agnhost), + ImagePullPolicy: "IfNotPresent", + TerminationMessagePolicy: "File", + }, + }) + _, err = podClient.UpdateEphemeralContainers(context.TODO(), pod.Name, podToUpdate, metav1.UpdateOptions{}) + return err + }) + framework.ExpectNoError(err, "Failed to update ephemeral container.") + + ginkgo.By(fmt.Sprintf("checking pod %q has only two ephemeralcontainers", pod.Name)) + unstruct, err = f.DynamicClient.Resource(podResource).Namespace(f.Namespace.Name).Get(ctx, "ephemeral-containers-target-pod", metav1.GetOptions{}, "ephemeralcontainers") + framework.ExpectNoError(err, "can't get ephermalcontainers") + verifyPod, err = unstructuredToPod(unstruct) + framework.ExpectNoError(err, "Getting the %q pod's ephemeralcontainers", verifyPod.Name) + gomega.Expect(verifyPod.Spec.EphemeralContainers).To(gomega.HaveLen(2), "checking ephemeralContainer count") + }) }) + +func unstructuredToPod(obj *unstructured.Unstructured) (*v1.Pod, error) { + json, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj) + if err != nil { + return nil, err + } + p := &v1.Pod{} + err = runtime.DecodeInto(clientscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), json, p) + + return p, err +}