diff options
Diffstat (limited to 'test/e2e')
-rw-r--r-- | test/e2e/config.go | 1 | ||||
-rw-r--r-- | test/e2e/network_test.go | 37 | ||||
-rw-r--r-- | test/e2e/search_test.go | 20 | ||||
-rw-r--r-- | test/e2e/toolbox_test.go | 368 |
4 files changed, 426 insertions, 0 deletions
diff --git a/test/e2e/config.go b/test/e2e/config.go index 49a47c7da..54e39f9d2 100644 --- a/test/e2e/config.go +++ b/test/e2e/config.go @@ -14,6 +14,7 @@ var ( BB = "docker.io/library/busybox:latest" healthcheck = "docker.io/libpod/alpine_healthcheck:latest" ImageCacheDir = "/tmp/podman/imagecachedir" + fedoraToolbox = "registry.fedoraproject.org/f32/fedora-toolbox:latest" // This image has seccomp profiles that blocks all syscalls. // The intention behind blocking all syscalls is to prevent diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go index cbfd72da6..9bd16c008 100644 --- a/test/e2e/network_test.go +++ b/test/e2e/network_test.go @@ -211,6 +211,43 @@ var _ = Describe("Podman network", func() { Expect(rmAll.ExitCode()).To(BeZero()) }) + It("podman inspect container two CNI networks (container not running)", func() { + netName1 := "testNetThreeCNI1" + network1 := podmanTest.Podman([]string{"network", "create", netName1}) + network1.WaitWithDefaultTimeout() + Expect(network1.ExitCode()).To(BeZero()) + defer podmanTest.removeCNINetwork(netName1) + + netName2 := "testNetThreeCNI2" + network2 := podmanTest.Podman([]string{"network", "create", netName2}) + network2.WaitWithDefaultTimeout() + Expect(network2.ExitCode()).To(BeZero()) + defer podmanTest.removeCNINetwork(netName2) + + ctrName := "testCtr" + container := podmanTest.Podman([]string{"create", "--network", fmt.Sprintf("%s,%s", netName1, netName2), "--name", ctrName, ALPINE, "top"}) + container.WaitWithDefaultTimeout() + Expect(container.ExitCode()).To(BeZero()) + + inspect := podmanTest.Podman([]string{"inspect", ctrName}) + inspect.WaitWithDefaultTimeout() + Expect(inspect.ExitCode()).To(BeZero()) + conData := inspect.InspectContainerToJSON() + Expect(len(conData)).To(Equal(1)) + Expect(len(conData[0].NetworkSettings.Networks)).To(Equal(2)) + net1, ok := conData[0].NetworkSettings.Networks[netName1] + Expect(ok).To(BeTrue()) + Expect(net1.NetworkID).To(Equal(netName1)) + net2, ok := conData[0].NetworkSettings.Networks[netName2] + Expect(ok).To(BeTrue()) + Expect(net2.NetworkID).To(Equal(netName2)) + + // Necessary to ensure the CNI network is removed cleanly + rmAll := podmanTest.Podman([]string{"rm", "-f", ctrName}) + rmAll.WaitWithDefaultTimeout() + Expect(rmAll.ExitCode()).To(BeZero()) + }) + It("podman inspect container two CNI networks", func() { netName1 := "testNetTwoCNI1" network1 := podmanTest.Podman([]string{"network", "create", "--subnet", "10.50.51.0/25", netName1}) diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go index 043da9059..0cf005529 100644 --- a/test/e2e/search_test.go +++ b/test/e2e/search_test.go @@ -423,4 +423,24 @@ registries = ['{{.Host}}:{{.Port}}']` Expect(search.ExitCode()).To(Equal(0)) Expect(len(search.OutputToStringArray()) > 1).To(BeTrue()) }) + + It("podman search repository tags", func() { + search := podmanTest.Podman([]string{"search", "--list-tags", "--limit", "30", "docker.io/library/alpine"}) + search.WaitWithDefaultTimeout() + Expect(search.ExitCode()).To(Equal(0)) + Expect(len(search.OutputToStringArray())).To(Equal(31)) + + search = podmanTest.Podman([]string{"search", "--list-tags", "docker.io/library/alpine"}) + search.WaitWithDefaultTimeout() + Expect(search.ExitCode()).To(Equal(0)) + Expect(len(search.OutputToStringArray()) > 2).To(BeTrue()) + + search = podmanTest.Podman([]string{"search", "--filter=is-official", "--list-tags", "docker.io/library/alpine"}) + search.WaitWithDefaultTimeout() + Expect(search.ExitCode()).To(Not(Equal(0))) + + search = podmanTest.Podman([]string{"search", "--list-tags", "docker.io/library/"}) + search.WaitWithDefaultTimeout() + Expect(len(search.OutputToStringArray()) == 0).To(BeTrue()) + }) }) diff --git a/test/e2e/toolbox_test.go b/test/e2e/toolbox_test.go new file mode 100644 index 000000000..6122cee19 --- /dev/null +++ b/test/e2e/toolbox_test.go @@ -0,0 +1,368 @@ +package integration + +/* + toolbox_test.go is under the care of the Toolbox Team. + + The tests are trying to stress parts of Podman that Toolbox[0] needs for + its functionality. + + [0] https://github.com/containers/toolbox + + Info about test cases: + - some tests rely on a certain configuration of a container that is done by + executing several commands in the entry-point of a container. To make + sure the initialization had enough time to be executed, + WaitContainerReady() after the container is started. + + - in several places there's an invocation of 'podman logs' It is there mainly + to ease debugging when a test goes wrong (during the initialization of a + container) but sometimes it is also used in the test case itself. + + Maintainers (Toolbox Team): + - Ondřej Míchal <harrymichal@fedoraproject.org> + - Debarshi Ray <rishi@fedoraproject.org> + + Also available on Freenode IRC on #silverblue or #podman +*/ + +import ( + "fmt" + "os" + "os/exec" + "os/user" + "strconv" + "strings" + "syscall" + + . "github.com/containers/podman/v2/test/utils" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("Toolbox-specific testing", func() { + var ( + tempdir string + err error + podmanTest *PodmanTestIntegration + ) + + BeforeEach(func() { + tempdir, err = CreateTempDirInTempDir() + if err != nil { + os.Exit(1) + } + podmanTest = PodmanTestCreate(tempdir) + podmanTest.Setup() + podmanTest.SeedImages() + }) + + AfterEach(func() { + podmanTest.Cleanup() + f := CurrentGinkgoTestDescription() + processTestResult(f) + }) + + It("podman run --dns=none - allows self-management of /etc/resolv.conf", func() { + var session *PodmanSessionIntegration + + session = podmanTest.Podman([]string{"run", "--dns", "none", ALPINE, "sh", "-c", + "rm -f /etc/resolv.conf; touch -d '1970-01-01 00:02:03' /etc/resolv.conf; stat -c %s:%Y /etc/resolv.conf"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("0:123")) + }) + + It("podman run --no-hosts - allows self-management of /etc/hosts", func() { + var session *PodmanSessionIntegration + + session = podmanTest.Podman([]string{"run", "--no-hosts", ALPINE, "sh", "-c", + "rm -f /etc/hosts; touch -d '1970-01-01 00:02:03' /etc/hosts; stat -c %s:%Y /etc/hosts"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("0:123")) + }) + + It("podman create --ulimit host + podman exec - correctly mirrors hosts ulimits", func() { + if podmanTest.RemoteTest { + Skip("Ulimit check does not work with a remote client") + } + var session *PodmanSessionIntegration + var containerHardLimit int + var rlimit syscall.Rlimit + var err error + + err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlimit) + Expect(err).To(BeNil()) + fmt.Printf("Expected value: %d", rlimit.Max) + + session = podmanTest.Podman([]string{"create", "--name", "test", "--ulimit", "host", ALPINE, + "sleep", "1000"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"start", "test"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"exec", "test", "sh", "-c", + "ulimit -H -n"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + containerHardLimit, err = strconv.Atoi(strings.Trim(session.OutputToString(), "\n")) + Expect(err).To(BeNil()) + Expect(containerHardLimit).To(BeNumerically(">=", rlimit.Max)) + }) + + It("podman create --ipc=host --pid=host + podman exec - correct shared memory limit size", func() { + // Comparison of the size of /dev/shm on the host being equal to the one in + // a container + if podmanTest.RemoteTest { + Skip("Shm size check does not work with a remote client") + } + var session *PodmanSessionIntegration + var cmd *exec.Cmd + var hostShmSize, containerShmSize int + var err error + + // Because Alpine uses busybox, most commands don't offer advanced options + // like "--output" in df. Therefore the value of the field 'Size' (or + // ('1K-blocks') needs to be extracted manually. + cmd = exec.Command("df", "/dev/shm") + res, err := cmd.Output() + Expect(err).To(BeNil()) + lines := strings.SplitN(string(res), "\n", 2) + fields := strings.Fields(lines[len(lines)-1]) + hostShmSize, err = strconv.Atoi(fields[1]) + Expect(err).To(BeNil()) + + session = podmanTest.Podman([]string{"create", "--name", "test", "--ipc=host", "--pid=host", ALPINE, + "sleep", "1000"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"start", "test"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"exec", "test", + "df", "/dev/shm"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + lines = session.OutputToStringArray() + fields = strings.Fields(lines[len(lines)-1]) + containerShmSize, err = strconv.Atoi(fields[1]) + Expect(err).To(BeNil()) + + // In some cases it may happen that the size of /dev/shm is not exactly + // equal. Therefore it's fine if there's a slight tolerance between the + // compared values. + Expect(hostShmSize).To(BeNumerically("~", containerShmSize, 100)) + }) + + It("podman create --userns=keep-id --user root:root - entrypoint - entrypoint is executed as root", func() { + var session *PodmanSessionIntegration + + session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--user", "root:root", ALPINE, + "id"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("uid=0(root) gid=0(root)")) + }) + + It("podman create --userns=keep-id + podman exec - correct names of user and group", func() { + var session *PodmanSessionIntegration + var err error + + currentUser, err := user.Current() + Expect(err).To(BeNil()) + + currentGroup, err := user.LookupGroupId(currentUser.Gid) + Expect(err).To(BeNil()) + + session = podmanTest.Podman([]string{"create", "--name", "test", "--userns=keep-id", ALPINE, + "sleep", "1000"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(err).To(BeNil()) + + session = podmanTest.Podman([]string{"start", "test"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + expectedOutput := fmt.Sprintf("uid=%s(%s) gid=%s(%s)", + currentUser.Uid, currentUser.Username, + currentGroup.Gid, currentGroup.Name) + + session = podmanTest.Podman([]string{"exec", "test", + "id"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(expectedOutput)) + }) + + It("podman create --userns=keep-id - entrypoint - adding user with useradd and then removing their password", func() { + var session *PodmanSessionIntegration + + var username string = "testuser" + var homeDir string = "/home/testuser" + var shell string = "/bin/sh" + var uid string = "1001" + var gid string = "1001" + + useradd := fmt.Sprintf("useradd --home-dir %s --shell %s --uid %s %s", + homeDir, shell, uid, username) + passwd := fmt.Sprintf("passwd --delete %s", username) + + session = podmanTest.Podman([]string{"create", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", + fmt.Sprintf("%s; %s; echo READY; sleep 1000", useradd, passwd)}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"start", "test"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + Expect(WaitContainerReady(podmanTest, "test", "READY", 2, 1)).To(BeTrue()) + + expectedOutput := fmt.Sprintf("%s:x:%s:%s::%s:%s", + username, uid, gid, homeDir, shell) + + session = podmanTest.Podman([]string{"exec", "test", "cat", "/etc/passwd"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(expectedOutput)) + + expectedOutput = "passwd: Note: deleting a password also unlocks the password." + + session = podmanTest.Podman([]string{"logs", "test"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(expectedOutput)) + }) + + It("podman create --userns=keep-id + podman exec - adding group with groupadd", func() { + var session *PodmanSessionIntegration + + var groupName string = "testgroup" + var gid string = "1001" + + groupadd := fmt.Sprintf("groupadd --gid %s %s", gid, groupName) + + session = podmanTest.Podman([]string{"create", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", + fmt.Sprintf("%s; echo READY; sleep 1000", groupadd)}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"start", "test"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + Expect(WaitContainerReady(podmanTest, "test", "READY", 2, 1)).To(BeTrue()) + + session = podmanTest.Podman([]string{"exec", "test", "cat", "/etc/group"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(groupName)) + + session = podmanTest.Podman([]string{"logs", "test"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("READY")) + }) + + It("podman create --userns=keep-id - entrypoint - modifying existing user with usermod - add to new group, change home/shell/uid", func() { + var session *PodmanSessionIntegration + var badHomeDir string = "/home/badtestuser" + var badShell string = "/bin/sh" + var badUID string = "1001" + var username string = "testuser" + var homeDir string = "/home/testuser" + var shell string = "/bin/bash" + var uid string = "2000" + var groupName string = "testgroup" + var gid string = "2000" + + // The use of bad* in the name of variables does not imply the invocation + // of useradd should fail The user is supposed to be created successfuly + // but later his information (uid, home, shell,..) is changed via usermod. + useradd := fmt.Sprintf("useradd --home-dir %s --shell %s --uid %s %s", + badHomeDir, badShell, badUID, username) + groupadd := fmt.Sprintf("groupadd --gid %s %s", + gid, groupName) + usermod := fmt.Sprintf("usermod --append --groups wheel --home %s --shell %s --uid %s --gid %s %s", + homeDir, shell, uid, gid, username) + + session = podmanTest.Podman([]string{"create", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c", + fmt.Sprintf("%s; %s; %s; echo READY; sleep 1000", useradd, groupadd, usermod)}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"start", "test"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + Expect(WaitContainerReady(podmanTest, "test", "READY", 2, 1)).To(BeTrue()) + + expectedUser := fmt.Sprintf("%s:x:%s:%s::%s:%s", + username, uid, gid, homeDir, shell) + + session = podmanTest.Podman([]string{"exec", "test", "cat", "/etc/passwd"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring(expectedUser)) + + session = podmanTest.Podman([]string{"logs", "test"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("READY")) + }) + + It("podman run --privileged --userns=keep-id --user root:root - entrypoint - (bind)mounting", func() { + var session *PodmanSessionIntegration + + session = podmanTest.Podman([]string{"run", "--privileged", "--userns=keep-id", "--user", "root:root", ALPINE, + "mount", "-t", "tmpfs", "tmpfs", "/tmp"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"run", "--privileged", "--userns=keep-id", "--user", "root:root", ALPINE, + "mount", "--rbind", "/tmp", "/var/tmp"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + }) + + It("podman create + start - with all needed switches for create - sleep as entry-point", func() { + var session *PodmanSessionIntegration + + // These should be most of the switches that Toolbox uses to create a "toolbox" container + // https://github.com/containers/toolbox/blob/master/src/cmd/create.go + session = podmanTest.Podman([]string{"create", + "--dns", "none", + "--hostname", "toolbox", + "--ipc", "host", + "--label", "com.github.containers.toolbox=true", + "--name", "test", + "--network", "host", + "--no-hosts", + "--pid", "host", + "--privileged", + "--security-opt", "label=disable", + "--ulimit", "host", + "--userns=keep-id", + "--user", "root:root", + fedoraToolbox, "sh", "-c", "echo READY; sleep 1000"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"start", "test"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + Expect(WaitContainerReady(podmanTest, "test", "READY", 2, 1)).To(BeTrue()) + + session = podmanTest.Podman([]string{"logs", "test"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("READY")) + }) +}) |