Use netexec container in http lifecycle hook test.

This commit is contained in:
Random-Liu 2016-11-18 10:29:37 -08:00
parent 70296869e9
commit e0cdeb4c2a
2 changed files with 147 additions and 74 deletions

View File

@ -18,6 +18,7 @@ package framework
import ( import (
"fmt" "fmt"
"regexp"
"sync" "sync"
"time" "time"
@ -173,3 +174,20 @@ func (c *PodClient) WaitForSuccess(name string, timeout time.Duration) {
}, },
)).To(Succeed(), "wait for pod %q to success", name) )).To(Succeed(), "wait for pod %q to success", name)
} }
// MatchContainerOutput gest output of a container and match expected regexp in the output.
func (c *PodClient) MatchContainerOutput(name string, containerName string, expectedRegexp string) error {
f := c.f
output, err := GetPodLogs(f.ClientSet, f.Namespace.Name, name, containerName)
if err != nil {
return fmt.Errorf("failed to get output for container %q of pod %q", containerName, name)
}
regex, err := regexp.Compile(expectedRegexp)
if err != nil {
return fmt.Errorf("failed to compile regexp %q: %v", expectedRegexp, err)
}
if !regex.MatchString(output) {
return fmt.Errorf("failed to match regexp %q in output %q", expectedRegexp, output)
}
return nil
}

View File

