diff options
Diffstat (limited to 'test')
24 files changed, 1075 insertions, 92 deletions
diff --git a/test/apiv2/40-pods.at b/test/apiv2/40-pods.at index 2dea1918a..9b8ff04f0 100644 --- a/test/apiv2/40-pods.at +++ b/test/apiv2/40-pods.at @@ -25,6 +25,16 @@ t POST "libpod/pods/create (dup pod)" name=foo 409 \ #t POST libpod/pods/create a=b 400 .cause='bad parameter' # FIXME: unimplemented +t POST libpod/pods/foo/start '' 200 \ + .Errs=null \ + .Id=$pod_id + +t POST libpod/pods/foo/start '' 304 \ + +t POST libpod/pods/fakename/start '' 404 \ + .cause="no such pod" \ + .message="no pod with name or ID fakename found: no such pod" + if root || have_cgroupsv2; then t POST libpod/pods/foo/pause '' 200 else @@ -35,12 +45,72 @@ else fi t POST libpod/pods/foo/unpause '' 200 t POST "libpod/pods/foo/unpause (2nd unpause in a row)" '' 200 +t POST "libpod/pods/fakename/unpause" '' 404\ + .cause="no such pod" \ + .message="no pod with name or ID fakename found: no such pod" + + +t POST libpod/pods/foo/stop '' 200 \ + .Errs=null \ + .Id=$pod_id + t POST "libpod/pods/foo/stop (pod is already stopped)" '' 304 +t POST "libpod/pods/fakename/stop" '' 404\ + .cause="no such pod" \ + .message="no pod with name or ID fakename found: no such pod" + t POST libpod/pods/foo/restart '' 200 \ .Errs=null \ .Id=$pod_id t POST "libpod/pods/bar/restart (restart on nonexistent pod)" '' 404 +t POST libpod/pods/create name=bar 201 .Id~[0-9a-f]\\{64\\} +pod_bar_id=$(jq -r .Id <<<"$output") + +t POST libpod/pods/bar/restart '' 200 \ + .Errs=null \ + .Id=$pod_bar_id + +t GET libpod/pods/bar/json 200 \ + .State=Running + +t POST libpod/pods/bar/restart '' 200 \ + .Errs=null \ + .Id=$pod_bar_id + +t POST "libpod/pods/bar/stop?t=invalid" '' 400 \ + .cause="schema: error converting value for \"t\"" \ + .message~"Failed to parse parameters for" + +podman run -d --pod bar busybox sleep 999 + +t POST libpod/pods/bar/stop?t=1 '' 200 \ + .Errs=null \ + .Id=$pod_bar_id + +t POST libpod/pods/bar/start '' 200 + +t GET libpod/pods/stats?all=true 200 +is $(jq '. | length' <<<"$output") 3 "stats?all=true: number of records found" + +t GET libpod/pods/stats?namesOrIDs=foo 200 +is $(jq '. | length' <<<"$output") 1 "stats?namesOrIDs=foo: number of records found" + +t GET libpod/pods/stats?namesOrIDs=fakename 404 \ + .cause="no such pod" \ + .message="unable to get list of pods: no pod with name or ID fakename found: no such pod" + +t DELETE libpod/pods/bar?force=true 200 + +t GET libpod/pods/foo/top 200 \ + .Processes[0][-1]="/pause " \ + .Titles[-1]="COMMAND" + +t GET libpod/pods/foo/top?ps_args=args,pid 200 \ + .Processes[0][0]="/pause " \ + .Processes[0][1]="1" \ + .Titles[0]="COMMAND" \ + .Titles[1]="PID" \ # FIXME: I'm not sure what 'prune' is supposed to do; as of 20200224 it # just returns 200 (ok) with empty result list. diff --git a/test/dockerpy/containers.py b/test/dockerpy/containers.py deleted file mode 100644 index d70ec932c..000000000 --- a/test/dockerpy/containers.py +++ /dev/null @@ -1,46 +0,0 @@ - -import unittest -import docker -import requests -import os -from docker import Client -from . import constant -from . import common - -client = common.get_client() - -class TestContainers(unittest.TestCase): - - podman = None - - def setUp(self): - super().setUp() - common.run_top_container() - - def tearDown(self): - common.remove_all_containers() - common.remove_all_images() - return super().tearDown() - - @classmethod - def setUpClass(cls): - super().setUpClass() - common.enable_sock(cls) - - @classmethod - def tearDownClass(cls): - common.terminate_connection(cls) - return super().tearDownClass() - - def test_inspect_container(self): - # Inspect bogus container - with self.assertRaises(requests.HTTPError): - client.inspect_container("dummy") - # Inspect valid container - container = client.inspect_container(constant.TOP) - self.assertIn(constant.TOP , container["Name"]) - - -if __name__ == '__main__': - # Setup temporary space - unittest.main() diff --git a/test/e2e/build/Dockerfile.test-cp-root-dir b/test/e2e/build/Dockerfile.test-cp-root-dir new file mode 100644 index 000000000..9f7de7c32 --- /dev/null +++ b/test/e2e/build/Dockerfile.test-cp-root-dir @@ -0,0 +1,2 @@ +FROM scratch +COPY Dockerfile.test-cp-root-dir / diff --git a/test/e2e/cp_test.go b/test/e2e/cp_test.go index 6ae54ba34..3f9b12e0a 100644 --- a/test/e2e/cp_test.go +++ b/test/e2e/cp_test.go @@ -296,4 +296,42 @@ var _ = Describe("Podman cp", func() { os.Remove("testfile1") }) + It("podman cp the root directory from the ctr to an existing directory on the host ", func() { + imgName := "test-cp-root-dir:latest" + DockerfileName := "Dockerfile.test-cp-root-dir" + ctrName := "test-container-cp-root" + + session := podmanTest.PodmanNoCache([]string{"build", "-f", "build/" + DockerfileName, "-t", imgName, "build/"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + testDirPath := filepath.Join(podmanTest.RunRoot, "TestDirForCp") + + session = podmanTest.Podman([]string{"create", "--name", ctrName, imgName, "dummy"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + err := os.Mkdir(testDirPath, 0755) + Expect(err).To(BeNil()) + defer os.RemoveAll(testDirPath) + + // Copy the root directory of the container to an existing directory + session = podmanTest.Podman([]string{"cp", ctrName + ":/", testDirPath}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // The file should be in the directory, + // not one layer too much of the directory called merged + checkFile := filepath.Join(testDirPath, DockerfileName) + _, err = os.Stat(checkFile) + Expect(err).To(BeNil()) + + session = podmanTest.Podman([]string{"container", "rm", ctrName}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.PodmanNoCache([]string{"rmi", "-f", imgName}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + }) }) diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go index f40472a7c..822e470f2 100644 --- a/test/e2e/create_test.go +++ b/test/e2e/create_test.go @@ -2,6 +2,7 @@ package integration import ( "fmt" + "io/ioutil" "os" "path/filepath" @@ -221,6 +222,42 @@ var _ = Describe("Podman create", func() { Expect(match).To(BeTrue()) }) + It("podman create --pod-id-file", func() { + // First, make sure that --pod and --pod-id-file yield an error + // if used together. + session := podmanTest.Podman([]string{"create", "--pod", "foo", "--pod-id-file", "bar", ALPINE, "ls"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(125)) + + tmpDir, err := ioutil.TempDir("", "") + Expect(err).To(BeNil()) + defer os.RemoveAll(tmpDir) + + podName := "rudoplh" + ctrName := "prancer" + podIDFile := tmpDir + "pod-id-file" + + // Now, let's create a pod with --pod-id-file. + session = podmanTest.Podman([]string{"pod", "create", "--pod-id-file", podIDFile, "--name", podName}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"pod", "inspect", podName}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.IsJSONOutputValid()).To(BeTrue()) + podData := session.InspectPodToJSON() + + // Finally we can create a container with --pod-id-file and do + // some checks to make sure it's working as expected. + session = podmanTest.Podman([]string{"create", "--pod-id-file", podIDFile, "--name", ctrName, ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + ctrJSON := podmanTest.InspectContainer(ctrName) + Expect(podData.ID).To(Equal(ctrJSON[0].Pod)) // Make sure the container's pod matches the pod's ID + }) + It("podman run entrypoint and cmd test", func() { name := "test101" create := podmanTest.Podman([]string{"create", "--name", name, redis}) @@ -392,4 +429,19 @@ var _ = Describe("Podman create", func() { Expect(len(data)).To(Equal(1)) Expect(data[0].HostConfig.NanoCpus).To(Equal(int64(nanoCPUs))) }) + + It("podman create --replace", func() { + // Make sure we error out with --name. + session := podmanTest.Podman([]string{"create", "--replace", ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(125)) + + // Create and replace 5 times in a row the "same" container. + ctrName := "testCtr" + for i := 0; i < 5; i++ { + session = podmanTest.Podman([]string{"create", "--replace", "--name", ctrName, ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + } + }) }) diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go index db750bfcc..7872a9fbf 100644 --- a/test/e2e/generate_kube_test.go +++ b/test/e2e/generate_kube_test.go @@ -282,7 +282,8 @@ var _ = Describe("Podman generate kube", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - inspect1 := podmanTest.Podman([]string{"inspect", "--format", "{{.Config.User}}", "test1"}) + // container name in pod is <podName>-<ctrName> + inspect1 := podmanTest.Podman([]string{"inspect", "--format", "{{.Config.User}}", "toppod-test1"}) inspect1.WaitWithDefaultTimeout() Expect(inspect1.ExitCode()).To(Equal(0)) Expect(inspect1.OutputToString()).To(ContainSubstring(inspect.OutputToString())) @@ -295,6 +296,7 @@ var _ = Describe("Podman generate kube", func() { // we need a container name because IDs don't persist after rm/play ctrName := "test-ctr" + ctrNameInKubePod := "test1-test-ctr" session1 := podmanTest.Podman([]string{"run", "-d", "--pod", "new:test1", "--name", ctrName, "-v", vol1 + ":/volume/:z", "alpine", "top"}) session1.WaitWithDefaultTimeout() @@ -313,7 +315,7 @@ var _ = Describe("Podman generate kube", func() { play.WaitWithDefaultTimeout() Expect(play.ExitCode()).To(Equal(0)) - inspect := podmanTest.Podman([]string{"inspect", ctrName}) + inspect := podmanTest.Podman([]string{"inspect", ctrNameInKubePod}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(Equal(0)) Expect(inspect.OutputToString()).To(ContainSubstring(vol1)) diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go index d5ae441e2..497e8f71e 100644 --- a/test/e2e/generate_systemd_test.go +++ b/test/e2e/generate_systemd_test.go @@ -3,6 +3,7 @@ package integration import ( + "io/ioutil" "os" . "github.com/containers/libpod/test/utils" @@ -191,7 +192,7 @@ var _ = Describe("Podman generate systemd", func() { found, _ := session.GrepString("# container-foo.service") Expect(found).To(BeTrue()) - found, _ = session.GrepString("stop --ignore --cidfile %t/%n-cid -t 42") + found, _ = session.GrepString("stop --ignore --cidfile %t/container-foo.ctr-id -t 42") Expect(found).To(BeTrue()) }) @@ -230,7 +231,7 @@ var _ = Describe("Podman generate systemd", func() { session := podmanTest.Podman([]string{"generate", "systemd", "--time", "42", "--name", "--new", "foo"}) session.WaitWithDefaultTimeout() - Expect(session.ExitCode()).To(Equal(125)) + Expect(session.ExitCode()).To(Equal(0)) }) It("podman generate systemd --container-prefix con", func() { @@ -325,4 +326,49 @@ var _ = Describe("Podman generate systemd", func() { found, _ = session.GrepString("BindsTo=p_foo.service") Expect(found).To(BeTrue()) }) + + It("podman generate systemd pod with containers --new", func() { + tmpDir, err := ioutil.TempDir("", "") + Expect(err).To(BeNil()) + tmpFile := tmpDir + "podID" + defer os.RemoveAll(tmpDir) + + n := podmanTest.Podman([]string{"pod", "create", "--pod-id-file", tmpFile, "--name", "foo"}) + n.WaitWithDefaultTimeout() + Expect(n.ExitCode()).To(Equal(0)) + + n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-1", "alpine", "top"}) + n.WaitWithDefaultTimeout() + Expect(n.ExitCode()).To(Equal(0)) + + n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-2", "alpine", "top"}) + n.WaitWithDefaultTimeout() + Expect(n.ExitCode()).To(Equal(0)) + + session := podmanTest.Podman([]string{"generate", "systemd", "--new", "--name", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Grepping the output (in addition to unit tests) + found, _ := session.GrepString("# pod-foo.service") + Expect(found).To(BeTrue()) + + found, _ = session.GrepString("Requires=container-foo-1.service container-foo-2.service") + Expect(found).To(BeTrue()) + + found, _ = session.GrepString("BindsTo=pod-foo.service") + Expect(found).To(BeTrue()) + + found, _ = session.GrepString("pod create --infra-conmon-pidfile %t/pod-foo.pid --pod-id-file %t/pod-foo.pod-id --name foo") + Expect(found).To(BeTrue()) + + found, _ = session.GrepString("ExecStartPre=/usr/bin/rm -f %t/pod-foo.pid %t/pod-foo.pod-id") + Expect(found).To(BeTrue()) + + found, _ = session.GrepString("pod stop --ignore --pod-id-file %t/pod-foo.pod-id -t 10") + Expect(found).To(BeTrue()) + + found, _ = session.GrepString("pod rm --ignore -f --pod-id-file %t/pod-foo.pod-id") + Expect(found).To(BeTrue()) + }) }) diff --git a/test/e2e/images_test.go b/test/e2e/images_test.go index b16cff411..0ee7260c2 100644 --- a/test/e2e/images_test.go +++ b/test/e2e/images_test.go @@ -186,6 +186,17 @@ RUN apk update && apk add strace Expect(len(result.OutputToStringArray()) >= 1).To(BeTrue()) }) + It("podman images workingdir from image", func() { + dockerfile := `FROM docker.io/library/alpine:latest +WORKDIR /test +` + podmanTest.BuildImage(dockerfile, "foobar.com/workdir:latest", "false") + result := podmanTest.Podman([]string{"run", "foobar.com/workdir:latest", "pwd"}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + Expect(result.OutputToString()).To(Equal("/test")) + }) + It("podman images filter after image", func() { podmanTest.RestoreAllArtifacts() rmi := podmanTest.PodmanNoCache([]string{"rmi", "busybox"}) diff --git a/test/e2e/logs_test.go b/test/e2e/logs_test.go index f36163ccc..f9446e0c6 100644 --- a/test/e2e/logs_test.go +++ b/test/e2e/logs_test.go @@ -288,4 +288,16 @@ var _ = Describe("Podman logs", func() { logc.WaitWithDefaultTimeout() Expect(logc).To(Exit(0)) }) + + It("follow output stopped container", func() { + containerName := "logs-f" + + logc := podmanTest.Podman([]string{"run", "--name", containerName, "-d", ALPINE}) + logc.WaitWithDefaultTimeout() + Expect(logc).To(Exit(0)) + + results := podmanTest.Podman([]string{"logs", "-f", containerName}) + results.WaitWithDefaultTimeout() + Expect(results).To(Exit(0)) + }) }) diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index 9daf266b8..7fe4ce967 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -3,6 +3,7 @@ package integration import ( + "bytes" "fmt" "io/ioutil" "os" @@ -14,7 +15,18 @@ import ( . "github.com/onsi/gomega" ) -var yamlTemplate = ` +var unknownKindYaml = ` +apiVerson: v1 +kind: UnknownKind +metadata: + labels: + app: app1 + name: unknown +spec: + hostname: unknown +` + +var podYamlTemplate = ` apiVersion: v1 kind: Pod metadata: @@ -77,31 +89,137 @@ spec: status: {} ` +var deploymentYamlTemplate = ` +apiVersion: v1 +kind: Deployment +metadata: + creationTimestamp: "2019-07-17T14:44:08Z" + labels: + app: {{ .Name }} + name: {{ .Name }} +{{ with .Annotations }} + annotations: + {{ range $key, $value := . }} + {{ $key }}: {{ $value }} + {{ end }} +{{ end }} + +spec: + replicas: {{ .Replicas }} + selector: + matchLabels: + app: {{ .Name }} + template: + {{ with .PodTemplate }} + metadata: + labels: + app: {{ .Name }} + {{ with .Annotations }} + annotations: + {{ range $key, $value := . }} + {{ $key }}: {{ $value }} + {{ end }} + {{ end }} + spec: + hostname: {{ .Hostname }} + containers: + {{ with .Ctrs }} + {{ range . }} + - command: + {{ range .Cmd }} + - {{.}} + {{ end }} + env: + - name: PATH + value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + - name: TERM + value: xterm + - name: HOSTNAME + - name: container + value: podman + image: {{ .Image }} + name: {{ .Name }} + imagePullPolicy: {{ .PullPolicy }} + resources: {} + {{ if .SecurityContext }} + securityContext: + allowPrivilegeEscalation: true + {{ if .Caps }} + capabilities: + {{ with .CapAdd }} + add: + {{ range . }} + - {{.}} + {{ end }} + {{ end }} + {{ with .CapDrop }} + drop: + {{ range . }} + - {{.}} + {{ end }} + {{ end }} + {{ end }} + privileged: false + readOnlyRootFilesystem: false + workingDir: / + {{ end }} + {{ end }} + {{ end }} + {{ end }} +` + var ( - defaultCtrName = "testCtr" - defaultCtrCmd = []string{"top"} - defaultCtrImage = ALPINE - defaultPodName = "testPod" - seccompPwdEPERM = []byte(`{"defaultAction":"SCMP_ACT_ALLOW","syscalls":[{"name":"getcwd","action":"SCMP_ACT_ERRNO"}]}`) + defaultCtrName = "testCtr" + defaultCtrCmd = []string{"top"} + defaultCtrImage = ALPINE + defaultPodName = "testPod" + defaultDeploymentName = "testDeployment" + seccompPwdEPERM = []byte(`{"defaultAction":"SCMP_ACT_ALLOW","syscalls":[{"name":"getcwd","action":"SCMP_ACT_ERRNO"}]}`) ) -func generateKubeYaml(pod *Pod, fileName string) error { +func writeYaml(content string, fileName string) error { f, err := os.Create(fileName) if err != nil { return err } defer f.Close() - t, err := template.New("pod").Parse(yamlTemplate) + _, err = f.WriteString(content) if err != nil { return err } - if err := t.Execute(f, pod); err != nil { + return nil +} + +func generatePodKubeYaml(pod *Pod, fileName string) error { + templateBytes := &bytes.Buffer{} + + t, err := template.New("pod").Parse(podYamlTemplate) + if err != nil { return err } - return nil + if err := t.Execute(templateBytes, pod); err != nil { + return err + } + + return writeYaml(templateBytes.String(), fileName) +} + +func generateDeploymentKubeYaml(deployment *Deployment, fileName string) error { + templateBytes := &bytes.Buffer{} + + t, err := template.New("deployment").Parse(deploymentYamlTemplate) + if err != nil { + return err + } + + if err := t.Execute(templateBytes, deployment); err != nil { + return err + } + + return writeYaml(templateBytes.String(), fileName) } // Pod describes the options a kube yaml can be configured at pod level @@ -146,6 +264,59 @@ func withAnnotation(k, v string) podOption { } } +// Deployment describes the options a kube yaml can be configured at deployment level +type Deployment struct { + Name string + Replicas int32 + Annotations map[string]string + PodTemplate *Pod +} + +func getDeployment(options ...deploymentOption) *Deployment { + d := Deployment{defaultDeploymentName, 1, make(map[string]string), getPod()} + for _, option := range options { + option(&d) + } + + return &d +} + +type deploymentOption func(*Deployment) + +func withDeploymentAnnotation(k, v string) deploymentOption { + return func(deployment *Deployment) { + deployment.Annotations[k] = v + } +} + +func withPod(pod *Pod) deploymentOption { + return func(d *Deployment) { + d.PodTemplate = pod + } +} + +func withReplicas(replicas int32) deploymentOption { + return func(d *Deployment) { + d.Replicas = replicas + } +} + +// getPodNamesInDeployment returns list of Pod objects +// with just their name set, so that it can be passed around +// and into getCtrNameInPod for ease of testing +func getPodNamesInDeployment(d *Deployment) []Pod { + var pods []Pod + var i int32 + + for i = 0; i < d.Replicas; i++ { + p := Pod{} + p.Name = fmt.Sprintf("%s-pod-%d", d.Name, i) + pods = append(pods, p) + } + + return pods +} + // Ctr describes the options a kube yaml can be configured at container level type Ctr struct { Name string @@ -208,6 +379,10 @@ func withPullPolicy(policy string) ctrOption { } } +func getCtrNameInPod(pod *Pod) string { + return fmt.Sprintf("%s-%s", pod.Name, defaultCtrName) +} + var _ = Describe("Podman generate kube", func() { var ( tempdir string @@ -234,8 +409,18 @@ var _ = Describe("Podman generate kube", func() { processTestResult(f) }) + It("podman play kube fail with yaml of unsupported kind", func() { + err := writeYaml(unknownKindYaml, kubeYaml) + Expect(err).To(BeNil()) + + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) + kube.WaitWithDefaultTimeout() + Expect(kube.ExitCode()).To(Not(Equal(0))) + + }) + It("podman play kube fail with nonexist authfile", func() { - err := generateKubeYaml(getPod(), kubeYaml) + err := generatePodKubeYaml(getPod(), kubeYaml) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", "--authfile", "/tmp/nonexist", kubeYaml}) @@ -245,14 +430,15 @@ var _ = Describe("Podman generate kube", func() { }) It("podman play kube test correct command", func() { - err := generateKubeYaml(getPod(), kubeYaml) + pod := getPod() + err := generatePodKubeYaml(pod, kubeYaml) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() Expect(kube.ExitCode()).To(Equal(0)) - inspect := podmanTest.Podman([]string{"inspect", defaultCtrName}) + inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod)}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(Equal(0)) Expect(inspect.OutputToString()).To(ContainSubstring(defaultCtrCmd[0])) @@ -261,33 +447,34 @@ var _ = Describe("Podman generate kube", func() { It("podman play kube test correct output", func() { p := getPod(withCtr(getCtr(withCmd([]string{"echo", "hello"})))) - err := generateKubeYaml(p, kubeYaml) + err := generatePodKubeYaml(p, kubeYaml) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() Expect(kube.ExitCode()).To(Equal(0)) - logs := podmanTest.Podman([]string{"logs", defaultCtrName}) + logs := podmanTest.Podman([]string{"logs", getCtrNameInPod(p)}) logs.WaitWithDefaultTimeout() Expect(logs.ExitCode()).To(Equal(0)) Expect(logs.OutputToString()).To(ContainSubstring("hello")) - inspect := podmanTest.Podman([]string{"inspect", defaultCtrName, "--format", "'{{ .Config.Cmd }}'"}) + inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(p), "--format", "'{{ .Config.Cmd }}'"}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(Equal(0)) Expect(inspect.OutputToString()).To(ContainSubstring("hello")) }) It("podman play kube test hostname", func() { - err := generateKubeYaml(getPod(), kubeYaml) + pod := getPod() + err := generatePodKubeYaml(pod, kubeYaml) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() Expect(kube.ExitCode()).To(Equal(0)) - inspect := podmanTest.Podman([]string{"inspect", defaultCtrName, "--format", "{{ .Config.Hostname }}"}) + inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "{{ .Config.Hostname }}"}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(Equal(0)) Expect(inspect.OutputToString()).To(Equal(defaultPodName)) @@ -295,14 +482,15 @@ var _ = Describe("Podman generate kube", func() { It("podman play kube test with customized hostname", func() { hostname := "myhostname" - err := generateKubeYaml(getPod(withHostname(hostname)), kubeYaml) + pod := getPod(withHostname(hostname)) + err := generatePodKubeYaml(getPod(withHostname(hostname)), kubeYaml) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() Expect(kube.ExitCode()).To(Equal(0)) - inspect := podmanTest.Podman([]string{"inspect", defaultCtrName, "--format", "{{ .Config.Hostname }}"}) + inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "{{ .Config.Hostname }}"}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(Equal(0)) Expect(inspect.OutputToString()).To(Equal(hostname)) @@ -312,14 +500,15 @@ var _ = Describe("Podman generate kube", func() { capAdd := "CAP_SYS_ADMIN" ctr := getCtr(withCapAdd([]string{capAdd}), withCmd([]string{"cat", "/proc/self/status"})) - err := generateKubeYaml(getPod(withCtr(ctr)), kubeYaml) + pod := getPod(withCtr(ctr)) + err := generatePodKubeYaml(pod, kubeYaml) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() Expect(kube.ExitCode()).To(Equal(0)) - inspect := podmanTest.Podman([]string{"inspect", defaultCtrName}) + inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod)}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(Equal(0)) Expect(inspect.OutputToString()).To(ContainSubstring(capAdd)) @@ -329,14 +518,15 @@ var _ = Describe("Podman generate kube", func() { capDrop := "CAP_CHOWN" ctr := getCtr(withCapDrop([]string{capDrop})) - err := generateKubeYaml(getPod(withCtr(ctr)), kubeYaml) + pod := getPod(withCtr(ctr)) + err := generatePodKubeYaml(pod, kubeYaml) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() Expect(kube.ExitCode()).To(Equal(0)) - inspect := podmanTest.Podman([]string{"inspect", defaultCtrName}) + inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod)}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(Equal(0)) Expect(inspect.OutputToString()).To(ContainSubstring(capDrop)) @@ -344,14 +534,15 @@ 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(withCtr(getCtr(withSecurityContext(false)))), kubeYaml) + pod := getPod(withCtr(getCtr(withSecurityContext(false)))) + err := generatePodKubeYaml(pod, kubeYaml) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) kube.WaitWithDefaultTimeout() Expect(kube.ExitCode()).To(Equal(0)) - inspect := podmanTest.Podman([]string{"inspect", defaultCtrName}) + inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod)}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(Equal(0)) }) @@ -367,7 +558,8 @@ var _ = Describe("Podman generate kube", func() { ctrAnnotation := "container.seccomp.security.alpha.kubernetes.io/" + defaultCtrName ctr := getCtr(withCmd([]string{"pwd"})) - err = generateKubeYaml(getPod(withCtr(ctr), withAnnotation(ctrAnnotation, "localhost/"+filepath.Base(jsonFile))), kubeYaml) + pod := getPod(withCtr(ctr), withAnnotation(ctrAnnotation, "localhost/"+filepath.Base(jsonFile))) + err = generatePodKubeYaml(pod, kubeYaml) Expect(err).To(BeNil()) // CreateSeccompJson will put the profile into podmanTest.TempDir. Use --seccomp-profile-root to tell play kube where to look @@ -375,7 +567,7 @@ var _ = Describe("Podman generate kube", func() { kube.WaitWithDefaultTimeout() Expect(kube.ExitCode()).To(Equal(0)) - logs := podmanTest.Podman([]string{"logs", defaultCtrName}) + logs := podmanTest.Podman([]string{"logs", getCtrNameInPod(pod)}) logs.WaitWithDefaultTimeout() Expect(logs.ExitCode()).To(Equal(0)) Expect(logs.OutputToString()).To(ContainSubstring("Operation not permitted")) @@ -392,7 +584,8 @@ var _ = Describe("Podman generate kube", func() { ctr := getCtr(withCmd([]string{"pwd"})) - err = generateKubeYaml(getPod(withCtr(ctr), withAnnotation("seccomp.security.alpha.kubernetes.io/pod", "localhost/"+filepath.Base(jsonFile))), kubeYaml) + pod := getPod(withCtr(ctr), withAnnotation("seccomp.security.alpha.kubernetes.io/pod", "localhost/"+filepath.Base(jsonFile))) + err = generatePodKubeYaml(pod, kubeYaml) Expect(err).To(BeNil()) // CreateSeccompJson will put the profile into podmanTest.TempDir. Use --seccomp-profile-root to tell play kube where to look @@ -400,7 +593,7 @@ var _ = Describe("Podman generate kube", func() { kube.WaitWithDefaultTimeout() Expect(kube.ExitCode()).To(Equal(0)) - logs := podmanTest.Podman([]string{"logs", defaultCtrName}) + logs := podmanTest.Podman([]string{"logs", getCtrNameInPod(pod)}) logs.WaitWithDefaultTimeout() Expect(logs.ExitCode()).To(Equal(0)) Expect(logs.OutputToString()).To(ContainSubstring("Operation not permitted")) @@ -408,7 +601,7 @@ var _ = Describe("Podman generate kube", func() { It("podman play kube with pull policy of never should be 125", func() { ctr := getCtr(withPullPolicy("never"), withImage(BB_GLIBC)) - err := generateKubeYaml(getPod(withCtr(ctr)), kubeYaml) + err := generatePodKubeYaml(getPod(withCtr(ctr)), kubeYaml) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) @@ -418,7 +611,7 @@ var _ = Describe("Podman generate kube", func() { It("podman play kube with pull policy of missing", func() { ctr := getCtr(withPullPolicy("missing"), withImage(BB)) - err := generateKubeYaml(getPod(withCtr(ctr)), kubeYaml) + err := generatePodKubeYaml(getPod(withCtr(ctr)), kubeYaml) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) @@ -444,7 +637,7 @@ var _ = Describe("Podman generate kube", func() { oldBBinspect := inspect.InspectImageJSON() ctr := getCtr(withPullPolicy("always"), withImage(BB)) - err := generateKubeYaml(getPod(withCtr(ctr)), kubeYaml) + err := generatePodKubeYaml(getPod(withCtr(ctr)), kubeYaml) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) @@ -475,7 +668,7 @@ var _ = Describe("Podman generate kube", func() { oldBBinspect := inspect.InspectImageJSON() ctr := getCtr(withImage(BB)) - err := generateKubeYaml(getPod(withCtr(ctr)), kubeYaml) + err := generatePodKubeYaml(getPod(withCtr(ctr)), kubeYaml) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) @@ -519,7 +712,7 @@ spec: kube.WaitWithDefaultTimeout() Expect(kube.ExitCode()).To(Equal(0)) - inspect := podmanTest.Podman([]string{"inspect", "demo_kube"}) + inspect := podmanTest.Podman([]string{"inspect", "demo_pod-demo_kube"}) inspect.WaitWithDefaultTimeout() Expect(inspect.ExitCode()).To(Equal(0)) @@ -529,4 +722,41 @@ spec: Expect(ctr[0].Config.Labels["key1"]).To(ContainSubstring("value1")) Expect(ctr[0].Config.StopSignal).To(Equal(uint(51))) }) + + // Deployment related tests + It("podman play kube deployment 1 replica test correct command", func() { + deployment := getDeployment() + err := generateDeploymentKubeYaml(deployment, kubeYaml) + Expect(err).To(BeNil()) + + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) + kube.WaitWithDefaultTimeout() + Expect(kube.ExitCode()).To(Equal(0)) + + podNames := getPodNamesInDeployment(deployment) + inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&podNames[0])}) + inspect.WaitWithDefaultTimeout() + Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect.OutputToString()).To(ContainSubstring(defaultCtrCmd[0])) + }) + + It("podman play kube deployment more than 1 replica test correct command", func() { + var i, numReplicas int32 + numReplicas = 5 + deployment := getDeployment(withReplicas(numReplicas)) + err := generateDeploymentKubeYaml(deployment, kubeYaml) + Expect(err).To(BeNil()) + + kube := podmanTest.Podman([]string{"play", "kube", kubeYaml}) + kube.WaitWithDefaultTimeout() + Expect(kube.ExitCode()).To(Equal(0)) + + podNames := getPodNamesInDeployment(deployment) + for i = 0; i < numReplicas; i++ { + inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&podNames[i])}) + inspect.WaitWithDefaultTimeout() + Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect.OutputToString()).To(ContainSubstring(defaultCtrCmd[0])) + } + }) }) diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go index a7d5783cb..8d07f6290 100644 --- a/test/e2e/pod_create_test.go +++ b/test/e2e/pod_create_test.go @@ -305,4 +305,19 @@ var _ = Describe("Podman pod create", func() { data := check.InspectPodToJSON() Expect(data.ID).To(Equal(string(id))) }) + + It("podman pod create --replace", func() { + // Make sure we error out with --name. + session := podmanTest.Podman([]string{"pod", "create", "--replace", ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(125)) + + // Create and replace 5 times in a row the "same" pod. + podName := "testCtr" + for i := 0; i < 5; i++ { + session = podmanTest.Podman([]string{"pod", "create", "--replace", "--name", podName}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + } + }) }) diff --git a/test/e2e/pod_inspect_test.go b/test/e2e/pod_inspect_test.go index 8040adf1e..f1acd3750 100644 --- a/test/e2e/pod_inspect_test.go +++ b/test/e2e/pod_inspect_test.go @@ -57,4 +57,26 @@ var _ = Describe("Podman pod inspect", func() { podData := inspect.InspectPodToJSON() Expect(podData.ID).To(Equal(podid)) }) + + It("podman pod inspect (CreateCommand)", func() { + podName := "myTestPod" + createCommand := []string{"pod", "create", "--name", podName, "--hostname", "rudolph", "--share", "net"} + + // Create the pod. + session := podmanTest.Podman(createCommand) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Inspect the pod and make sure that the create command is + // exactly how we created the pod. + inspect := podmanTest.Podman([]string{"pod", "inspect", podName}) + inspect.WaitWithDefaultTimeout() + Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect.IsJSONOutputValid()).To(BeTrue()) + podData := inspect.InspectPodToJSON() + // Let's get the last len(createCommand) items in the command. + inspectCreateCommand := podData.CreateCommand + index := len(inspectCreateCommand) - len(createCommand) + Expect(inspectCreateCommand[index:]).To(Equal(createCommand)) + }) }) diff --git a/test/e2e/pod_rm_test.go b/test/e2e/pod_rm_test.go index 4060e1268..d0ece7b53 100644 --- a/test/e2e/pod_rm_test.go +++ b/test/e2e/pod_rm_test.go @@ -2,6 +2,7 @@ package integration import ( "fmt" + "io/ioutil" "os" "path/filepath" "strings" @@ -229,4 +230,72 @@ var _ = Describe("Podman pod rm", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) }) + + It("podman pod start/remove single pod via --pod-id-file", func() { + tmpDir, err := ioutil.TempDir("", "") + Expect(err).To(BeNil()) + tmpFile := tmpDir + "podID" + defer os.RemoveAll(tmpDir) + + podName := "rudolph" + + // Create a pod with --pod-id-file. + session := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--pod-id-file", tmpFile}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Create container inside the pod. + session = podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"pod", "start", "--pod-id-file", tmpFile}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) // infra+top + + session = podmanTest.Podman([]string{"pod", "rm", "--pod-id-file", tmpFile, "--force"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + }) + + It("podman pod start/remove multiple pods via --pod-id-file", func() { + tmpDir, err := ioutil.TempDir("", "") + Expect(err).To(BeNil()) + defer os.RemoveAll(tmpDir) + + podIDFiles := []string{} + for _, i := range "0123456789" { + tmpFile := tmpDir + "cid" + string(i) + podName := "rudolph" + string(i) + // Create a pod with --pod-id-file. + session := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--pod-id-file", tmpFile}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Create container inside the pod. + session = podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Append the id files along with the command. + podIDFiles = append(podIDFiles, "--pod-id-file") + podIDFiles = append(podIDFiles, tmpFile) + } + + cmd := []string{"pod", "start"} + cmd = append(cmd, podIDFiles...) + session := podmanTest.Podman(cmd) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(20)) // 10*(infra+top) + + cmd = []string{"pod", "rm", "--force"} + cmd = append(cmd, podIDFiles...) + session = podmanTest.Podman(cmd) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + }) }) diff --git a/test/e2e/pod_start_test.go b/test/e2e/pod_start_test.go index 8e78cadfd..d7d623d6e 100644 --- a/test/e2e/pod_start_test.go +++ b/test/e2e/pod_start_test.go @@ -1,7 +1,11 @@ package integration import ( + "fmt" + "io/ioutil" "os" + "strconv" + "strings" . "github.com/containers/libpod/test/utils" . "github.com/onsi/ginkgo" @@ -136,4 +140,94 @@ var _ = Describe("Podman pod start", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(125)) }) + + It("podman pod start single pod via --pod-id-file", func() { + tmpDir, err := ioutil.TempDir("", "") + Expect(err).To(BeNil()) + tmpFile := tmpDir + "podID" + defer os.RemoveAll(tmpDir) + + podName := "rudolph" + + // Create a pod with --pod-id-file. + session := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--pod-id-file", tmpFile}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Create container inside the pod. + session = podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"pod", "start", "--pod-id-file", tmpFile}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) // infra+top + }) + + It("podman pod start multiple pods via --pod-id-file", func() { + tmpDir, err := ioutil.TempDir("", "") + Expect(err).To(BeNil()) + defer os.RemoveAll(tmpDir) + + podIDFiles := []string{} + for _, i := range "0123456789" { + tmpFile := tmpDir + "cid" + string(i) + podName := "rudolph" + string(i) + // Create a pod with --pod-id-file. + session := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--pod-id-file", tmpFile}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Create container inside the pod. + session = podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Append the id files along with the command. + podIDFiles = append(podIDFiles, "--pod-id-file") + podIDFiles = append(podIDFiles, tmpFile) + } + + cmd := []string{"pod", "start"} + cmd = append(cmd, podIDFiles...) + session := podmanTest.Podman(cmd) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(20)) // 10*(infra+top) + }) + + It("podman pod create --infra-conmon-pod create + start", func() { + tmpDir, err := ioutil.TempDir("", "") + Expect(err).To(BeNil()) + tmpFile := tmpDir + "podID" + defer os.RemoveAll(tmpDir) + + podName := "rudolph" + // Create a pod with --infra-conmon-pid. + session := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--infra-conmon-pidfile", tmpFile}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"pod", "start", podName}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) // infra + + readFirstLine := func(path string) string { + content, err := ioutil.ReadFile(path) + Expect(err).To(BeNil()) + return strings.Split(string(content), "\n")[0] + } + + // Read the infra-conmon-pidfile and perform some sanity checks + // on the pid. + infraConmonPID := readFirstLine(tmpFile) + _, err = strconv.Atoi(infraConmonPID) // Make sure it's a proper integer + Expect(err).To(BeNil()) + + cmdline := readFirstLine(fmt.Sprintf("/proc/%s/cmdline", infraConmonPID)) + Expect(cmdline).To(ContainSubstring("/conmon")) + }) + }) diff --git a/test/e2e/pod_stop_test.go b/test/e2e/pod_stop_test.go index 0a46b07c9..0fe580921 100644 --- a/test/e2e/pod_stop_test.go +++ b/test/e2e/pod_stop_test.go @@ -1,6 +1,7 @@ package integration import ( + "io/ioutil" "os" . "github.com/containers/libpod/test/utils" @@ -175,4 +176,72 @@ var _ = Describe("Podman pod stop", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(125)) }) + + It("podman pod start/stop single pod via --pod-id-file", func() { + tmpDir, err := ioutil.TempDir("", "") + Expect(err).To(BeNil()) + tmpFile := tmpDir + "podID" + defer os.RemoveAll(tmpDir) + + podName := "rudolph" + + // Create a pod with --pod-id-file. + session := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--pod-id-file", tmpFile}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Create container inside the pod. + session = podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"pod", "start", "--pod-id-file", tmpFile}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) // infra+top + + session = podmanTest.Podman([]string{"pod", "stop", "--pod-id-file", tmpFile}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + }) + + It("podman pod start/stop multiple pods via --pod-id-file", func() { + tmpDir, err := ioutil.TempDir("", "") + Expect(err).To(BeNil()) + defer os.RemoveAll(tmpDir) + + podIDFiles := []string{} + for _, i := range "0123456789" { + tmpFile := tmpDir + "cid" + string(i) + podName := "rudolph" + string(i) + // Create a pod with --pod-id-file. + session := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--pod-id-file", tmpFile}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Create container inside the pod. + session = podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + // Append the id files along with the command. + podIDFiles = append(podIDFiles, "--pod-id-file") + podIDFiles = append(podIDFiles, tmpFile) + } + + cmd := []string{"pod", "start"} + cmd = append(cmd, podIDFiles...) + session := podmanTest.Podman(cmd) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(20)) // 10*(infra+top) + + cmd = []string{"pod", "stop"} + cmd = append(cmd, podIDFiles...) + session = podmanTest.Podman(cmd) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + }) }) diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go index 9db2f5d49..4fad85f00 100644 --- a/test/e2e/run_networking_test.go +++ b/test/e2e/run_networking_test.go @@ -129,6 +129,32 @@ var _ = Describe("Podman run networking", func() { Expect(inspectOut[0].NetworkSettings.Ports[0].HostIP).To(Equal("127.0.0.1")) }) + It("podman run -p [::1]:8080:80/udp", func() { + name := "testctr" + session := podmanTest.Podman([]string{"create", "-t", "-p", "[::1]:8080:80/udp", "--name", name, ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + inspectOut := podmanTest.InspectContainer(name) + Expect(len(inspectOut)).To(Equal(1)) + Expect(len(inspectOut[0].NetworkSettings.Ports)).To(Equal(1)) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostPort).To(Equal(int32(8080))) + Expect(inspectOut[0].NetworkSettings.Ports[0].ContainerPort).To(Equal(int32(80))) + Expect(inspectOut[0].NetworkSettings.Ports[0].Protocol).To(Equal("udp")) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostIP).To(Equal("::1")) + }) + + It("podman run -p [::1]:8080:80/tcp", func() { + name := "testctr" + session := podmanTest.Podman([]string{"create", "-t", "-p", "[::1]:8080:80/tcp", "--name", name, ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + inspectOut := podmanTest.InspectContainer(name) + Expect(len(inspectOut)).To(Equal(1)) + Expect(len(inspectOut[0].NetworkSettings.Ports)).To(Equal(1)) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostPort).To(Equal(int32(8080))) + Expect(inspectOut[0].NetworkSettings.Ports[0].ContainerPort).To(Equal(int32(80))) + Expect(inspectOut[0].NetworkSettings.Ports[0].Protocol).To(Equal("tcp")) + Expect(inspectOut[0].NetworkSettings.Ports[0].HostIP).To(Equal("::1")) + }) + It("podman run --expose 80 -P", func() { name := "testctr" session := podmanTest.Podman([]string{"create", "-t", "--expose", "80", "-P", "--name", name, ALPINE, "/bin/sh"}) diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 59215c7e5..76944b3db 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -931,4 +931,19 @@ USER mail` session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) }) + + It("podman run --replace", func() { + // Make sure we error out with --name. + session := podmanTest.Podman([]string{"create", "--replace", ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(125)) + + // Run and replace 5 times in a row the "same" container. + ctrName := "testCtr" + for i := 0; i < 5; i++ { + session := podmanTest.Podman([]string{"run", "--detach", "--replace", "--name", ctrName, ALPINE, "/bin/sh"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + } + }) }) diff --git a/test/dockerpy/README.md b/test/test_dockerpy/README.md index 32e426d58..32e426d58 100644 --- a/test/dockerpy/README.md +++ b/test/test_dockerpy/README.md diff --git a/test/dockerpy/__init__.py b/test/test_dockerpy/__init__.py index e69de29bb..e69de29bb 100644 --- a/test/dockerpy/__init__.py +++ b/test/test_dockerpy/__init__.py diff --git a/test/dockerpy/common.py b/test/test_dockerpy/common.py index fdacb49be..975b13dc6 100644 --- a/test/dockerpy/common.py +++ b/test/test_dockerpy/common.py @@ -23,13 +23,30 @@ def podman(): binary = "bin/podman" return binary -def restore_image_from_cache(): - client.load_image(constant.ImageCacheDir+alpineDict["tarballName"]) +def restore_image_from_cache(TestClass): + alpineImage = os.path.join(constant.ImageCacheDir , alpineDict["tarballName"]) + if not os.path.exists(alpineImage): + os.makedirs(constant.ImageCacheDir) + client.pull(constant.ALPINE) + response = client.get_image(constant.ALPINE) + image_tar = open(alpineImage,mode="wb") + image_tar.write(response.data) + image_tar.close() + else : + TestClass.podman = subprocess.run( + [ + podman(), "load", "-i", alpineImage + ], + shell=False, + stdin=subprocess.DEVNULL, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) def run_top_container(): - client.pull(constant.ALPINE) - c = client.create_container(constant.ALPINE,name=constant.TOP) + c = client.create_container(image=constant.ALPINE,command='/bin/sleep 5',name=constant.TOP) client.start(container=c.get("Id")) + return c.get("Id") def enable_sock(TestClass): TestClass.podman = subprocess.Popen( diff --git a/test/dockerpy/constant.py b/test/test_dockerpy/constant.py index 8a3f1d984..8a3f1d984 100644 --- a/test/dockerpy/constant.py +++ b/test/test_dockerpy/constant.py diff --git a/test/test_dockerpy/test_containers.py b/test/test_dockerpy/test_containers.py new file mode 100644 index 000000000..34fe82c18 --- /dev/null +++ b/test/test_dockerpy/test_containers.py @@ -0,0 +1,194 @@ + +import unittest +import docker +import requests +import os +from docker import Client +from . import constant +from . import common +import time + +client = common.get_client() + +class TestContainers(unittest.TestCase): + + podman = None + topContainerId = "" + + def setUp(self): + super().setUp() + common.restore_image_from_cache(self) + TestContainers.topContainerId = common.run_top_container() + + def tearDown(self): + common.remove_all_containers() + common.remove_all_images() + return super().tearDown() + + @classmethod + def setUpClass(cls): + super().setUpClass() + common.enable_sock(cls) + + @classmethod + def tearDownClass(cls): + common.terminate_connection(cls) + return super().tearDownClass() + + def test_inspect_container(self): + # Inspect bogus container + with self.assertRaises(requests.HTTPError) as error: + client.inspect_container("dummy") + self.assertEqual(error.exception.response.status_code, 404) + # Inspect valid container by name + container = client.inspect_container(constant.TOP) + self.assertIn(TestContainers.topContainerId , container["Id"]) + # Inspect valid container by Id + container = client.inspect_container(TestContainers.topContainerId) + self.assertIn(constant.TOP , container["Name"]) + + def test_create_container(self): + # Run a container with detach mode + container = client.create_container(image="alpine", detach=True) + self.assertEqual(len(container),2) + + + def test_start_container(self): + # Start bogus container + with self.assertRaises(requests.HTTPError) as error: + client.start("dummy") + self.assertEqual(error.exception.response.status_code, 404) + + # Podman docs says it should give a 304 but returns with no response + # # Start a already started container should return 304 + # response = client.start(container=TestContainers.topContainerId) + # self.assertEqual(error.exception.response.status_code, 304) + + # Create a new container and validate the count + client.create_container(image=constant.ALPINE,name="container2") + containers = client.containers(quiet=True,all=True) + self.assertEqual(len(containers),2) + + def test_stop_container(self): + # Stop bogus container + with self.assertRaises(requests.HTTPError) as error: + client.stop("dummy") + self.assertEqual(error.exception.response.status_code, 404) + + # Validate the container state + container = client.inspect_container(constant.TOP) + self.assertEqual(container["State"]["Status"], "running") + + # Stop a running container and validate the state + client.stop(TestContainers.topContainerId) + container = client.inspect_container(constant.TOP) + self.assertIn(container["State"]["Status"],"stopped exited",) + + def test_restart_container(self): + # Restart bogus container + with self.assertRaises(requests.HTTPError) as error: + client.restart("dummy") + self.assertEqual(error.exception.response.status_code, 404) + + # Validate the container state + client.stop(TestContainers.topContainerId) + container = client.inspect_container(constant.TOP) + self.assertEqual(container["State"]["Status"], "stopped") + + # restart a running container and validate the state + client.restart(TestContainers.topContainerId) + container = client.inspect_container(constant.TOP) + self.assertEqual(container["State"]["Status"], "running") + + def test_remove_container(self): + # Remove bogus container + with self.assertRaises(requests.HTTPError) as error: + client.remove_container("dummy") + self.assertEqual(error.exception.response.status_code, 404) + + # Remove container by ID with force + client.remove_container(TestContainers.topContainerId, force=True) + containers = client.containers() + self.assertEqual(len(containers),0) + + def test_remove_container_without_force(self): + # Validate current container count + containers = client.containers() + self.assertTrue(len(containers),1) + + # Remove running container should throw error + with self.assertRaises(requests.HTTPError) as error: + client.remove_container(TestContainers.topContainerId) + self.assertEqual(error.exception.response.status_code, 500) + + # Remove container by ID with force + client.stop(TestContainers.topContainerId) + client.remove_container(TestContainers.topContainerId) + containers = client.containers() + self.assertEqual(len(containers),0) + + def test_pause_container(self): + # Pause bogus container + with self.assertRaises(requests.HTTPError) as error: + client.pause("dummy") + self.assertEqual(error.exception.response.status_code, 404) + + # Validate the container state + container = client.inspect_container(constant.TOP) + self.assertEqual(container["State"]["Status"], "running") + + # Pause a running container and validate the state + client.pause(container) + container = client.inspect_container(constant.TOP) + self.assertEqual(container["State"]["Status"], "paused") + + def test_pause_stoped_container(self): + # Stop the container + client.stop(TestContainers.topContainerId) + + # Pause exited container should trow error + with self.assertRaises(requests.HTTPError) as error: + client.pause(TestContainers.topContainerId) + self.assertEqual(error.exception.response.status_code, 500) + + + def test_unpause_container(self): + # Unpause bogus container + with self.assertRaises(requests.HTTPError) as error: + client.unpause("dummy") + self.assertEqual(error.exception.response.status_code, 404) + + # Validate the container state + client.pause(TestContainers.topContainerId) + container = client.inspect_container(constant.TOP) + self.assertEqual(container["State"]["Status"], "paused") + + # Pause a running container and validate the state + client.unpause(TestContainers.topContainerId) + container = client.inspect_container(constant.TOP) + self.assertEqual(container["State"]["Status"], "running") + + def test_list_container(self): + + # Add container and validate the count + client.create_container(image="alpine", detach=True) + containers = client.containers(all=True) + self.assertEqual(len(containers),2) + + # Not working for now......checking + # # List container with filter by id + # filters = {'id':TestContainers.topContainerId} + # filteredContainers = client.containers(all=True,filters = filters) + # self.assertEqual(len(filteredContainers) , 1) + + # # List container with filter by name + # filters = {'name':constant.TOP} + # filteredContainers = client.containers(all=True,filters = filters) + # self.assertEqual(len(filteredContainers) , 1) + + @unittest.skip("Not Supported yet") + def test_rename_container(self): + # rename bogus container + with self.assertRaises(requests.HTTPError) as error: + client.rename(container="dummy", name="newname") + self.assertEqual(error.exception.response.status_code, 404) diff --git a/test/dockerpy/images.py b/test/test_dockerpy/test_images.py index 1e07d25c7..c88353b79 100644 --- a/test/dockerpy/images.py +++ b/test/test_dockerpy/test_images.py @@ -14,7 +14,7 @@ class TestImages(unittest.TestCase): podman = None def setUp(self): super().setUp() - client.pull(constant.ALPINE) + common.restore_image_from_cache(self) def tearDown(self): common.remove_all_images() @@ -73,9 +73,8 @@ class TestImages(unittest.TestCase): self.assertEqual(len(allImages), 1) # Add more images client.pull(constant.BB) - client.pull(constant.NGINX) allImages = client.images() - self.assertEqual(len(allImages) , 3) + self.assertEqual(len(allImages) , 2) # List images with filter diff --git a/test/test_dockerpy/test_info_version.py b/test/test_dockerpy/test_info_version.py new file mode 100644 index 000000000..be1a2aab9 --- /dev/null +++ b/test/test_dockerpy/test_info_version.py @@ -0,0 +1,46 @@ +import unittest +import docker +from docker import Client +from . import constant +from . import common + +client = common.get_client() + +class TestInfo_Version(unittest.TestCase): + + podman = None + topContainerId = "" + + def setUp(self): + super().setUp() + common.restore_image_from_cache(self) + TestInfo_Version.topContainerId = common.run_top_container() + + def tearDown(self): + common.remove_all_containers() + common.remove_all_images() + return super().tearDown() + + @classmethod + def setUpClass(cls): + super().setUpClass() + common.enable_sock(cls) + + @classmethod + def tearDownClass(cls): + common.terminate_connection(cls) + return super().tearDownClass() + + + def test_Info(self): + self.assertIsNotNone(client.info()) + + def test_info_container_details(self): + info = client.info() + self.assertEqual(info["Containers"],1) + client.create_container(image=constant.ALPINE) + info = client.info() + self.assertEqual(info["Containers"],2) + + def test_version(self): + self.assertIsNotNone(client.version()) |