func runLivenessTest(f *framework.Framework, pod *api.Pod, expectNumRestarts int, timeout time.Duration) { podClient := f.PodClient() ns := f.Namespace.Name Expect(pod.Spec.Containers).NotTo(BeEmpty()) containerName := pod.Spec.Containers[0].Name // At the end of the test, clean up by removing the pod. defer func() { By("deleting the pod") podClient.Delete(pod.Name, api.NewDeleteOptions(0)) }() By(fmt.Sprintf("Creating pod %s in namespace %s", pod.Name, ns)) podClient.Create(pod) // Wait until the pod is not pending. (Here we need to check for something other than // 'Pending' other than checking for 'Running', since when failures occur, we go to // 'Terminated' which can cause indefinite blocking.) framework.ExpectNoError(framework.WaitForPodNotPending(f.ClientSet, ns, pod.Name, pod.ResourceVersion), fmt.Sprintf("starting pod %s in namespace %s", pod.Name, ns)) framework.Logf("Started pod %s in namespace %s", pod.Name, ns) // Check the pod's current state and verify that restartCount is present. By("checking the pod's current state and verifying that restartCount is present") pod, err := podClient.Get(pod.Name) framework.ExpectNoError(err, fmt.Sprintf("getting pod %s in namespace %s", pod.Name, ns)) initialRestartCount := api.GetExistingContainerStatus(pod.Status.ContainerStatuses, containerName).RestartCount framework.Logf("Initial restart count of pod %s is %d", pod.Name, initialRestartCount) // Wait for the restart state to be as desired. deadline := time.Now().Add(timeout) lastRestartCount := initialRestartCount observedRestarts := int32(0) for start := time.Now(); time.Now().Before(deadline); time.Sleep(2 * time.Second) { pod, err = podClient.Get(pod.Name) framework.ExpectNoError(err, fmt.Sprintf("getting pod %s", pod.Name)) restartCount := api.GetExistingContainerStatus(pod.Status.ContainerStatuses, containerName).RestartCount if restartCount != lastRestartCount { framework.Logf("Restart count of pod %s/%s is now %d (%v elapsed)", ns, pod.Name, restartCount, time.Since(start)) if restartCount < lastRestartCount { framework.Failf("Restart count should increment monotonically: restart cont of pod %s/%s changed from %d to %d", ns, pod.Name, lastRestartCount, restartCount) } } observedRestarts = restartCount - initialRestartCount if expectNumRestarts > 0 && int(observedRestarts) >= expectNumRestarts { // Stop if we have observed more than expectNumRestarts restarts. break } lastRestartCount = restartCount } // If we expected 0 restarts, fail if observed any restart. // If we expected n restarts (n > 0), fail if we observed < n restarts. if (expectNumRestarts == 0 && observedRestarts > 0) || (expectNumRestarts > 0 && int(observedRestarts) < expectNumRestarts) { framework.Failf("pod %s/%s - expected number of restarts: %d, found restarts: %d", ns, pod.Name, expectNumRestarts, observedRestarts) } }
func runLivenessTest(c *client.Client, ns string, podDescr *api.Pod, expectNumRestarts int) { By(fmt.Sprintf("Creating pod %s in namespace %s", podDescr.Name, ns)) _, err := c.Pods(ns).Create(podDescr) expectNoError(err, fmt.Sprintf("creating pod %s", podDescr.Name)) // At the end of the test, clean up by removing the pod. defer func() { By("deleting the pod") c.Pods(ns).Delete(podDescr.Name, api.NewDeleteOptions(0)) }() // Wait until the pod is not pending. (Here we need to check for something other than // 'Pending' other than checking for 'Running', since when failures occur, we go to // 'Terminated' which can cause indefinite blocking.) expectNoError(waitForPodNotPending(c, ns, podDescr.Name), fmt.Sprintf("starting pod %s in namespace %s", podDescr.Name, ns)) By(fmt.Sprintf("Started pod %s in namespace %s", podDescr.Name, ns)) // Check the pod's current state and verify that restartCount is present. By("checking the pod's current state and verifying that restartCount is present") pod, err := c.Pods(ns).Get(podDescr.Name) expectNoError(err, fmt.Sprintf("getting pod %s in namespace %s", podDescr.Name, ns)) initialRestartCount := api.GetExistingContainerStatus(pod.Status.ContainerStatuses, "liveness").RestartCount By(fmt.Sprintf("Initial restart count of pod %s is %d", podDescr.Name, initialRestartCount)) // Wait for the restart state to be as desired. deadline := time.Now().Add(2 * time.Minute) lastRestartCount := initialRestartCount observedRestarts := 0 for start := time.Now(); time.Now().Before(deadline); time.Sleep(2 * time.Second) { pod, err = c.Pods(ns).Get(podDescr.Name) expectNoError(err, fmt.Sprintf("getting pod %s", podDescr.Name)) restartCount := api.GetExistingContainerStatus(pod.Status.ContainerStatuses, "liveness").RestartCount if restartCount != lastRestartCount { By(fmt.Sprintf("Restart count of pod %s/%s is now %d (%v elapsed)", ns, podDescr.Name, restartCount, time.Since(start))) if restartCount < lastRestartCount { Failf("Restart count should increment monotonically: restart cont of pod %s/%s changed from %d to %d", ns, podDescr.Name, lastRestartCount, restartCount) } } observedRestarts = restartCount - initialRestartCount if expectNumRestarts > 0 && observedRestarts >= expectNumRestarts { // Stop if we have observed more than expectNumRestarts restarts. break } lastRestartCount = restartCount } // If we expected 0 restarts, fail if observed any restart. // If we expected n restarts (n > 0), fail if we observed < n restarts. if (expectNumRestarts == 0 && observedRestarts > 0) || (expectNumRestarts > 0 && observedRestarts < expectNumRestarts) { Failf("pod %s/%s - expected number of restarts: %t, found restarts: %t", ns, podDescr.Name, expectNumRestarts, observedRestarts) } }
func runLivenessTest(c *client.Client, ns string, podDescr *api.Pod, expectRestart bool) { By(fmt.Sprintf("Creating pod %s in namespace %s", podDescr.Name, ns)) _, err := c.Pods(ns).Create(podDescr) expectNoError(err, fmt.Sprintf("creating pod %s", podDescr.Name)) // At the end of the test, clean up by removing the pod. defer func() { By("deleting the pod") c.Pods(ns).Delete(podDescr.Name, api.NewDeleteOptions(0)) }() // Wait until the pod is not pending. (Here we need to check for something other than // 'Pending' other than checking for 'Running', since when failures occur, we go to // 'Terminated' which can cause indefinite blocking.) expectNoError(waitForPodNotPending(c, ns, podDescr.Name), fmt.Sprintf("starting pod %s in namespace %s", podDescr.Name, ns)) By(fmt.Sprintf("Started pod %s in namespace %s", podDescr.Name, ns)) // Check the pod's current state and verify that restartCount is present. By("checking the pod's current state and verifying that restartCount is present") pod, err := c.Pods(ns).Get(podDescr.Name) expectNoError(err, fmt.Sprintf("getting pod %s in namespace %s", podDescr.Name, ns)) initialRestartCount := api.GetExistingContainerStatus(pod.Status.ContainerStatuses, "liveness").RestartCount By(fmt.Sprintf("Initial restart count of pod %s is %d", podDescr.Name, initialRestartCount)) // Wait for the restart state to be as desired. restarts, deadline := false, time.Now().Add(2*time.Minute) for start := time.Now(); time.Now().Before(deadline); time.Sleep(2 * time.Second) { pod, err = c.Pods(ns).Get(podDescr.Name) expectNoError(err, fmt.Sprintf("getting pod %s", podDescr.Name)) restartCount := api.GetExistingContainerStatus(pod.Status.ContainerStatuses, "liveness").RestartCount By(fmt.Sprintf("Restart count of pod %s/%s is now %d (%v elapsed)", ns, podDescr.Name, restartCount, time.Since(start))) if restartCount > initialRestartCount { By(fmt.Sprintf("Restart count of pod %s/%s changed from %d to %d", ns, podDescr.Name, initialRestartCount, restartCount)) restarts = true break } } if restarts != expectRestart { Failf("pod %s/%s - expected restarts: %t, found restarts: %t", ns, podDescr.Name, expectRestart, restarts) } }
return filepath.Join(testContext.RepoRoot, "docs", "user-guide", "liveness", file) } execYaml := mkpath("exec-liveness.yaml") httpYaml := mkpath("http-liveness.yaml") nsFlag := fmt.Sprintf("--namespace=%v", ns) runKubectlOrDie("create", "-f", execYaml, nsFlag) runKubectlOrDie("create", "-f", httpYaml, nsFlag) checkRestart := func(podName string, timeout time.Duration) { err := waitForPodRunningInNamespace(c, podName, ns) Expect(err).NotTo(HaveOccurred()) for t := time.Now(); time.Since(t) < timeout; time.Sleep(poll) { pod, err := c.Pods(ns).Get(podName) expectNoError(err, fmt.Sprintf("getting pod %s", podName)) restartCount := api.GetExistingContainerStatus(pod.Status.ContainerStatuses, "liveness").RestartCount Logf("Pod: %s restart count:%d", podName, restartCount) if restartCount > 0 { return } } Failf("Pod %s was not restarted", podName) } By("Check restarts") checkRestart("liveness-exec", time.Minute) checkRestart("liveness-http", time.Minute) }) }) Describe("[Skipped][Example]Secret", func() { It("should create a pod that reads a secret", func() {
httpYaml := mkpath("http-liveness.yaml") nsFlag := fmt.Sprintf("--namespace=%v", ns) framework.RunKubectlOrDie("create", "-f", filepath.Join(framework.TestContext.OutputDir, execYaml), nsFlag) framework.RunKubectlOrDie("create", "-f", filepath.Join(framework.TestContext.OutputDir, httpYaml), nsFlag) // Since both containers start rapidly, we can easily run this test in parallel. var wg sync.WaitGroup passed := true checkRestart := func(podName string, timeout time.Duration) { err := framework.WaitForPodNameRunningInNamespace(c, podName, ns) Expect(err).NotTo(HaveOccurred()) for t := time.Now(); time.Since(t) < timeout; time.Sleep(framework.Poll) { pod, err := c.Pods(ns).Get(podName) framework.ExpectNoError(err, fmt.Sprintf("getting pod %s", podName)) stat := api.GetExistingContainerStatus(pod.Status.ContainerStatuses, podName) framework.Logf("Pod: %s, restart count:%d", stat.Name, stat.RestartCount) if stat.RestartCount > 0 { framework.Logf("Saw %v restart, succeeded...", podName) wg.Done() return } } framework.Logf("Failed waiting for %v restart! ", podName) passed = false wg.Done() } By("Check restarts") // Start the "actual test", and wait for both pods to complete.