From 6ad4fb0c49c5a023b94cda64c0b7c0385a17af9b Mon Sep 17 00:00:00 2001 From: Peter Hunt Date: Thu, 10 Oct 2019 20:34:29 -0400 Subject: play kube: refactor test suite The play kube test suite has many different cases to cover, and should only grow in coverage over time The old design was difficult to extend, and there was lots of duplicated code. The largest pain point was the Container struct needed to be changed often, and doing so caused changes every test case Instead, adopt the `withOption` idiom. Now, adding a new option for customizing just involves adding a new withOption function, and changing the struct definition and initialization in one place. Signed-off-by: Peter Hunt --- test/e2e/play_kube_test.go | 201 ++++++++++++++++++++++++++++----------------- 1 file changed, 127 insertions(+), 74 deletions(-) (limited to 'test/e2e') diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index 5d59f0eb0..5fc5b65ac 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -67,40 +67,120 @@ spec: status: {} ` +var ( + defaultCtrName = "testCtr" + defaultCtrCmd = []string{"top"} + defaultCtrImage = ALPINE + defaultPodName = "testPod" +) + +func generateKubeYaml(pod *Pod, fileName string) error { + f, err := os.Create(fileName) + if err != nil { + return err + } + defer f.Close() + + t, err := template.New("pod").Parse(yamlTemplate) + if err != nil { + return err + } + + if err := t.Execute(f, pod); err != nil { + return err + } + + return nil +} + +// Pod describes the options a kube yaml can be configured at pod level type Pod struct { Name string Hostname string - Containers []Container + Containers []*Container +} + +// getPod takes a list of podOptions and returns a pod with sane defaults +// and the configured options +// if no containers are added, it will add the default container +func getPod(options ...podOption) *Pod { + p := Pod{defaultPodName, "", make([]*Container, 0)} + for _, option := range options { + option(&p) + } + if len(p.Containers) == 0 { + p.Containers = []*Container{getContainer()} + } + return &p +} + +type podOption func(*Pod) + +func withHostname(h string) podOption { + return func(pod *Pod) { + pod.Hostname = h + } +} + +func withContainer(c *Container) podOption { + return func(pod *Pod) { + pod.Containers = append(pod.Containers, c) + } } +// Container describes the options a kube yaml can be configured at container level type Container struct { - Cmd []string - Image string Name string + Image string + Cmd []string SecurityContext bool Caps bool CapAdd []string CapDrop []string } -func generateKubeYaml(name string, hostname string, ctrs []Container, fileName string) error { - f, err := os.Create(fileName) - if err != nil { - return err +// getContainer takes a list of containerOptions and returns a container with sane defaults +// and the configured options +func getContainer(options ...containerOption) *Container { + c := Container{defaultCtrName, defaultCtrImage, defaultCtrCmd, true, false, nil, nil} + for _, option := range options { + option(&c) } - defer f.Close() - testPod := Pod{name, hostname, ctrs} + return &c +} - t, err := template.New("pod").Parse(yamlTemplate) - if err != nil { - return err +type containerOption func(*Container) + +func withCmd(cmd []string) containerOption { + return func(c *Container) { + c.Cmd = cmd } +} - if err := t.Execute(f, testPod); err != nil { - return err +func withImage(img string) containerOption { + return func(c *Container) { + c.Image = img } +} - return nil +func withSecurityContext(sc bool) containerOption { + return func(c *Container) { + c.SecurityContext = sc + } +} + +func withCapAdd(caps []string) containerOption { + return func(c *Container) { + c.CapAdd = caps + c.Caps = true + } +} + +func withCapDrop(caps []string) containerOption { + return func(c *Container) { + c.CapDrop = caps + c.Caps = true + } } var _ = Describe("Podman generate kube", func() { @@ -108,6 +188,7 @@ var _ = Describe("Podman generate kube", func() { tempdir string err error podmanTest *PodmanTestIntegration + kubeYaml string ) BeforeEach(func() { @@ -118,6 +199,8 @@ var _ = Describe("Podman generate kube", func() { podmanTest = PodmanTestCreate(tempdir) podmanTest.Setup() podmanTest.SeedImages() + + kubeYaml = filepath.Join(podmanTest.TempDir, "kube.yaml") }) AfterEach(func() { @@ -127,123 +210,98 @@ var _ = Describe("Podman generate kube", func() { }) It("podman play kube test correct command", func() { - ctrName := "testCtr" - ctrCmd := []string{"top"} - testContainer := Container{ctrCmd, ALPINE, ctrName, true, false, nil, nil} - tempFile := filepath.Join(podmanTest.TempDir, "kube.yaml") - - err := generateKubeYaml("test", "", []Container{testContainer}, tempFile) + err := generateKubeYaml(getPod(), kubeYaml) Expect(err).To(BeNil()) - kube := podmanTest.Podman([]string{"play", "kube", tempFile}) + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() Expect(kube.ExitCode()).To(Equal(0)) - inspect := podmanTest.Podman([]string{"inspect", ctrName}) + inspect := podmanTest.Podman([]string{"inspect", defaultCtrName}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(Equal(0)) - Expect(inspect.OutputToString()).To(ContainSubstring(ctrCmd[0])) + Expect(inspect.OutputToString()).To(ContainSubstring(defaultCtrCmd[0])) }) It("podman play kube test correct output", func() { - ctrName := "testCtr" - ctrCmd := []string{"echo", "hello"} - testContainer := Container{ctrCmd, ALPINE, ctrName, true, false, nil, nil} - tempFile := filepath.Join(podmanTest.TempDir, "kube.yaml") + p := getPod(withContainer(getContainer(withCmd([]string{"echo", "hello"})))) - err := generateKubeYaml("test", "", []Container{testContainer}, tempFile) + err := generateKubeYaml(p, kubeYaml) Expect(err).To(BeNil()) - kube := podmanTest.Podman([]string{"play", "kube", tempFile}) + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() Expect(kube.ExitCode()).To(Equal(0)) - logs := podmanTest.Podman([]string{"logs", ctrName}) + logs := podmanTest.Podman([]string{"logs", defaultCtrName}) logs.WaitWithDefaultTimeout() Expect(logs.ExitCode()).To(Equal(0)) Expect(logs.OutputToString()).To(ContainSubstring("hello")) - inspect := podmanTest.Podman([]string{"inspect", ctrName, "--format", "'{{ .Config.Cmd }}'"}) + inspect := podmanTest.Podman([]string{"inspect", defaultCtrName, "--format", "'{{ .Config.Cmd }}'"}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(Equal(0)) Expect(inspect.OutputToString()).To(ContainSubstring("hello")) }) It("podman play kube test hostname", func() { - podName := "test" - ctrName := "testCtr" - ctrCmd := []string{"top"} - testContainer := Container{ctrCmd, ALPINE, ctrName, true, false, nil, nil} - tempFile := filepath.Join(podmanTest.TempDir, "kube.yaml") - - err := generateKubeYaml(podName, "", []Container{testContainer}, tempFile) + err := generateKubeYaml(getPod(), kubeYaml) Expect(err).To(BeNil()) - kube := podmanTest.Podman([]string{"play", "kube", tempFile}) + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() Expect(kube.ExitCode()).To(Equal(0)) - inspect := podmanTest.Podman([]string{"inspect", ctrName, "--format", "{{ .Config.Hostname }}"}) + inspect := podmanTest.Podman([]string{"inspect", defaultCtrName, "--format", "{{ .Config.Hostname }}"}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(Equal(0)) - Expect(inspect.OutputToString()).To(Equal(podName)) + Expect(inspect.OutputToString()).To(Equal(defaultPodName)) }) It("podman play kube test with customized hostname", func() { hostname := "myhostname" - ctrName := "testCtr" - ctrCmd := []string{"top"} - testContainer := Container{ctrCmd, ALPINE, ctrName, true, false, nil, nil} - tempFile := filepath.Join(podmanTest.TempDir, "kube.yaml") - - err := generateKubeYaml("test", hostname, []Container{testContainer}, tempFile) + err := generateKubeYaml(getPod(withHostname(hostname)), kubeYaml) Expect(err).To(BeNil()) - kube := podmanTest.Podman([]string{"play", "kube", tempFile}) + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() Expect(kube.ExitCode()).To(Equal(0)) - inspect := podmanTest.Podman([]string{"inspect", ctrName, "--format", "{{ .Config.Hostname }}"}) + inspect := podmanTest.Podman([]string{"inspect", defaultCtrName, "--format", "{{ .Config.Hostname }}"}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(Equal(0)) Expect(inspect.OutputToString()).To(Equal(hostname)) }) It("podman play kube cap add", func() { - ctrName := "testCtr" - ctrCmd := []string{"cat", "/proc/self/status"} capAdd := "CAP_SYS_ADMIN" - testContainer := Container{ctrCmd, ALPINE, ctrName, true, true, []string{capAdd}, nil} - tempFile := filepath.Join(podmanTest.TempDir, "kube.yaml") + ctr := getContainer(withCapAdd([]string{capAdd}), withCmd([]string{"cat", "/proc/self/status"})) - err := generateKubeYaml("test", "", []Container{testContainer}, tempFile) + err := generateKubeYaml(getPod(withContainer(ctr)), kubeYaml) Expect(err).To(BeNil()) - kube := podmanTest.Podman([]string{"play", "kube", tempFile}) + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() Expect(kube.ExitCode()).To(Equal(0)) - inspect := podmanTest.Podman([]string{"inspect", ctrName}) + inspect := podmanTest.Podman([]string{"inspect", defaultCtrName}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(Equal(0)) Expect(inspect.OutputToString()).To(ContainSubstring(capAdd)) }) - It("podman play kube cap add", func() { - ctrName := "testCtr" - ctrCmd := []string{"cat", "/proc/self/status"} - capDrop := "CAP_SYS_ADMIN" - testContainer := Container{ctrCmd, ALPINE, ctrName, true, true, []string{capDrop}, nil} - tempFile := filepath.Join(podmanTest.TempDir, "kube.yaml") + It("podman play kube cap drop", func() { + capDrop := "CAP_CHOWN" + ctr := getContainer(withCapDrop([]string{capDrop})) - err := generateKubeYaml("test", "", []Container{testContainer}, tempFile) + err := generateKubeYaml(getPod(withContainer(ctr)), kubeYaml) Expect(err).To(BeNil()) - kube := podmanTest.Podman([]string{"play", "kube", tempFile}) + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() Expect(kube.ExitCode()).To(Equal(0)) - inspect := podmanTest.Podman([]string{"inspect", ctrName}) + inspect := podmanTest.Podman([]string{"inspect", defaultCtrName}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(Equal(0)) Expect(inspect.OutputToString()).To(ContainSubstring(capDrop)) @@ -251,19 +309,14 @@ var _ = Describe("Podman generate kube", func() { It("podman play kube no security context", func() { // expect play kube to not fail if no security context is specified - ctrName := "testCtr" - ctrCmd := "ls" - testContainer := Container{[]string{ctrCmd}, ALPINE, ctrName, false, false, nil, nil} - tempFile := filepath.Join(podmanTest.TempDir, "kube.yaml") - - err := generateKubeYaml("test", "", []Container{testContainer}, tempFile) + err := generateKubeYaml(getPod(withContainer(getContainer(withSecurityContext(false)))), kubeYaml) Expect(err).To(BeNil()) - kube := podmanTest.Podman([]string{"play", "kube", tempFile}) + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() Expect(kube.ExitCode()).To(Equal(0)) - inspect := podmanTest.Podman([]string{"inspect", ctrName}) + inspect := podmanTest.Podman([]string{"inspect", defaultCtrName}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(Equal(0)) }) -- cgit v1.2.3-54-g00ecf From e0fda971daded84e9f886c7ebd545c6eac074633 Mon Sep 17 00:00:00 2001 From: Peter Hunt Date: Fri, 11 Oct 2019 13:10:25 -0400 Subject: play kube: Container->Ctr for berevity Signed-off-by: Peter Hunt --- test/e2e/play_kube_test.go | 62 +++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 31 deletions(-) (limited to 'test/e2e') diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index 5fc5b65ac..7069e049d 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -23,7 +23,7 @@ metadata: spec: hostname: {{ .Hostname }} containers: -{{ with .Containers }} +{{ with .Ctrs }} {{ range . }} - command: {{ range .Cmd }} @@ -95,21 +95,21 @@ func generateKubeYaml(pod *Pod, fileName string) error { // Pod describes the options a kube yaml can be configured at pod level type Pod struct { - Name string - Hostname string - Containers []*Container + Name string + Hostname string + Ctrs []*Ctr } // getPod takes a list of podOptions and returns a pod with sane defaults // and the configured options // if no containers are added, it will add the default container func getPod(options ...podOption) *Pod { - p := Pod{defaultPodName, "", make([]*Container, 0)} + p := Pod{defaultPodName, "", make([]*Ctr, 0)} for _, option := range options { option(&p) } - if len(p.Containers) == 0 { - p.Containers = []*Container{getContainer()} + if len(p.Ctrs) == 0 { + p.Ctrs = []*Ctr{getCtr()} } return &p } @@ -122,14 +122,14 @@ func withHostname(h string) podOption { } } -func withContainer(c *Container) podOption { +func withCtr(c *Ctr) podOption { return func(pod *Pod) { - pod.Containers = append(pod.Containers, c) + pod.Ctrs = append(pod.Ctrs, c) } } -// Container describes the options a kube yaml can be configured at container level -type Container struct { +// Ctr describes the options a kube yaml can be configured at container level +type Ctr struct { Name string Image string Cmd []string @@ -139,45 +139,45 @@ type Container struct { CapDrop []string } -// getContainer takes a list of containerOptions and returns a container with sane defaults +// getCtr takes a list of ctrOptions and returns a Ctr with sane defaults // and the configured options -func getContainer(options ...containerOption) *Container { - c := Container{defaultCtrName, defaultCtrImage, defaultCtrCmd, true, false, nil, nil} +func getCtr(options ...ctrOption) *Ctr { + c := Ctr{defaultCtrName, defaultCtrImage, defaultCtrCmd, true, false, nil, nil} for _, option := range options { option(&c) } return &c } -type containerOption func(*Container) +type ctrOption func(*Ctr) -func withCmd(cmd []string) containerOption { - return func(c *Container) { +func withCmd(cmd []string) ctrOption { + return func(c *Ctr) { c.Cmd = cmd } } -func withImage(img string) containerOption { - return func(c *Container) { +func withImage(img string) ctrOption { + return func(c *Ctr) { c.Image = img } } -func withSecurityContext(sc bool) containerOption { - return func(c *Container) { +func withSecurityContext(sc bool) ctrOption { + return func(c *Ctr) { c.SecurityContext = sc } } -func withCapAdd(caps []string) containerOption { - return func(c *Container) { +func withCapAdd(caps []string) ctrOption { + return func(c *Ctr) { c.CapAdd = caps c.Caps = true } } -func withCapDrop(caps []string) containerOption { - return func(c *Container) { +func withCapDrop(caps []string) ctrOption { + return func(c *Ctr) { c.CapDrop = caps c.Caps = true } @@ -224,7 +224,7 @@ var _ = Describe("Podman generate kube", func() { }) It("podman play kube test correct output", func() { - p := getPod(withContainer(getContainer(withCmd([]string{"echo", "hello"})))) + p := getPod(withCtr(getCtr(withCmd([]string{"echo", "hello"})))) err := generateKubeYaml(p, kubeYaml) Expect(err).To(BeNil()) @@ -275,9 +275,9 @@ var _ = Describe("Podman generate kube", func() { It("podman play kube cap add", func() { capAdd := "CAP_SYS_ADMIN" - ctr := getContainer(withCapAdd([]string{capAdd}), withCmd([]string{"cat", "/proc/self/status"})) + ctr := getCtr(withCapAdd([]string{capAdd}), withCmd([]string{"cat", "/proc/self/status"})) - err := generateKubeYaml(getPod(withContainer(ctr)), kubeYaml) + err := generateKubeYaml(getPod(withCtr(ctr)), kubeYaml) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) @@ -292,9 +292,9 @@ var _ = Describe("Podman generate kube", func() { It("podman play kube cap drop", func() { capDrop := "CAP_CHOWN" - ctr := getContainer(withCapDrop([]string{capDrop})) + ctr := getCtr(withCapDrop([]string{capDrop})) - err := generateKubeYaml(getPod(withContainer(ctr)), kubeYaml) + err := generateKubeYaml(getPod(withCtr(ctr)), kubeYaml) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) @@ -309,7 +309,7 @@ var _ = Describe("Podman generate kube", func() { It("podman play kube no security context", func() { // expect play kube to not fail if no security context is specified - err := generateKubeYaml(getPod(withContainer(getContainer(withSecurityContext(false)))), kubeYaml) + err := generateKubeYaml(getPod(withCtr(getCtr(withSecurityContext(false)))), kubeYaml) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) -- cgit v1.2.3-54-g00ecf