From 9e52d1cfd0afa3b81d0689d0de9c5dfffc399eaa Mon Sep 17 00:00:00 2001 From: Kara Alexandra Date: Mon, 15 Aug 2016 15:07:36 -0700 Subject: [PATCH] Add test for --quiet flag for kubectl run Signed-off-by: Kara Alexandra --- test/e2e/framework/util.go | 35 ++++++++++++++------------ test/e2e/kubectl.go | 50 +++++++++++++++++++++++++++----------- 2 files changed, 56 insertions(+), 29 deletions(-) diff --git a/test/e2e/framework/util.go b/test/e2e/framework/util.go index c3244219565..0b9e746da78 100644 --- a/test/e2e/framework/util.go +++ b/test/e2e/framework/util.go @@ -2094,20 +2094,18 @@ func (b kubectlBuilder) WithStdinReader(reader io.Reader) *kubectlBuilder { return &b } -func (b kubectlBuilder) ExecOrDie() string { - str, err := b.Exec() - Logf("stdout: %q", str) +func (b kubectlBuilder) ExecOrDie() (string, string) { + stdout, stderr, err := b.Exec() // In case of i/o timeout error, try talking to the apiserver again after 2s before dying. // Note that we're still dying after retrying so that we can get visibility to triage it further. if isTimeout(err) { Logf("Hit i/o timeout error, talking to the server 2s later to see if it's temporary.") time.Sleep(2 * time.Second) - retryStr, retryErr := RunKubectl("version") - Logf("stdout: %q", retryStr) + _, retryErr := RunKubectl("version") Logf("err: %v", retryErr) } Expect(err).NotTo(HaveOccurred()) - return str + return stdout, stderr } func isTimeout(err error) bool { @@ -2124,14 +2122,14 @@ func isTimeout(err error) bool { return false } -func (b kubectlBuilder) Exec() (string, error) { +func (b kubectlBuilder) Exec() (string, string, error) { var stdout, stderr bytes.Buffer cmd := b.cmd cmd.Stdout, cmd.Stderr = &stdout, &stderr Logf("Running '%s %s'", cmd.Path, strings.Join(cmd.Args[1:], " ")) // skip arg[0] as it is printed separately if err := cmd.Start(); err != nil { - return "", fmt.Errorf("error starting %v:\nCommand stdout:\n%v\nstderr:\n%v\nerror:\n%v\n", cmd, cmd.Stdout, cmd.Stderr, err) + return "", "", fmt.Errorf("error starting %v:\nCommand stdout:\n%v\nstderr:\n%v\nerror:\n%v\n", cmd, cmd.Stdout, cmd.Stderr, err) } errCh := make(chan error, 1) go func() { @@ -2145,32 +2143,39 @@ func (b kubectlBuilder) Exec() (string, error) { Logf("rc: %d", rc) rc = int(ee.Sys().(syscall.WaitStatus).ExitStatus()) } - return "", uexec.CodeExitError{ + return "", "", uexec.CodeExitError{ Err: fmt.Errorf("error running %v:\nCommand stdout:\n%v\nstderr:\n%v\nerror:\n%v\n", cmd, cmd.Stdout, cmd.Stderr, err), Code: rc, } } case <-b.timeout: b.cmd.Process.Kill() - return "", fmt.Errorf("timed out waiting for command %v:\nCommand stdout:\n%v\nstderr:\n%v\n", cmd, cmd.Stdout, cmd.Stderr) + return "", "", fmt.Errorf("timed out waiting for command %v:\nCommand stdout:\n%v\nstderr:\n%v\n", cmd, cmd.Stdout, cmd.Stderr) } - Logf("stderr: %q", stderr.String()) - return stdout.String(), nil + + stderrString := stderr.String() + stdoutString := stdout.String() + Logf("stderr: %q", stderrString) + Logf("stdout: %q", stdoutString) + return stdoutString, stderrString, nil } // RunKubectlOrDie is a convenience wrapper over kubectlBuilder func RunKubectlOrDie(args ...string) string { - return NewKubectlCommand(args...).ExecOrDie() + stdout, _ := NewKubectlCommand(args...).ExecOrDie() + return stdout } // RunKubectl is a convenience wrapper over kubectlBuilder func RunKubectl(args ...string) (string, error) { - return NewKubectlCommand(args...).Exec() + stdout, _, err := NewKubectlCommand(args...).Exec() + return stdout, err } // RunKubectlOrDieInput is a convenience wrapper over kubectlBuilder that takes input to stdin func RunKubectlOrDieInput(data string, args ...string) string { - return NewKubectlCommand(args...).WithStdinData(data).ExecOrDie() + stdout, _ := NewKubectlCommand(args...).WithStdinData(data).ExecOrDie() + return stdout } func StartCmdAndStreamOutput(cmd *exec.Cmd) (stdout, stderr io.ReadCloser, err error) { diff --git a/test/e2e/kubectl.go b/test/e2e/kubectl.go index e7ba1f87017..1edb68f7c5f 100644 --- a/test/e2e/kubectl.go +++ b/test/e2e/kubectl.go @@ -288,7 +288,7 @@ var _ = framework.KubeDescribe("Kubectl client", func() { } By("executing a command in the container with noninteractive stdin") - execOutput = framework.NewKubectlCommand("exec", fmt.Sprintf("--namespace=%v", ns), "-i", simplePodName, "cat"). + execOutput, _ = framework.NewKubectlCommand("exec", fmt.Sprintf("--namespace=%v", ns), "-i", simplePodName, "cat"). WithStdinData("abcd1234"). ExecOrDie() if e, a := "abcd1234", execOutput; e != a { @@ -304,7 +304,7 @@ var _ = framework.KubeDescribe("Kubectl client", func() { defer closer.Close() By("executing a command in the container with pseudo-interactive stdin") - execOutput = framework.NewKubectlCommand("exec", fmt.Sprintf("--namespace=%v", ns), "-i", simplePodName, "bash"). + execOutput, _ = framework.NewKubectlCommand("exec", fmt.Sprintf("--namespace=%v", ns), "-i", simplePodName, "bash"). WithStdinReader(r). ExecOrDie() if e, a := "hi", strings.TrimSpace(execOutput); e != a { @@ -329,7 +329,7 @@ var _ = framework.KubeDescribe("Kubectl client", func() { for _, proxyVar := range []string{"https_proxy", "HTTPS_PROXY"} { proxyLogs.Reset() By("Running kubectl via an HTTP proxy using " + proxyVar) - output := framework.NewKubectlCommand(fmt.Sprintf("--namespace=%s", ns), "exec", "nginx", "echo", "running", "in", "container"). + output, _ := framework.NewKubectlCommand(fmt.Sprintf("--namespace=%s", ns), "exec", "nginx", "echo", "running", "in", "container"). WithEnv(append(os.Environ(), fmt.Sprintf("%s=%s", proxyVar, proxyAddr))). ExecOrDie() @@ -353,40 +353,40 @@ var _ = framework.KubeDescribe("Kubectl client", func() { nsFlag := fmt.Sprintf("--namespace=%v", ns) By("execing into a container with a successful command") - _, err := framework.NewKubectlCommand(nsFlag, "exec", "nginx", "--", "/bin/sh", "-c", "exit 0").Exec() + _, _, err := framework.NewKubectlCommand(nsFlag, "exec", "nginx", "--", "/bin/sh", "-c", "exit 0").Exec() ExpectNoError(err) By("execing into a container with a failing command") - _, err = framework.NewKubectlCommand(nsFlag, "exec", "nginx", "--", "/bin/sh", "-c", "exit 42").Exec() + _, _, err = framework.NewKubectlCommand(nsFlag, "exec", "nginx", "--", "/bin/sh", "-c", "exit 42").Exec() ee, ok := err.(uexec.ExitError) Expect(ok).To(Equal(true)) Expect(ee.ExitStatus()).To(Equal(42)) By("running a successful command") - _, err = framework.NewKubectlCommand(nsFlag, "run", "-i", "--image="+busyboxImage, "--restart=Never", "success", "--", "/bin/sh", "-c", "exit 0").Exec() + _, _, err = framework.NewKubectlCommand(nsFlag, "run", "-i", "--image="+busyboxImage, "--restart=Never", "success", "--", "/bin/sh", "-c", "exit 0").Exec() ExpectNoError(err) By("running a failing command") - _, err = framework.NewKubectlCommand(nsFlag, "run", "-i", "--image="+busyboxImage, "--restart=Never", "failure-1", "--", "/bin/sh", "-c", "exit 42").Exec() + _, _, err = framework.NewKubectlCommand(nsFlag, "run", "-i", "--image="+busyboxImage, "--restart=Never", "failure-1", "--", "/bin/sh", "-c", "exit 42").Exec() ee, ok = err.(uexec.ExitError) Expect(ok).To(Equal(true)) Expect(ee.ExitStatus()).To(Equal(42)) By("running a failing command without --restart=Never") - _, err = framework.NewKubectlCommand(nsFlag, "run", "-i", "--image="+busyboxImage, "--restart=OnFailure", "failure-2", "--", "/bin/sh", "-c", "cat && exit 42"). + _, _, err = framework.NewKubectlCommand(nsFlag, "run", "-i", "--image="+busyboxImage, "--restart=OnFailure", "failure-2", "--", "/bin/sh", "-c", "cat && exit 42"). WithStdinData("abcd1234"). Exec() ExpectNoError(err) By("running a failing command without --restart=Never, but with --rm") - _, err = framework.NewKubectlCommand(nsFlag, "run", "-i", "--image="+busyboxImage, "--restart=OnFailure", "--rm", "failure-3", "--", "/bin/sh", "-c", "cat && exit 42"). + _, _, err = framework.NewKubectlCommand(nsFlag, "run", "-i", "--image="+busyboxImage, "--restart=OnFailure", "--rm", "failure-3", "--", "/bin/sh", "-c", "cat && exit 42"). WithStdinData("abcd1234"). Exec() ExpectNoError(err) framework.WaitForPodToDisappear(f.Client, ns, "failure-3", labels.Everything(), 2*time.Second, wait.ForeverTestTimeout) By("running a failing command with --leave-stdin-open") - _, err = framework.NewKubectlCommand(nsFlag, "run", "-i", "--image="+busyboxImage, "--restart=Never", "failure-4", "--leave-stdin-open", "--", "/bin/sh", "-c", "exit 42"). + _, _, err = framework.NewKubectlCommand(nsFlag, "run", "-i", "--image="+busyboxImage, "--restart=Never", "failure-4", "--leave-stdin-open", "--", "/bin/sh", "-c", "exit 42"). WithStdinData("abcd1234"). Exec() ExpectNoError(err) @@ -399,7 +399,7 @@ var _ = framework.KubeDescribe("Kubectl client", func() { nsFlag := fmt.Sprintf("--namespace=%v", ns) By("executing a command with run and attach with stdin") - runOutput := framework.NewKubectlCommand(nsFlag, "run", "run-test", "--image="+busyboxImage, "--restart=OnFailure", "--attach=true", "--stdin", "--", "sh", "-c", "cat && echo 'stdin closed'"). + runOutput, _ := framework.NewKubectlCommand(nsFlag, "run", "run-test", "--image="+busyboxImage, "--restart=OnFailure", "--attach=true", "--stdin", "--", "sh", "-c", "cat && echo 'stdin closed'"). WithStdinData("abcd1234"). ExecOrDie() Expect(runOutput).To(ContainSubstring("abcd1234")) @@ -407,7 +407,7 @@ var _ = framework.KubeDescribe("Kubectl client", func() { Expect(c.Extensions().Jobs(ns).Delete("run-test", nil)).To(BeNil()) By("executing a command with run and attach without stdin") - runOutput = framework.NewKubectlCommand(fmt.Sprintf("--namespace=%v", ns), "run", "run-test-2", "--image="+busyboxImage, "--restart=OnFailure", "--attach=true", "--leave-stdin-open=true", "--", "sh", "-c", "cat && echo 'stdin closed'"). + runOutput, _ = framework.NewKubectlCommand(fmt.Sprintf("--namespace=%v", ns), "run", "run-test-2", "--image="+busyboxImage, "--restart=OnFailure", "--attach=true", "--leave-stdin-open=true", "--", "sh", "-c", "cat && echo 'stdin closed'"). WithStdinData("abcd1234"). ExecOrDie() Expect(runOutput).ToNot(ContainSubstring("abcd1234")) @@ -415,7 +415,7 @@ var _ = framework.KubeDescribe("Kubectl client", func() { Expect(c.Extensions().Jobs(ns).Delete("run-test-2", nil)).To(BeNil()) By("executing a command with run and attach with stdin with open stdin should remain running") - runOutput = framework.NewKubectlCommand(nsFlag, "run", "run-test-3", "--image="+busyboxImage, "--restart=OnFailure", "--attach=true", "--leave-stdin-open=true", "--stdin", "--", "sh", "-c", "cat && echo 'stdin closed'"). + runOutput, _ = framework.NewKubectlCommand(nsFlag, "run", "run-test-3", "--image="+busyboxImage, "--restart=OnFailure", "--attach=true", "--leave-stdin-open=true", "--stdin", "--", "sh", "-c", "cat && echo 'stdin closed'"). WithStdinData("abcd1234\n"). ExecOrDie() Expect(runOutput).ToNot(ContainSubstring("stdin closed")) @@ -1146,7 +1146,7 @@ var _ = framework.KubeDescribe("Kubectl client", func() { By("executing a command with run --rm and attach with stdin") t := time.NewTimer(runJobTimeout) defer t.Stop() - runOutput := framework.NewKubectlCommand(nsFlag, "run", jobName, "--image="+busyboxImage, "--rm=true", "--generator=job/v1", "--restart=OnFailure", "--attach=true", "--stdin", "--", "sh", "-c", "cat && echo 'stdin closed'"). + runOutput, _ := framework.NewKubectlCommand(nsFlag, "run", jobName, "--image="+busyboxImage, "--rm=true", "--generator=job/v1", "--restart=OnFailure", "--attach=true", "--stdin", "--", "sh", "-c", "cat && echo 'stdin closed'"). WithStdinData("abcd1234"). WithTimeout(t.C). ExecOrDie() @@ -1160,6 +1160,28 @@ var _ = framework.KubeDescribe("Kubectl client", func() { }) }) + framework.KubeDescribe("Kubectl run --quiet job", func() { + jobName := "e2e-test-quiet-busybox-job" + + It("should not output anything except the command when --quiet is set", func() { + nsFlag := fmt.Sprintf("--namespace=%v", ns) + + // The rkt runtime doesn't support attach, see #23335 + framework.SkipIfContainerRuntimeIs("rkt") + framework.SkipUnlessServerVersionGTE(jobsVersion, c) + + By("executing a command with run --rm and attach with stdin") + t := time.NewTimer(runJobTimeout) + defer t.Stop() + // TODO: remove sleep when attach works immediately + stdout, stderr := framework.NewKubectlCommand(nsFlag, "run", jobName, "--image="+busyboxImage, "--quiet", "--rm", "--restart=Never", "--stdin", "--attach", "--generator=job/v1", "--", "sh", "-c", "sleep 3; echo output; sleep 3"). + WithTimeout(t.C). + ExecOrDie() + Expect(stdout).To(Equal("output\n"), "Checking STDOUT contains only our output") + Expect(stderr).To(Equal(""), "Checking STDERR is empty") + }) + }) + framework.KubeDescribe("Proxy server", func() { // TODO: test proxy options (static, prefix, etc) It("should support proxy with --port 0 [Conformance]", func() {