diff --git a/test/e2e/kubectl/kubectl.go b/test/e2e/kubectl/kubectl.go index 934f0e3e460..11c085ae7bf 100644 --- a/test/e2e/kubectl/kubectl.go +++ b/test/e2e/kubectl/kubectl.go @@ -108,6 +108,7 @@ var ( redisImage = imageutils.GetE2EImage(imageutils.Redis) httpdImage = imageutils.GetE2EImage(imageutils.Httpd) busyboxImage = imageutils.GetE2EImage(imageutils.BusyBox) + agnhostImage = imageutils.GetE2EImage(imageutils.Agnhost) ) var ( @@ -1291,23 +1292,23 @@ metadata: framework.KubeDescribe("Kubectl logs", func() { var nsFlag string - var rc string - containerName := "redis-master" + podName := "logs-generator" + containerName := "logs-generator" ginkgo.BeforeEach(func() { - ginkgo.By("creating an rc") - rc = commonutils.SubstituteImageName(string(readTestFileOrDie(redisControllerFilename))) + ginkgo.By("creating an pod") nsFlag = fmt.Sprintf("--namespace=%v", ns) - framework.RunKubectlOrDieInput(rc, "create", "-f", "-", nsFlag) + // Agnhost image generates logs for a total of 100 lines over 20s. + framework.RunKubectlOrDie("run", podName, "--generator=run-pod/v1", "--image="+agnhostImage, nsFlag, "--", "logs-generator", "--log-lines-total", "100", "--run-duration", "20s") }) ginkgo.AfterEach(func() { - cleanupKubectlInputs(rc, ns, simplePodSelector) + framework.RunKubectlOrDie("delete", "pod", podName, nsFlag) }) /* Release : v1.9 Testname: Kubectl, logs Description: When a Pod is running then it MUST generate logs. - Starting a Pod should have a log line indicating the server is running and ready to accept connections. Also log command options MUST work as expected and described below. + Starting a Pod should have a expected log line. Also log command options MUST work as expected and described below. ‘kubectl log -tail=1’ should generate a output of one line, the last line in the log. ‘kubectl --limit-bytes=1’ should generate a single byte output. ‘kubectl --tail=1 --timestamp should generate one line with timestamp in RFC3339 format @@ -1321,46 +1322,47 @@ metadata: return strings.Split(strings.TrimRight(out, "\n"), "\n") } - ginkgo.By("Waiting for Redis master to start.") - waitForOrFailWithDebug(1) - forEachPod(func(pod v1.Pod) { - ginkgo.By("checking for a matching strings") - _, err := framework.LookForStringInLog(ns, pod.Name, containerName, "Ready to accept connections", framework.PodStartTimeout) - framework.ExpectNoError(err) + ginkgo.By("Waiting for log generator to start.") + if !e2epod.CheckPodsRunningReadyOrSucceeded(c, ns, []string{podName}, framework.PodStartTimeout) { + e2elog.Failf("Pod %s was not ready", podName) + } - ginkgo.By("limiting log lines") - out := framework.RunKubectlOrDie("log", pod.Name, containerName, nsFlag, "--tail=1") - gomega.Expect(len(out)).NotTo(gomega.BeZero()) - framework.ExpectEqual(len(lines(out)), 1) + ginkgo.By("checking for a matching strings") + _, err := framework.LookForStringInLog(ns, podName, containerName, "/api/v1/namespaces/kube-system", framework.PodStartTimeout) + framework.ExpectNoError(err) - ginkgo.By("limiting log bytes") - out = framework.RunKubectlOrDie("log", pod.Name, containerName, nsFlag, "--limit-bytes=1") - framework.ExpectEqual(len(lines(out)), 1) - framework.ExpectEqual(len(out), 1) + ginkgo.By("limiting log lines") + out := framework.RunKubectlOrDie("log", podName, containerName, nsFlag, "--tail=1") + gomega.Expect(len(out)).NotTo(gomega.BeZero()) + framework.ExpectEqual(len(lines(out)), 1) - ginkgo.By("exposing timestamps") - out = framework.RunKubectlOrDie("log", pod.Name, containerName, nsFlag, "--tail=1", "--timestamps") - l := lines(out) - framework.ExpectEqual(len(l), 1) - words := strings.Split(l[0], " ") - gomega.Expect(len(words)).To(gomega.BeNumerically(">", 1)) - if _, err := time.Parse(time.RFC3339Nano, words[0]); err != nil { - if _, err := time.Parse(time.RFC3339, words[0]); err != nil { - e2elog.Failf("expected %q to be RFC3339 or RFC3339Nano", words[0]) - } + ginkgo.By("limiting log bytes") + out = framework.RunKubectlOrDie("log", podName, containerName, nsFlag, "--limit-bytes=1") + framework.ExpectEqual(len(lines(out)), 1) + framework.ExpectEqual(len(out), 1) + + ginkgo.By("exposing timestamps") + out = framework.RunKubectlOrDie("log", podName, containerName, nsFlag, "--tail=1", "--timestamps") + l := lines(out) + framework.ExpectEqual(len(l), 1) + words := strings.Split(l[0], " ") + gomega.Expect(len(words)).To(gomega.BeNumerically(">", 1)) + if _, err := time.Parse(time.RFC3339Nano, words[0]); err != nil { + if _, err := time.Parse(time.RFC3339, words[0]); err != nil { + e2elog.Failf("expected %q to be RFC3339 or RFC3339Nano", words[0]) } + } - ginkgo.By("restricting to a time range") - // Note: we must wait at least two seconds, - // because the granularity is only 1 second and - // it could end up rounding the wrong way. - time.Sleep(2500 * time.Millisecond) // ensure that startup logs on the node are seen as older than 1s - recentOut := framework.RunKubectlOrDie("log", pod.Name, containerName, nsFlag, "--since=1s") - recent := len(strings.Split(recentOut, "\n")) - olderOut := framework.RunKubectlOrDie("log", pod.Name, containerName, nsFlag, "--since=24h") - older := len(strings.Split(olderOut, "\n")) - gomega.Expect(recent).To(gomega.BeNumerically("<", older), "expected recent(%v) to be less than older(%v)\nrecent lines:\n%v\nolder lines:\n%v\n", recent, older, recentOut, olderOut) - }) + ginkgo.By("restricting to a time range") + // Note: we must wait at least two seconds, + // because the granularity is only 1 second and + // it could end up rounding the wrong way. + time.Sleep(2500 * time.Millisecond) // ensure that startup logs on the node are seen as older than 1s + recentOut := framework.RunKubectlOrDie("log", podName, containerName, nsFlag, "--since=1s") + recent := len(strings.Split(recentOut, "\n")) + olderOut := framework.RunKubectlOrDie("log", podName, containerName, nsFlag, "--since=24h") + older := len(strings.Split(olderOut, "\n")) + gomega.Expect(recent).To(gomega.BeNumerically("<", older), "expected recent(%v) to be less than older(%v)\nrecent lines:\n%v\nolder lines:\n%v\n", recent, older, recentOut, olderOut) }) })