@ -26,16 +26,27 @@ import (
"k8s.io/kubernetes/test/e2e/framework" "k8s.io/kubernetes/test/e2e/framework"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
) )
var _ = framework.KubeDescribe("Container Lifecycle Hook", func() { var _ = framework.KubeDescribe("Container Lifecycle Hook", func() {
f := framework.NewDefaultFramework("container-lifecycle-hook") f := framework.NewDefaultFramework("container-lifecycle-hook")
var podClient *framework.PodClient var podClient *framework.PodClient
var file string const (
const podWaitTimeout = 2 * time.Minute podCheckInterval = 1 * time.Second
podWaitTimeout = 2 * time.Minute
postStartWaitTimeout = 2 * time.Minute
preStopWaitTimeout = 30 * time.Second
)
Context("when create a pod with lifecycle hook", func() {
BeforeEach(func() {
podClient = f.PodClient()
})
testPodWithHook := func(podWithHook *api.Pod) { Context("when it is exec hook", func() {
podCheckHook := getLifecycleHookTestPod("pod-check-hook", var file string
testPodWithExecHook := func(podWithHook *api.Pod) {
podCheckHook := getExecHookTestPod("pod-check-hook",
// Wait until the file is created. // Wait until the file is created.
[]string{"sh", "-c", fmt.Sprintf("while [ ! -e %s ]; do sleep 1; done", file)}, []string{"sh", "-c", fmt.Sprintf("while [ ! -e %s ]; do sleep 1; done", file)},
) )
@ -45,7 +56,7 @@ var _ = framework.KubeDescribe("Container Lifecycle Hook", func() {
By("create the hook check pod") By("create the hook check pod")
podClient.Create(podCheckHook) podClient.Create(podCheckHook)
By("wait for the hook check pod to success") By("wait for the hook check pod to success")
podClient.WaitForSuccess(podCheckHook.Name, podWaitTimeout) podClient.WaitForSuccess(podCheckHook.Name, postStartWaitTimeout)
} }
By("delete the pod with lifecycle hook") By("delete the pod with lifecycle hook")
podClient.DeleteSync(podWithHook.Name, api.NewDeleteOptions(15), podWaitTimeout) podClient.DeleteSync(podWithHook.Name, api.NewDeleteOptions(15), podWaitTimeout)
@ -53,26 +64,23 @@ var _ = framework.KubeDescribe("Container Lifecycle Hook", func() {
By("create the hook check pod") By("create the hook check pod")
podClient.Create(podCheckHook) podClient.Create(podCheckHook)
By("wait for the prestop check pod to success") By("wait for the prestop check pod to success")
podClient.WaitForSuccess(podCheckHook.Name, podWaitTimeout) podClient.WaitForSuccess(podCheckHook.Name, preStopWaitTimeout)
} }
} }
Context("when create a pod with lifecycle hook", func() {
BeforeEach(func() { BeforeEach(func() {
podClient = f.PodClient()
file = "/tmp/test-" + string(uuid.NewUUID()) file = "/tmp/test-" + string(uuid.NewUUID())
}) })
AfterEach(func() { AfterEach(func() {
By("cleanup the temporary file created in the test.") By("cleanup the temporary file created in the test.")
cleanupPod := getLifecycleHookTestPod("pod-clean-up", []string{"rm", file}) cleanupPod := getExecHookTestPod("pod-clean-up", []string{"rm", file})
podClient.Create(cleanupPod) podClient.Create(cleanupPod)
podClient.WaitForSuccess(cleanupPod.Name, podWaitTimeout) podClient.WaitForSuccess(cleanupPod.Name, podWaitTimeout)
}) })
Context("when it is exec hook", func() {
It("should execute poststart exec hook properly [Conformance]", func() { It("should execute poststart exec hook properly [Conformance]", func() {
podWithHook := getLifecycleHookTestPod("pod-with-poststart-exec-hook", podWithHook := getExecHookTestPod("pod-with-poststart-exec-hook",
// Block forever // Block forever
[]string{"tail", "-f", "/dev/null"}, []string{"tail", "-f", "/dev/null"},
) )
@ -81,11 +89,11 @@ var _ = framework.KubeDescribe("Container Lifecycle Hook", func() {
Exec: &api.ExecAction{Command: []string{"touch", file}}, Exec: &api.ExecAction{Command: []string{"touch", file}},
}, },
} }
testPodWithHook(podWithHook) testPodWithExecHook(podWithHook)
}) })
It("should execute prestop exec hook properly [Conformance]", func() { It("should execute prestop exec hook properly [Conformance]", func() {
podWithHook := getLifecycleHookTestPod("pod-with-prestop-exec-hook", podWithHook := getExecHookTestPod("pod-with-prestop-exec-hook",
// Block forever // Block forever
[]string{"tail", "-f", "/dev/null"}, []string{"tail", "-f", "/dev/null"},
) )
@ -94,64 +102,111 @@ var _ = framework.KubeDescribe("Container Lifecycle Hook", func() {
Exec: &api.ExecAction{Command: []string{"touch", file}}, Exec: &api.ExecAction{Command: []string{"touch", file}},
}, },
} }
testPodWithHook(podWithHook) testPodWithExecHook(podWithHook)
}) })
}) })
Context("when it is http hook", func() { Context("when it is http hook", func() {
var targetIP string var targetIP string
BeforeEach(func() { podHandleHookRequest := &api.Pod{
By("cleanup the container to handle the HTTPGet hook request.") ObjectMeta: api.ObjectMeta{
podHandleHookRequest := getLifecycleHookTestPod("pod-handle-http-request", Name: "pod-handle-http-request",
[]string{"sh", "-c",
// Create test file when receive request on 1234.
fmt.Sprintf("echo -e \"HTTP/1.1 200 OK\n\" | nc -l -p 1234; touch %s", file),
}, },
) Spec: api.PodSpec{
podHandleHookRequest.Spec.Containers[0].Ports = []api.ContainerPort{ Containers: []api.Container{
{ {
ContainerPort: 1234, Name: "pod-handle-http-request",
Image: "gcr.io/google_containers/netexec:1.7",
Ports: []api.ContainerPort{
{
ContainerPort: 8080,
Protocol: api.ProtocolTCP, Protocol: api.ProtocolTCP,
}, },
},
},
},
},
} }
podHandleHookRequest = podClient.CreateSync(podHandleHookRequest) BeforeEach(func() {
targetIP = podHandleHookRequest.Status.PodIP By("create the container to handle the HTTPGet hook request.")
newPod := podClient.CreateSync(podHandleHookRequest)
targetIP = newPod.Status.PodIP
}) })
testPodWithHttpHook := func(podWithHook *api.Pod) {
By("create the pod with lifecycle hook")
podClient.CreateSync(podWithHook)
if podWithHook.Spec.Containers[0].Lifecycle.PostStart != nil {
By("check poststart hook")
Eventually(func() error {
return podClient.MatchContainerOutput(podHandleHookRequest.Name, podHandleHookRequest.Spec.Containers[0].Name,
`GET /echo\?msg=poststart`)
}, postStartWaitTimeout, podCheckInterval).Should(BeNil())
}
By("delete the pod with lifecycle hook")
podClient.DeleteSync(podWithHook.Name, api.NewDeleteOptions(15), podWaitTimeout)
if podWithHook.Spec.Containers[0].Lifecycle.PreStop != nil {
By("check prestop hook")
Eventually(func() error {
return podClient.MatchContainerOutput(podHandleHookRequest.Name, podHandleHookRequest.Spec.Containers[0].Name,
`GET /echo\?msg=prestop`)
}, preStopWaitTimeout, podCheckInterval).Should(BeNil())
}
}
It("should execute poststart http hook properly [Conformance]", func() { It("should execute poststart http hook properly [Conformance]", func() {
podWithHook := getLifecycleHookTestPod("pod-with-poststart-http-hook", podWithHook := &api.Pod{
// Block forever ObjectMeta: api.ObjectMeta{
[]string{"tail", "-f", "/dev/null"}, Name: "pod-with-poststart-http-hook",
) },
podWithHook.Spec.Containers[0].Lifecycle = &api.Lifecycle{ Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "pod-with-poststart-http-hook",
Image: framework.GetPauseImageNameForHostArch(),
Lifecycle: &api.Lifecycle{
PostStart: &api.Handler{ PostStart: &api.Handler{
HTTPGet: &api.HTTPGetAction{ HTTPGet: &api.HTTPGetAction{
Path: "/echo?msg=poststart",
Host: targetIP, Host: targetIP,
Port: intstr.FromInt(1234), Port: intstr.FromInt(8080),
},
},
},
},
}, },
}, },
} }
testPodWithHook(podWithHook) testPodWithHttpHook(podWithHook)
}) })
It("should execute prestop http hook properly [Conformance]", func() { It("should execute prestop http hook properly [Conformance]", func() {
podWithHook := getLifecycleHookTestPod("pod-with-prestop-http-hook", podWithHook := &api.Pod{
// Block forever ObjectMeta: api.ObjectMeta{
[]string{"tail", "-f", "/dev/null"}, Name: "pod-with-prestop-http-hook",
) },
podWithHook.Spec.Containers[0].Lifecycle = &api.Lifecycle{ Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "pod-with-prestop-http-hook",
Image: framework.GetPauseImageNameForHostArch(),
Lifecycle: &api.Lifecycle{
PreStop: &api.Handler{ PreStop: &api.Handler{
HTTPGet: &api.HTTPGetAction{ HTTPGet: &api.HTTPGetAction{
Path: "/echo?msg=prestop",
Host: targetIP, Host: targetIP,
Port: intstr.FromInt(1234), Port: intstr.FromInt(8080),
},
},
},
},
}, },
}, },
} }
testPodWithHook(podWithHook) testPodWithHttpHook(podWithHook)
}) })
}) })
}) })
}) })
func getLifecycleHookTestPod(name string, cmd []string) *api.Pod { func getExecHookTestPod(name string, cmd []string) *api.Pod {
return &api.Pod{ return &api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: name, Name: name,