diff options
Diffstat (limited to 'test/e2e')
-rw-r--r-- | test/e2e/checkpoint_test.go | 164 | ||||
-rw-r--r-- | test/e2e/healthcheck_run_test.go | 10 | ||||
-rw-r--r-- | test/e2e/network_create_test.go | 49 | ||||
-rw-r--r-- | test/e2e/play_kube_test.go | 2 | ||||
-rw-r--r-- | test/e2e/prune_test.go | 50 | ||||
-rw-r--r-- | test/e2e/pull_test.go | 2 | ||||
-rw-r--r-- | test/e2e/run_test.go | 4 | ||||
-rw-r--r-- | test/e2e/volume_prune_test.go | 31 |
8 files changed, 290 insertions, 22 deletions
diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go index b5bbfcd5c..1c9a8dc6f 100644 --- a/test/e2e/checkpoint_test.go +++ b/test/e2e/checkpoint_test.go @@ -1,11 +1,13 @@ package integration import ( + "fmt" "net" "os" "os/exec" "strings" + "github.com/containers/podman/v3/pkg/checkpoint/crutils" "github.com/containers/podman/v3/pkg/criu" . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" @@ -46,7 +48,7 @@ var _ = Describe("Podman checkpoint", func() { Skip("OCI runtime does not support checkpoint/restore") } - if !criu.CheckForCriu() { + if !criu.CheckForCriu(criu.MinCriuVersion) { Skip("CRIU is missing or too old.") } // Only Fedora 29 and newer has a new enough selinux-policy and @@ -977,4 +979,164 @@ var _ = Describe("Podman checkpoint", func() { // Remove exported checkpoint os.Remove(fileName) }) + + namespaceCombination := []string{ + "cgroup,ipc,net,uts,pid", + "cgroup,ipc,net,uts", + "cgroup,ipc,net", + "cgroup,ipc", + "ipc,net,uts,pid", + "ipc,net,uts", + "ipc,net", + "net,uts,pid", + "net,uts", + "uts,pid", + } + for _, share := range namespaceCombination { + testName := fmt.Sprintf( + "podman checkpoint and restore container out of and into pod (%s)", + share, + ) + It(testName, func() { + if !criu.CheckForCriu(criu.PodCriuVersion) { + Skip("CRIU is missing or too old.") + } + if !crutils.CRRuntimeSupportsPodCheckpointRestore(podmanTest.OCIRuntime) { + Skip("runtime does not support pod restore") + } + // Create a pod + session := podmanTest.Podman([]string{ + "pod", + "create", + "--share", + share, + }) + session.WaitWithDefaultTimeout() + Expect(session).To(Exit(0)) + podID := session.OutputToString() + + session = podmanTest.Podman([]string{ + "run", + "-d", + "--rm", + "--pod", + podID, + ALPINE, + "top", + }) + session.WaitWithDefaultTimeout() + Expect(session).To(Exit(0)) + cid := session.OutputToString() + + fileName := "/tmp/checkpoint-" + cid + ".tar.gz" + + // Checkpoint the container + result := podmanTest.Podman([]string{ + "container", + "checkpoint", + "-e", + fileName, + cid, + }) + result.WaitWithDefaultTimeout() + + // As the container has been started with '--rm' it will be completely + // cleaned up after checkpointing. + Expect(result).To(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + Expect(podmanTest.NumberOfContainers()).To(Equal(1)) + + // Remove the pod and create a new pod + result = podmanTest.Podman([]string{ + "pod", + "rm", + podID, + }) + result.WaitWithDefaultTimeout() + Expect(result).To(Exit(0)) + + // First create a pod with different shared namespaces. + // Restore should fail + + wrongShare := share[:strings.LastIndex(share, ",")] + + session = podmanTest.Podman([]string{ + "pod", + "create", + "--share", + wrongShare, + }) + session.WaitWithDefaultTimeout() + Expect(session).To(Exit(0)) + podID = session.OutputToString() + + // Restore container with different port mapping + result = podmanTest.Podman([]string{ + "container", + "restore", + "--pod", + podID, + "-i", + fileName, + }) + result.WaitWithDefaultTimeout() + Expect(result).To(Exit(125)) + Expect(result.ErrorToString()).To(ContainSubstring("does not share the")) + + // Remove the pod and create a new pod + result = podmanTest.Podman([]string{ + "pod", + "rm", + podID, + }) + result.WaitWithDefaultTimeout() + Expect(result).To(Exit(0)) + + session = podmanTest.Podman([]string{ + "pod", + "create", + "--share", + share, + }) + session.WaitWithDefaultTimeout() + Expect(session).To(Exit(0)) + podID = session.OutputToString() + + // Restore container with different port mapping + result = podmanTest.Podman([]string{ + "container", + "restore", + "--pod", + podID, + "-i", + fileName, + }) + result.WaitWithDefaultTimeout() + + Expect(result).To(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) + Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) + + result = podmanTest.Podman([]string{ + "rm", + "-f", + result.OutputToString(), + }) + result.WaitWithDefaultTimeout() + Expect(result).To(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + Expect(podmanTest.NumberOfContainers()).To(Equal(1)) + + result = podmanTest.Podman([]string{ + "pod", + "rm", + "-fa", + }) + result.WaitWithDefaultTimeout() + Expect(result).To(Exit(0)) + + // Remove exported checkpoint + os.Remove(fileName) + }) + } }) diff --git a/test/e2e/healthcheck_run_test.go b/test/e2e/healthcheck_run_test.go index 28040ecfd..535783dbd 100644 --- a/test/e2e/healthcheck_run_test.go +++ b/test/e2e/healthcheck_run_test.go @@ -174,6 +174,16 @@ var _ = Describe("Podman healthcheck run", func() { Expect(inspect[0].State.Healthcheck.Status).To(Equal("healthy")) }) + It("podman healthcheck unhealthy but valid arguments check", func() { + session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--health-retries", "2", "--health-cmd", "[\"ls\", \"/foo\"]", ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + hc := podmanTest.Podman([]string{"healthcheck", "run", "hc"}) + hc.WaitWithDefaultTimeout() + Expect(hc.ExitCode()).To(Equal(1)) + }) + It("podman healthcheck single healthy result changes failed to healthy", func() { session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--health-retries", "2", "--health-cmd", "ls /foo || exit 1", ALPINE, "top"}) session.WaitWithDefaultTimeout() diff --git a/test/e2e/network_create_test.go b/test/e2e/network_create_test.go index 2bec88020..fb4a144fa 100644 --- a/test/e2e/network_create_test.go +++ b/test/e2e/network_create_test.go @@ -244,10 +244,59 @@ var _ = Describe("Podman network create", func() { Expect(bridgePlugin.IPAM.Routes[0].Dest).To(Equal("::/0")) Expect(bridgePlugin.IPAM.Routes[1].Dest).To(Equal("0.0.0.0/0")) + Expect(bridgePlugin.IPAM.Ranges).To(HaveLen(2)) + Expect(bridgePlugin.IPAM.Ranges[0]).To(HaveLen(1)) + Expect(bridgePlugin.IPAM.Ranges[0][0].Subnet).ToNot(BeEmpty()) + Expect(bridgePlugin.IPAM.Ranges[1]).To(HaveLen(1)) + Expect(bridgePlugin.IPAM.Ranges[1][0].Subnet).ToNot(BeEmpty()) + + _, subnet11, err := net.ParseCIDR(bridgePlugin.IPAM.Ranges[0][0].Subnet) + Expect(err).To(BeNil()) + _, subnet12, err := net.ParseCIDR(bridgePlugin.IPAM.Ranges[1][0].Subnet) + Expect(err).To(BeNil()) + // Once a container executes a new network, the nic will be created. We should clean those up // best we can defer removeNetworkDevice(bridgePlugin.BrName) + // create a second network to check the auto assigned ipv4 subnet does not overlap + // https://github.com/containers/podman/issues/11032 + netName2 := "dual-" + stringid.GenerateNonCryptoID() + nc = podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:6:3:2:1::/64", "--ipv6", netName2}) + nc.WaitWithDefaultTimeout() + defer podmanTest.removeCNINetwork(netName2) + Expect(nc).Should(Exit(0)) + + // Inspect the network configuration + inspect = podmanTest.Podman([]string{"network", "inspect", netName2}) + inspect.WaitWithDefaultTimeout() + + // JSON the network configuration into something usable + err = json.Unmarshal([]byte(inspect.OutputToString()), &results) + Expect(err).To(BeNil()) + result = results[0] + Expect(result["name"]).To(Equal(netName2)) + + // JSON the bridge info + bridgePlugin, err = genericPluginsToBridge(result["plugins"], "bridge") + Expect(err).To(BeNil()) + Expect(bridgePlugin.IPAM.Routes[0].Dest).To(Equal("::/0")) + Expect(bridgePlugin.IPAM.Routes[1].Dest).To(Equal("0.0.0.0/0")) + Expect(bridgePlugin.IPAM.Ranges).To(HaveLen(2)) + Expect(bridgePlugin.IPAM.Ranges[0]).To(HaveLen(1)) + Expect(bridgePlugin.IPAM.Ranges[0][0].Subnet).ToNot(BeEmpty()) + Expect(bridgePlugin.IPAM.Ranges[1]).To(HaveLen(1)) + Expect(bridgePlugin.IPAM.Ranges[1][0].Subnet).ToNot(BeEmpty()) + + _, subnet21, err := net.ParseCIDR(bridgePlugin.IPAM.Ranges[0][0].Subnet) + Expect(err).To(BeNil()) + _, subnet22, err := net.ParseCIDR(bridgePlugin.IPAM.Ranges[1][0].Subnet) + Expect(err).To(BeNil()) + + // check that the subnets do not overlap + Expect(subnet11.Contains(subnet21.IP)).To(BeFalse()) + Expect(subnet12.Contains(subnet22.IP)).To(BeFalse()) + try := podmanTest.Podman([]string{"run", "-it", "--rm", "--network", netName, ALPINE, "sh", "-c", "ip addr show eth0 | grep global | awk ' /inet6 / {print $2}'"}) try.WaitWithDefaultTimeout() diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index 5e303bf2f..66bfdefe7 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -1729,7 +1729,7 @@ var _ = Describe("Podman play kube", func() { }) It("podman play kube with pull policy of missing", func() { - ctr := getCtr(withPullPolicy("missing"), withImage(BB)) + ctr := getCtr(withPullPolicy("Missing"), withImage(BB)) err := generateKubeYaml("pod", getPod(withCtr(ctr)), kubeYaml) Expect(err).To(BeNil()) diff --git a/test/e2e/prune_test.go b/test/e2e/prune_test.go index 68ccd0a94..ff70a8cf4 100644 --- a/test/e2e/prune_test.go +++ b/test/e2e/prune_test.go @@ -16,6 +16,11 @@ LABEL RUN podman --version RUN apk update RUN apk add bash`, ALPINE) +var emptyPruneImage = ` +FROM scratch +ENV test1=test1 +ENV test2=test2` + var _ = Describe("Podman prune", func() { var ( tempdir string @@ -110,8 +115,12 @@ var _ = Describe("Podman prune", func() { Expect(session).Should(Exit(0)) Expect(len(session.OutputToStringArray())).To(Equal(numImages)) - // Now build a new image with dangling intermediate images. + // Now build an image and untag it. The (intermediate) images + // should be removed recursively during pruning. podmanTest.BuildImage(pruneImage, "alpine_bash:latest", "true") + session = podmanTest.Podman([]string{"untag", "alpine_bash:latest"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) session = podmanTest.Podman([]string{"images", "-a"}) session.WaitWithDefaultTimeout() @@ -136,26 +145,33 @@ var _ = Describe("Podman prune", func() { Expect(len(session.OutputToStringArray())).To(Equal(numImages - numPrunedImages)) }) - It("podman image prune skip cache images", func() { - podmanTest.BuildImage(pruneImage, "alpine_bash:latest", "true") + It("podman image prune - handle empty images", func() { + // As shown in #10832, empty images were not treated correctly + // in Podman. + podmanTest.BuildImage(emptyPruneImage, "empty:scratch", "true") - none := podmanTest.Podman([]string{"images", "-a"}) - none.WaitWithDefaultTimeout() - Expect(none).Should(Exit(0)) - hasNone, _ := none.GrepString("<none>") + session := podmanTest.Podman([]string{"images", "-a"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + hasNone, _ := session.GrepString("<none>") Expect(hasNone).To(BeTrue()) - prune := podmanTest.Podman([]string{"image", "prune", "-f"}) - prune.WaitWithDefaultTimeout() - Expect(prune).Should(Exit(0)) + // Nothing will be pruned. + session = podmanTest.Podman([]string{"image", "prune", "-f"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(len(session.OutputToStringArray())).To(Equal(0)) - after := podmanTest.Podman([]string{"images", "-a"}) - after.WaitWithDefaultTimeout() - Expect(none).Should(Exit(0)) - // Check if all "dangling" images were pruned. - hasNoneAfter, _ := after.GrepString("<none>") - Expect(hasNoneAfter).To(BeFalse()) - Expect(len(after.OutputToStringArray()) > 1).To(BeTrue()) + // Now the image will be untagged, and its parent images will + // be removed recursively. + session = podmanTest.Podman([]string{"untag", "empty:scratch"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"image", "prune", "-f"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(len(session.OutputToStringArray())).To(Equal(2)) }) It("podman image prune dangling images", func() { diff --git a/test/e2e/pull_test.go b/test/e2e/pull_test.go index fd9656f4d..c377f158d 100644 --- a/test/e2e/pull_test.go +++ b/test/e2e/pull_test.go @@ -44,7 +44,7 @@ var _ = Describe("Podman pull", func() { session = podmanTest.Podman([]string{"pull", "busybox:latest", "docker.io/library/ibetthisdoesnotexistfr:random", "alpine"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(125)) - expectedError := "Error initializing source docker://ibetthisdoesnotexistfr:random" + expectedError := "initializing source docker://ibetthisdoesnotexistfr:random" found, _ := session.ErrorGrepString(expectedError) Expect(found).To(Equal(true)) diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 3bfd59b54..3c65c02d1 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -1213,14 +1213,14 @@ USER mail`, BB) }) It("podman run with bad healthcheck timeout", func() { - session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "[\"foo\"]", "--health-timeout", "0s", ALPINE, "top"}) + session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "foo", "--health-timeout", "0s", ALPINE, "top"}) session.WaitWithDefaultTimeout() Expect(session).To(ExitWithError()) Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-timeout must be at least 1 second")) }) It("podman run with bad healthcheck start-period", func() { - session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "[\"foo\"]", "--health-start-period", "-1s", ALPINE, "top"}) + session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "foo", "--health-start-period", "-1s", ALPINE, "top"}) session.WaitWithDefaultTimeout() Expect(session).To(ExitWithError()) Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-start-period must be 0 seconds or greater")) diff --git a/test/e2e/volume_prune_test.go b/test/e2e/volume_prune_test.go index 68a257110..364ca0ab7 100644 --- a/test/e2e/volume_prune_test.go +++ b/test/e2e/volume_prune_test.go @@ -63,6 +63,37 @@ var _ = Describe("Podman volume prune", func() { podmanTest.Cleanup() }) + It("podman prune volume --filter until", func() { + session := podmanTest.Podman([]string{"volume", "create", "--label", "label1=value1", "myvol1"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"volume", "ls"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(len(session.OutputToStringArray())).To(Equal(2)) + + session = podmanTest.Podman([]string{"volume", "prune", "--force", "--filter", "until=50"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"volume", "ls"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(len(session.OutputToStringArray())).To(Equal(2)) + + session = podmanTest.Podman([]string{"volume", "prune", "--force", "--filter", "until=5000000000"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"volume", "ls"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(len(session.OutputToStringArray())).To(Equal(0)) + + podmanTest.Cleanup() + }) + It("podman prune volume --filter", func() { session := podmanTest.Podman([]string{"volume", "create", "--label", "label1=value1", "myvol1"}) session.WaitWithDefaultTimeout() |