diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/apiv2/01-basic.at | 2 | ||||
-rw-r--r-- | test/apiv2/python/rest_api/test_v2_0_0_container.py | 10 | ||||
-rwxr-xr-x | test/buildah-bud/apply-podman-deltas | 61 | ||||
-rw-r--r-- | test/buildah-bud/buildah-tests.diff | 93 | ||||
-rw-r--r-- | test/buildah-bud/make-new-buildah-diffs | 8 | ||||
-rwxr-xr-x | test/buildah-bud/run-buildah-bud-tests | 4 | ||||
-rw-r--r-- | test/e2e/healthcheck_run_test.go | 10 | ||||
-rw-r--r-- | test/e2e/image_scp_test.go | 104 | ||||
-rw-r--r-- | test/e2e/login_logout_test.go | 223 | ||||
-rw-r--r-- | test/e2e/ps_test.go | 37 | ||||
-rw-r--r-- | test/e2e/run_test.go | 4 | ||||
-rw-r--r-- | test/system/050-stop.bats | 31 | ||||
-rw-r--r-- | test/system/255-auto-update.bats | 3 | ||||
-rw-r--r-- | test/system/410-selinux.bats | 12 |
14 files changed, 559 insertions, 43 deletions
diff --git a/test/apiv2/01-basic.at b/test/apiv2/01-basic.at index 64aafa013..564c7bed5 100644 --- a/test/apiv2/01-basic.at +++ b/test/apiv2/01-basic.at @@ -18,7 +18,7 @@ t HEAD libpod/_ping 200 for i in /version version; do t GET $i 200 \ .Components[0].Name="Podman Engine" \ - .Components[0].Details.APIVersion~3[0-9.-]\\+ \ + .Components[0].Details.APIVersion~4[0-9.-]\\+ \ .Components[0].Details.MinAPIVersion=3.1.0 \ .Components[0].Details.Os=linux \ .ApiVersion=1.40 \ diff --git a/test/apiv2/python/rest_api/test_v2_0_0_container.py b/test/apiv2/python/rest_api/test_v2_0_0_container.py index f252bd401..30d902d8c 100644 --- a/test/apiv2/python/rest_api/test_v2_0_0_container.py +++ b/test/apiv2/python/rest_api/test_v2_0_0_container.py @@ -33,9 +33,10 @@ class ContainerTestCase(APITestCase): self.assertId(r.content) _ = parse(r.json()["Created"]) + r = requests.post( self.podman_url + "/v1.40/containers/create?name=topcontainer", - json={"Cmd": ["top"], "Image": "alpine:latest"}, + json={"Healthcheck": {"Test": ["CMD-SHELL", "exit 0"], "Interval":1000, "Timeout":1000, "Retries": 5}, "Cmd": ["top"], "Image": "alpine:latest"}, ) self.assertEqual(r.status_code, 201, r.text) payload = r.json() @@ -49,6 +50,13 @@ class ContainerTestCase(APITestCase): state = out["State"]["Health"] self.assertIsInstance(state, dict) + r = requests.get(self.uri(f"/containers/{payload['Id']}/json")) + self.assertEqual(r.status_code, 200, r.text) + self.assertId(r.content) + out = r.json() + hc = out["Config"]["Healthcheck"]["Test"] + self.assertListEqual(["CMD-SHELL", "exit 0"], hc) + def test_stats(self): r = requests.get(self.uri(self.resolve_container("/containers/{}/stats?stream=false"))) self.assertIn(r.status_code, (200, 409), r.text) diff --git a/test/buildah-bud/apply-podman-deltas b/test/buildah-bud/apply-podman-deltas index 41c84257f..18b3d56f9 100755 --- a/test/buildah-bud/apply-podman-deltas +++ b/test/buildah-bud/apply-podman-deltas @@ -56,22 +56,31 @@ function errmsg() { done } -# skip: used to add a 'skip' to one specific test -function skip() { +# _skip: used to add a 'skip' or 'skip_if_remote' to one specific test +function _skip() { + local skip=$1; shift local reason=$1; shift # All further arguments are test names for t in "$@"; do if fgrep -qx "@test \"$t\" {" $BUD; then - $ECHO "@test \"$t\" : skip \"$reason\"" + $ECHO "@test \"$t\" : $skip \"$reason\"" t=${t//\//\\/} - sed -i -e "/^\@test \"$t\" {/ a \ \ skip \"$reason\"" $BUD + sed -i -e "/^\@test \"$t\" {/ a \ \ $skip \"$reason\"" $BUD else - warn "[skip] Did not find test \"$t\" in $BUD" + warn "[$skip] Did not find test \"$t\" in $BUD" fi done } +function skip() { + _skip "skip" "$@" +} + +function skip_if_remote() { + _skip "skip_if_remote" "$@" +} + # END handlers ############################################################################### # BEGIN user-customizable section @@ -79,14 +88,14 @@ function skip() { # These are the hand-maintained exceptions. This is what you want to edit # or update as needed. # -# There are two directives you can use below: +# There are three directives you can use below: # # errmsg "old-message" "new-message" "test name" ["test name"...] # # This replaced "old-message" with "new-message" in @test "test name". # It is used when a podman error message differs from buildah's. # -# skip "reason" "test name" ["test name"...] +# [skip | skip_if_remote] "reason" "test name" ["test name"...] # # This adds a 'skip' statement as the first line of @test "test name". # It is used when a test does not work in podman, either for permanent @@ -126,6 +135,7 @@ errmsg "no such file or directory" \ ############################################################################### # BEGIN tests that don't make sense under podman due to fundamental differences + skip "N/A under podman" \ "bud-flags-order-verification" @@ -147,13 +157,13 @@ skip "Too much effort to spin up a local registry" \ skip "FIXME FIXME FIXME: argument-order incompatible with podman" \ "bud-squash-hardlinks" -skip "FIXME FIXME FIXME we'll figure these out later" \ - "bud-multi-stage-nocache-nocommit" \ - "bud with --cgroup-parent" +skip "FIXME FIXME FIXME: this passes on Ed's laptop, fails in CI??" \ + "bud-multi-stage-nocache-nocommit" -# see https://github.com/containers/podman/pull/10147#issuecomment-832503633 -skip "FIXME FIXME FIXME podman save/load has been fixed (but not yet used in Buildah CI)" \ - "bud with --layers and --no-cache flags" +# This will probably never work: buildah and podman have incompatible defaults +# Documented in https://github.com/containers/podman/issues/10412 +skip "buildah runs with --cgroup-manager=cgroupfs, podman with systemd" \ + "bud with --cgroup-parent" # see https://github.com/containers/podman/pull/10829 skip "FIXME FIXME FIXME - requires updated CI images (#10829)" \ @@ -164,6 +174,31 @@ skip "FIXME FIXME FIXME - requires updated CI images (#10829)" \ ############################################################################### +# BEGIN tests which are skipped because they make no sense under podman-remote + +skip_if_remote "--target does not work with podman-remote" \ + "bud-target" + +skip_if_remote "--runtime not meaningful under podman-remote" \ + "bud with --runtime and --runtime-flag" + +skip_if_remote "secret files not implemented under podman-remote" \ + "bud with containerfile secret" \ + "bud with containerfile secret accessed on second RUN" \ + "bud with containerfile secret options" + +skip_if_remote "volumes don't work with podman-remote" \ + "buildah bud --volume" \ + "buildah-bud-policy" + +# See podman #9890 for discussion +skip_if_remote "--stdin option will not be implemented in podman-remote" \ + "bud test no --stdin" + +############################################################################### +# BEGIN tests which are skipped due to actual podman-remote bugs. + +############################################################################### # Done. exit $RC diff --git a/test/buildah-bud/buildah-tests.diff b/test/buildah-bud/buildah-tests.diff index 1c8592f7f..66d470648 100644 --- a/test/buildah-bud/buildah-tests.diff +++ b/test/buildah-bud/buildah-tests.diff @@ -1,23 +1,75 @@ -From a00508656599b24776982996fdb44d4874338fd4 Mon Sep 17 00:00:00 2001 +From d684753d6f00ee95720d8fb2e09c7ac19b37b01e Mon Sep 17 00:00:00 2001 From: Ed Santiago <santiago@redhat.com> Date: Tue, 9 Feb 2021 17:28:05 -0700 Subject: [PATCH] tweaks for running buildah tests under podman Signed-off-by: Ed Santiago <santiago@redhat.com> --- - tests/helpers.bash | 28 +++++++++++++++++++++++++--- - 1 file changed, 25 insertions(+), 3 deletions(-) + tests/helpers.bash | 71 +++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/tests/helpers.bash b/tests/helpers.bash -index 11deb367..08e73954 100644 +index 11deb367..44c71dad 100644 --- a/tests/helpers.bash +++ b/tests/helpers.bash -@@ -164,15 +164,37 @@ function run_buildah() { +@@ -34,6 +34,23 @@ function setup() { + ROOTDIR_OPTS="--root ${TESTDIR}/root --runroot ${TESTDIR}/runroot --storage-driver ${STORAGE_DRIVER}" + BUILDAH_REGISTRY_OPTS="--registries-conf ${TESTSDIR}/registries.conf --registries-conf-dir ${TESTDIR}/registries.d --short-name-alias-conf ${TESTDIR}/cache/shortnames.conf" + PODMAN_REGISTRY_OPTS="--registries-conf ${TESTSDIR}/registries.conf" ++ ++ PODMAN_SERVER_PID= ++ PODMAN_NATIVE="${PODMAN_BINARY} ${ROOTDIR_OPTS} ${PODMAN_REGISTRY_OPTS}" ++ if [[ -n "$REMOTE" ]]; then ++ PODMAN_NATIVE="${PODMAN_BINARY%%-remote} ${ROOTDIR_OPTS} ${PODMAN_REGISTRY_OPTS}" ++ # static CONTAINERS_CONF needed for capabilities test. As of 2021-07-01 ++ # no tests in bud.bats override this; if at some point any test does ++ # so, it will probably need to be skip_if_remote()d. ++ env CONTAINERS_CONF=${CONTAINERS_CONF:-$(dirname ${BASH_SOURCE})/containers.conf} $PODMAN_NATIVE system service --timeout=0 & ++ PODMAN_SERVER_PID=$! ++ local timeout=10 ++ while ((timeout > 0)); do ++ test -S /run/podman/podman.sock && return ++ sleep 0.2 ++ done ++ die "podman server never came up" ++ fi + } + + function starthttpd() { +@@ -57,6 +74,12 @@ function stophttpd() { + function teardown() { + stophttpd + ++ if [[ -n "$PODMAN_SERVER_PID" ]]; then ++ kill $PODMAN_SERVER_PID ++ wait $PODMAN_SERVER_PID ++ rm -f /run/podman/podman.sock ++ fi ++ + # Workaround for #1991 - buildah + overlayfs leaks mount points. + # Many tests leave behind /var/tmp/.../root/overlay and sub-mounts; + # let's find those and clean them up, otherwise 'rm -rf' fails. +@@ -129,7 +152,13 @@ function copy() { + } + + function podman() { +- command podman ${PODMAN_REGISTRY_OPTS} ${ROOTDIR_OPTS} "$@" ++ echo "# ... podman $*" >&3 ++ ${PODMAN_BINARY} ${PODMAN_REGISTRY_OPTS} ${ROOTDIR_OPTS} "$@" ++} ++ ++function podman-remote() { ++ echo "# ... podman-remote $*" >&3 ++ ${PODMAN_BINARY} ${ROOTDIR_OPTS} "$@" + } + + ################# +@@ -164,15 +193,40 @@ function run_buildah() { --retry) retry=3; shift;; # retry network flakes esac - + + local podman_or_buildah=${BUILDAH_BINARY} -+ local registry_opts=${BUILDAH_REGISTRY_OPTS} ++ local _opts="${ROOTDIR_OPTS} ${BUILDAH_REGISTRY_OPTS}" + if [[ $1 == "bud" || $1 == "build-using-dockerfile" ]]; then + shift + # podman defaults to --layers=true; buildah to --false. @@ -29,7 +81,10 @@ index 11deb367..08e73954 100644 + set "build" "--force-rm=false" "--layers=false" "$@" + fi + podman_or_buildah=${PODMAN_BINARY} -+ registry_opts=${PODMAN_REGISTRY_OPTS} ++ _opts="${ROOTDIR_OPTS} ${PODMAN_REGISTRY_OPTS}" ++ if [[ -n "$REMOTE" ]]; then ++ _opts= ++ fi + + # podman always exits 125 where buildah exits 1 or 2 + case $expected_rc in @@ -41,17 +96,31 @@ index 11deb367..08e73954 100644 # Remember command args, for possible use in later diagnostic messages - MOST_RECENT_BUILDAH_COMMAND="buildah $*" + MOST_RECENT_BUILDAH_COMMAND="$cmd_basename $*" - + while [ $retry -gt 0 ]; do retry=$(( retry - 1 )) - + # stdout is only emitted upon error; this echo is to help a debugger - echo "\$ $BUILDAH_BINARY $*" - run env CONTAINERS_CONF=${CONTAINERS_CONF:-$(dirname ${BASH_SOURCE})/containers.conf} timeout --foreground --kill=10 $BUILDAH_TIMEOUT ${BUILDAH_BINARY} ${BUILDAH_REGISTRY_OPTS} ${ROOTDIR_OPTS} "$@" + echo "\$ $cmd_basename $*" -+ run env CONTAINERS_CONF=${CONTAINERS_CONF:-$(dirname ${BASH_SOURCE})/containers.conf} timeout --foreground --kill=10 $BUILDAH_TIMEOUT ${podman_or_buildah} ${registry_opts} ${ROOTDIR_OPTS} "$@" ++ run env CONTAINERS_CONF=${CONTAINERS_CONF:-$(dirname ${BASH_SOURCE})/containers.conf} timeout --foreground --kill=10 $BUILDAH_TIMEOUT ${podman_or_buildah} ${_opts} "$@" # without "quotes", multiple lines are glommed together into one if [ -n "$output" ]; then echo "$output" --- +@@ -396,3 +450,12 @@ function skip_if_no_docker() { + skip "this test needs actual docker, not podman-docker" + fi + } ++ ++#################### ++# skip_if_remote # (only applicable for podman) ++#################### ++function skip_if_remote() { ++ if [[ -n "$REMOTE" ]]; then ++ skip "${1:-test does not work with podman-remote}" ++ fi ++} +-- 2.31.1 + diff --git a/test/buildah-bud/make-new-buildah-diffs b/test/buildah-bud/make-new-buildah-diffs index 11987e376..3d0a77008 100644 --- a/test/buildah-bud/make-new-buildah-diffs +++ b/test/buildah-bud/make-new-buildah-diffs @@ -56,8 +56,6 @@ if [[ -n "$patch2" ]]; then die "Internal error: I thought I checked for squashed commits, but still see $patch2" fi -# All looks good. Now write that patch into its proper place in the -# podman repo. The sed and tac mess strips trailing whitespace and -# empty lines; we need to do this to pass github CI checks. -sed -e 's/ \+$//' <0001-*.patch |\ - tac | sed -e '/./,$!d' | tac >| ../test/buildah-bud/buildah-tests.diff +# All looks good. We can now copy that patch into its proper place in the +# podman repo. +cp 0001-*.patch ../test/buildah-bud/buildah-tests.diff diff --git a/test/buildah-bud/run-buildah-bud-tests b/test/buildah-bud/run-buildah-bud-tests index a37e90dc4..eb8de5618 100755 --- a/test/buildah-bud/run-buildah-bud-tests +++ b/test/buildah-bud/run-buildah-bud-tests @@ -69,8 +69,7 @@ REMOTE= # If remote, start server & change path if [[ "${PODBIN_NAME:-}" = "remote" ]]; then REMOTE=1 - echo "$ME: remote tests are not working yet" >&2 - exit 1 + PODMAN_BINARY+="-remote" fi function die() { @@ -214,6 +213,7 @@ review the test failure and double-check your changes. (set -x;sudo env TMPDIR=/var/tmp \ PODMAN_BINARY=$PODMAN_BINARY \ + REMOTE=$REMOTE \ BUILDAH_BINARY=$(pwd)/bin/buildah \ COPY_BINARY=$(pwd)/bin/copy \ bats "${bats_filter[@]}" tests/bud.bats) diff --git a/test/e2e/healthcheck_run_test.go b/test/e2e/healthcheck_run_test.go index 28040ecfd..899c84a14 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).Should(Exit(0)) + + hc := podmanTest.Podman([]string{"healthcheck", "run", "hc"}) + hc.WaitWithDefaultTimeout() + Expect(hc).Should(Exit(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/image_scp_test.go b/test/e2e/image_scp_test.go new file mode 100644 index 000000000..9fd8d7e27 --- /dev/null +++ b/test/e2e/image_scp_test.go @@ -0,0 +1,104 @@ +package integration + +import ( + "io/ioutil" + "os" + + "github.com/containers/common/pkg/config" + . "github.com/containers/podman/v3/test/utils" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" +) + +var _ = Describe("podman image scp", func() { + ConfPath := struct { + Value string + IsSet bool + }{} + var ( + tempdir string + podmanTest *PodmanTestIntegration + ) + + BeforeEach(func() { + ConfPath.Value, ConfPath.IsSet = os.LookupEnv("CONTAINERS_CONF") + conf, err := ioutil.TempFile("", "containersconf") + if err != nil { + panic(err) + } + os.Setenv("CONTAINERS_CONF", conf.Name()) + tempdir, err = CreateTempDirInTempDir() + if err != nil { + os.Exit(1) + } + podmanTest = PodmanTestCreate(tempdir) + podmanTest.Setup() + }) + + AfterEach(func() { + podmanTest.Cleanup() + os.Remove(os.Getenv("CONTAINERS_CONF")) + if ConfPath.IsSet { + os.Setenv("CONTAINERS_CONF", ConfPath.Value) + } else { + os.Unsetenv("CONTAINERS_CONF") + } + f := CurrentGinkgoTestDescription() + processTestResult(f) + + }) + + It("podman image scp quiet flag", func() { + if IsRemote() { + Skip("this test is only for non-remote") + } + scp := podmanTest.Podman([]string{"image", "scp", "-q", ALPINE}) + scp.WaitWithDefaultTimeout() + Expect(scp).To(Exit(0)) + }) + + It("podman image scp bogus image", func() { + if IsRemote() { + Skip("this test is only for non-remote") + } + scp := podmanTest.Podman([]string{"image", "scp", "FOOBAR"}) + scp.WaitWithDefaultTimeout() + Expect(scp).To(ExitWithError()) + }) + + It("podman image scp with proper connection", func() { + if IsRemote() { + Skip("this test is only for non-remote") + } + cmd := []string{"system", "connection", "add", + "--default", + "QA", + "ssh://root@server.fubar.com:2222/run/podman/podman.sock", + } + session := podmanTest.Podman(cmd) + session.WaitWithDefaultTimeout() + Expect(session).To(Exit(0)) + + cfg, err := config.ReadCustomConfig() + Expect(err).ShouldNot(HaveOccurred()) + Expect(cfg.Engine.ActiveService).To(Equal("QA")) + Expect(cfg.Engine.ServiceDestinations["QA"]).To(Equal( + config.Destination{ + URI: "ssh://root@server.fubar.com:2222/run/podman/podman.sock", + }, + )) + + scp := podmanTest.Podman([]string{"image", "scp", ALPINE, "QA::"}) + scp.Wait(45) + // exit with error because we cannot make an actual ssh connection + // This tests that the input we are given is validated and prepared correctly + // Error: failed to connect: dial tcp: address foo: missing port in address + Expect(scp).To(ExitWithError()) + Expect(scp.ErrorToString()).To(ContainSubstring( + "Error: failed to connect: dial tcp 66.151.147.142:2222: i/o timeout", + )) + + }) + +}) diff --git a/test/e2e/login_logout_test.go b/test/e2e/login_logout_test.go index 6088d991f..7ad1fc1f2 100644 --- a/test/e2e/login_logout_test.go +++ b/test/e2e/login_logout_test.go @@ -97,6 +97,24 @@ var _ = Describe("Podman login and logout", func() { os.RemoveAll(certDirPath) }) + readAuthInfo := func(filePath string) map[string]interface{} { + authBytes, err := ioutil.ReadFile(filePath) + Expect(err).To(BeNil()) + + var authInfo map[string]interface{} + err = json.Unmarshal(authBytes, &authInfo) + Expect(err).To(BeNil()) + fmt.Println(authInfo) + + const authsKey = "auths" + Expect(authInfo).To(HaveKey(authsKey)) + + auths, ok := authInfo[authsKey].(map[string]interface{}) + Expect(ok).To(BeTrue()) + + return auths + } + It("podman login and logout", func() { session := podmanTest.Podman([]string{"login", "-u", "podmantest", "-p", "test", server}) session.WaitWithDefaultTimeout() @@ -151,10 +169,7 @@ var _ = Describe("Podman login and logout", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - authInfo, _ := ioutil.ReadFile(authFile) - var info map[string]interface{} - json.Unmarshal(authInfo, &info) - fmt.Println(info) + readAuthInfo(authFile) // push should fail with nonexistent authfile session = podmanTest.Podman([]string{"push", "--authfile", "/tmp/nonexistent", ALPINE, testImg}) @@ -284,4 +299,204 @@ var _ = Describe("Podman login and logout", func() { session.WaitWithDefaultTimeout() Expect(session).To(ExitWithError()) }) + + It("podman login and logout with repository", func() { + authFile := filepath.Join(podmanTest.TempDir, "auth.json") + + testRepository := server + "/podmantest" + session := podmanTest.Podman([]string{ + "login", + "-u", "podmantest", + "-p", "test", + "--authfile", authFile, + testRepository, + }) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + authInfo := readAuthInfo(authFile) + Expect(authInfo).To(HaveKey(testRepository)) + + session = podmanTest.Podman([]string{ + "logout", + "--authfile", authFile, + testRepository, + }) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + authInfo = readAuthInfo(authFile) + Expect(authInfo).NotTo(HaveKey(testRepository)) + }) + + It("podman login and logout with repository and specified image", func() { + authFile := filepath.Join(podmanTest.TempDir, "auth.json") + + testTarget := server + "/podmantest/test-alpine" + session := podmanTest.Podman([]string{ + "login", + "-u", "podmantest", + "-p", "test", + "--authfile", authFile, + testTarget, + }) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + authInfo := readAuthInfo(authFile) + Expect(authInfo).To(HaveKey(testTarget)) + + session = podmanTest.Podman([]string{ + "push", + "--authfile", authFile, + ALPINE, testTarget, + }) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + }) + + It("podman login and logout with repository with fallback", func() { + authFile := filepath.Join(podmanTest.TempDir, "auth.json") + + testRepos := []string{ + server + "/podmantest", + server, + } + for _, testRepo := range testRepos { + session := podmanTest.Podman([]string{ + "login", + "-u", "podmantest", + "-p", "test", + "--authfile", authFile, + testRepo, + }) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + } + + authInfo := readAuthInfo(authFile) + Expect(authInfo).To(HaveKey(testRepos[0])) + Expect(authInfo).To(HaveKey(testRepos[1])) + + session := podmanTest.Podman([]string{ + "push", + "--authfile", authFile, + ALPINE, testRepos[0] + "/test-image-alpine", + }) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{ + "logout", + "--authfile", authFile, + testRepos[0], + }) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{ + "push", + "--authfile", authFile, + ALPINE, testRepos[0] + "/test-image-alpine", + }) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{ + "logout", + "--authfile", authFile, + testRepos[1], + }) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + authInfo = readAuthInfo(authFile) + Expect(authInfo).NotTo(HaveKey(testRepos[0])) + Expect(authInfo).NotTo(HaveKey(testRepos[1])) + }) + + It("podman login with repository invalid arguments", func() { + authFile := filepath.Join(podmanTest.TempDir, "auth.json") + + for _, invalidArg := range []string{ + "https://" + server + "/podmantest", + server + "/podmantest/image:latest", + } { + session := podmanTest.Podman([]string{ + "login", + "-u", "podmantest", + "-p", "test", + "--authfile", authFile, + invalidArg, + }) + session.WaitWithDefaultTimeout() + Expect(session).Should(ExitWithError()) + } + }) + + It("podman login and logout with repository push with invalid auth.json credentials", func() { + authFile := filepath.Join(podmanTest.TempDir, "auth.json") + // only `server` contains the correct login data + err := ioutil.WriteFile(authFile, []byte(fmt.Sprintf(`{"auths": { + "%s/podmantest": { "auth": "cG9kbWFudGVzdDp3cm9uZw==" }, + "%s": { "auth": "cG9kbWFudGVzdDp0ZXN0" } + }}`, server, server)), 0644) + Expect(err).To(BeNil()) + + session := podmanTest.Podman([]string{ + "push", + "--authfile", authFile, + ALPINE, server + "/podmantest/test-image", + }) + session.WaitWithDefaultTimeout() + Expect(session).To(ExitWithError()) + + session = podmanTest.Podman([]string{ + "push", + "--authfile", authFile, + ALPINE, server + "/test-image", + }) + session.WaitWithDefaultTimeout() + Expect(session).To(Exit(0)) + }) + + It("podman login and logout with repository pull with wrong auth.json credentials", func() { + authFile := filepath.Join(podmanTest.TempDir, "auth.json") + + testTarget := server + "/podmantest/test-alpine" + session := podmanTest.Podman([]string{ + "login", + "-u", "podmantest", + "-p", "test", + "--authfile", authFile, + testTarget, + }) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{ + "push", + "--authfile", authFile, + ALPINE, testTarget, + }) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + // only `server + /podmantest` and `server` have the correct login data + err := ioutil.WriteFile(authFile, []byte(fmt.Sprintf(`{"auths": { + "%s/podmantest/test-alpine": { "auth": "cG9kbWFudGVzdDp3cm9uZw==" }, + "%s/podmantest": { "auth": "cG9kbWFudGVzdDp0ZXN0" }, + "%s": { "auth": "cG9kbWFudGVzdDp0ZXN0" } + }}`, server, server, server)), 0644) + Expect(err).To(BeNil()) + + session = podmanTest.Podman([]string{ + "pull", + "--authfile", authFile, + server + "/podmantest/test-alpine", + }) + session.WaitWithDefaultTimeout() + Expect(session).To(ExitWithError()) + }) }) diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go index e27ff27a4..aeb88e481 100644 --- a/test/e2e/ps_test.go +++ b/test/e2e/ps_test.go @@ -172,6 +172,43 @@ var _ = Describe("Podman ps", func() { Expect(fullCid).To(Equal(result.OutputToStringArray()[0])) }) + It("podman ps --filter network=container:<name>", func() { + ctrAlpha := "alpha" + container := podmanTest.Podman([]string{"run", "-dt", "--name", ctrAlpha, ALPINE, "top"}) + container.WaitWithDefaultTimeout() + Expect(container).Should(Exit(0)) + + ctrBravo := "bravo" + containerBravo := podmanTest.Podman([]string{"run", "-dt", "--network", "container:alpha", "--name", ctrBravo, ALPINE, "top"}) + containerBravo.WaitWithDefaultTimeout() + Expect(containerBravo).Should(Exit(0)) + + result := podmanTest.Podman([]string{"ps", "-a", "--format", "table {{.Names}}", "--filter", "network=container:alpha"}) + result.WaitWithDefaultTimeout() + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + Expect(result.OutputToString()).To(ContainSubstring("bravo")) + }) + + It("podman ps --filter network=container:<id>", func() { + ctrAlpha := "first" + container := podmanTest.Podman([]string{"run", "-dt", "--name", ctrAlpha, ALPINE, "top"}) + container.WaitWithDefaultTimeout() + cid := container.OutputToString() + Expect(container).Should(Exit(0)) + + ctrBravo := "second" + containerBravo := podmanTest.Podman([]string{"run", "-dt", "--network", "container:" + cid, "--name", ctrBravo, ALPINE, "top"}) + containerBravo.WaitWithDefaultTimeout() + Expect(containerBravo).Should(Exit(0)) + + result := podmanTest.Podman([]string{"ps", "-a", "--format", "table {{.Names}}", "--filter", "network=container:" + cid}) + result.WaitWithDefaultTimeout() + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + Expect(result.OutputToString()).To(ContainSubstring("second")) + }) + It("podman ps namespace flag", func() { _, ec, _ := podmanTest.RunLsContainer("") Expect(ec).To(Equal(0)) 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/system/050-stop.bats b/test/system/050-stop.bats index 2ed791429..d809507a5 100644 --- a/test/system/050-stop.bats +++ b/test/system/050-stop.bats @@ -119,11 +119,31 @@ load helpers # the container's status. run_podman run --name stopme -d $IMAGE sh -c \ - "trap 'echo Received SIGTERM, ignoring' SIGTERM; echo READY; while :; do sleep 1; done" + "trap 'echo Received SIGTERM, ignoring' SIGTERM; echo READY; while :; do sleep 0.2; done" - # Stop the container in the background + wait_for_ready stopme + + local t0=$SECONDS + # Stop the container, but do so in the background so we can inspect + # the container status while it's stopping. Use $PODMAN because we + # don't want the overhead and error checks of run_podman. $PODMAN stop -t 20 stopme & + # Wait for container to acknowledge the signal. We can't use wait_for_output + # because that aborts if .State.Running != true + local timeout=5 + while [[ $timeout -gt 0 ]]; do + run_podman logs stopme + if [[ "$output" =~ "Received SIGTERM, ignoring" ]]; then + break + fi + timeout=$((timeout - 1)) + if [[ $timeout -eq 0 ]]; then + die "Timed out waiting for container to receive SIGERM" + fi + sleep 0.5 + done + # Other commands can acquire the lock run_podman ps -a @@ -131,6 +151,13 @@ load helpers run_podman inspect --format '{{.State.Status}}' stopme is "$output" "stopping" "Status of container should be 'stopping'" + # Time check: make sure we were able to run 'ps' before the container + # exited. If this takes too long, it means ps had to wait for lock. + local delta_t=$(( $SECONDS - t0 )) + if [[ $delta_t -gt 5 ]]; then + die "Operations took too long ($delta_t seconds)" + fi + run_podman kill stopme run_podman wait stopme diff --git a/test/system/255-auto-update.bats b/test/system/255-auto-update.bats index 25eaba45b..6fb40f41e 100644 --- a/test/system/255-auto-update.bats +++ b/test/system/255-auto-update.bats @@ -261,7 +261,8 @@ EOF systemctl enable --now podman-auto-update-$cname.timer systemctl list-timers --all - local expect='Finished Podman auto-update testing service' + # While systemd v245 and later uses 'Finished', older versions uses 'Started' for oneshot services + local expect='(Finished|Started) Podman auto-update testing service' local failed_start=failed local count=0 while [ $count -lt 120 ]; do diff --git a/test/system/410-selinux.bats b/test/system/410-selinux.bats index 4ef9c8b30..5ee0e0715 100644 --- a/test/system/410-selinux.bats +++ b/test/system/410-selinux.bats @@ -50,6 +50,18 @@ function check_label() { check_label "--systemd=always" "container_init_t" } +@test "podman selinux: init container with --security-opt type" { + check_label "--systemd=always --security-opt=label=type:spc_t" "spc_t" +} + +@test "podman selinux: init container with --security-opt level&type" { + check_label "--systemd=always --security-opt=label=level:s0:c1,c2 --security-opt=label=type:spc_t" "spc_t" "s0:c1,c2" +} + +@test "podman selinux: init container with --security-opt level" { + check_label "--systemd=always --security-opt=label=level:s0:c1,c2" "container_init_t" "s0:c1,c2" +} + @test "podman selinux: pid=host" { # FIXME this test fails when run rootless with runc: # Error: container_linux.go:367: starting container process caused: process_linux.go:495: container init caused: readonly path /proc/asound: operation not permitted: OCI permission denied |