From f448c01651df7fda732f87ae9364aeb689529735 Mon Sep 17 00:00:00 2001 From: "Julian V. Modesto" Date: Thu, 26 Mar 2020 17:15:12 -0400 Subject: [PATCH] Add kubectl diff + server-side dry-run to e2e --- test/e2e/framework/util.go | 2 +- test/e2e/kubectl/kubectl.go | 65 +++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/test/e2e/framework/util.go b/test/e2e/framework/util.go index aff45e0b959..471ecfcfdd2 100644 --- a/test/e2e/framework/util.go +++ b/test/e2e/framework/util.go @@ -647,7 +647,7 @@ func (b KubectlBuilder) Exec() (string, error) { rc = int(ee.Sys().(syscall.WaitStatus).ExitStatus()) Logf("rc: %d", rc) } - return "", uexec.CodeExitError{ + return stdout.String(), uexec.CodeExitError{ Err: fmt.Errorf("error running %v:\nCommand stdout:\n%v\nstderr:\n%v\nerror:\n%v", cmd, cmd.Stdout, cmd.Stderr, err), Code: rc, } diff --git a/test/e2e/kubectl/kubectl.go b/test/e2e/kubectl/kubectl.go index 425a3edb0a1..346be0edff2 100644 --- a/test/e2e/kubectl/kubectl.go +++ b/test/e2e/kubectl/kubectl.go @@ -853,6 +853,71 @@ metadata: }) }) + ginkgo.Describe("Kubectl diff", func() { + /* + Release : v1.18 + Testname: Kubectl, diff Deployment + Description: Create a Deployment with httpd image. Declare the same Deployment with a different image, busybox. Diff of live Deployment with declared Deployment MUST include the difference between live and declared image. + */ + ginkgo.It("should find diff in Deployment", func() { + ginkgo.By("create deployment with httpd image") + deployment := commonutils.SubstituteImageName(string(readTestFileOrDie(httpdDeployment3Filename))) + framework.RunKubectlOrDieInput(ns, deployment, "create", "-f", "-") + + ginkgo.By("verify diff finds difference between live and declared image") + deployment = strings.Replace(deployment, httpdImage, busyboxImage, 1) + if !strings.Contains(deployment, busyboxImage) { + framework.Failf("Failed replacing image from %s to %s in:\n%s\n", httpdImage, busyboxImage, deployment) + } + output, err := framework.RunKubectlInput(ns, deployment, "diff", "-f", "-") + if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 { + framework.Failf("Expected kubectl diff exit code of 1, but got %d: %v\n", err.ExitCode(), err) + } + requiredItems := []string{httpdImage, busyboxImage} + for _, item := range requiredItems { + if !strings.Contains(output, item) { + framework.Failf("Missing %s in kubectl diff output:\n%s\n%v\n", item, output, err) + } + } + + framework.RunKubectlOrDieInput(ns, deployment, "delete", "-f", "-") + }) + }) + + ginkgo.Describe("Kubectl server-side dry-run", func() { + /* + Release : v1.18 + Testname: Kubectl, server-side dry-run Pod + Description: The command 'kubectl run' must create a pod with the specified image name. After, the command 'kubectl replace --dry-run=server' should update the Pod with the new image name and server-side dry-run enabled. The image name must not change. + */ + ginkgo.It("should dry-run update the Pod", func() { + ginkgo.By("running the image " + httpdImage) + podName := "e2e-test-httpd-pod" + nsFlag := fmt.Sprintf("--namespace=%v", ns) + framework.RunKubectlOrDie(ns, "run", podName, "--image="+httpdImage, "--labels=run="+podName, nsFlag) + + ginkgo.By("replace the image in the pod with server-side dry-run") + podJSON := framework.RunKubectlOrDie(ns, "get", "pod", podName, "-o", "json", nsFlag) + podJSON = strings.Replace(podJSON, httpdImage, busyboxImage, 1) + if !strings.Contains(podJSON, busyboxImage) { + framework.Failf("Failed replacing image from %s to %s in:\n%s\n", httpdImage, busyboxImage, podJSON) + } + framework.RunKubectlOrDieInput(ns, podJSON, "replace", "-f", "-", "--dry-run", "server", nsFlag) + + ginkgo.By("verifying the pod " + podName + " has the right image " + httpdImage) + pod, err := c.CoreV1().Pods(ns).Get(context.TODO(), podName, metav1.GetOptions{}) + if err != nil { + framework.Failf("Failed getting pod %s: %v", podName, err) + } + containers := pod.Spec.Containers + if checkContainersImage(containers, httpdImage) { + framework.Failf("Failed creating pod with expected image %s", httpdImage) + } + + framework.RunKubectlOrDie(ns, "delete", "pods", podName, nsFlag) + }) + }) + // definitionMatchesGVK returns true if the specified GVK is listed as an x-kubernetes-group-version-kind extension definitionMatchesGVK := func(extensions []*openapi_v2.NamedAny, desiredGVK schema.GroupVersionKind) bool { for _, extension := range extensions {