diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/apiv2/10-images.at | 12 | ||||
-rwxr-xr-x | test/buildah-bud/apply-podman-deltas | 16 | ||||
-rw-r--r-- | test/e2e/build_test.go | 26 | ||||
-rw-r--r-- | test/e2e/checkpoint_test.go | 4 | ||||
-rw-r--r-- | test/e2e/kill_test.go | 20 | ||||
-rw-r--r-- | test/e2e/logs_test.go | 12 | ||||
-rw-r--r-- | test/e2e/network_connect_disconnect_test.go | 10 | ||||
-rw-r--r-- | test/e2e/run_networking_test.go | 2 | ||||
-rw-r--r-- | test/e2e/search_test.go | 1 | ||||
-rw-r--r-- | test/e2e/volume_create_test.go | 17 | ||||
-rw-r--r-- | test/system/015-help.bats | 58 | ||||
-rw-r--r-- | test/system/030-run.bats | 11 | ||||
-rw-r--r-- | test/system/060-mount.bats | 8 | ||||
-rw-r--r-- | test/system/160-volumes.bats | 39 | ||||
-rw-r--r-- | test/system/170-run-userns.bats | 4 | ||||
-rw-r--r-- | test/system/200-pod.bats | 21 | ||||
-rw-r--r-- | test/system/250-systemd.bats | 6 | ||||
-rw-r--r-- | test/system/600-completion.bats | 92 |
18 files changed, 291 insertions, 68 deletions
diff --git a/test/apiv2/10-images.at b/test/apiv2/10-images.at index fd04e3f1b..13aaea317 100644 --- a/test/apiv2/10-images.at +++ b/test/apiv2/10-images.at @@ -225,6 +225,18 @@ t POST "images/load" ${TMPD}/test.tar 200 \ t GET libpod/images/quay.io/libpod/alpine:latest/exists 204 t GET libpod/images/quay.io/libpod/busybox:latest/exists 204 +CONTAINERFILE_WITH_ERR_TAR="${TMPD}/containerfile.tar" +cat > $TMPD/containerfile << EOF +FROM quay.io/fedora/fedora +RUN echo 'some error' >&2 +EOF +tar --format=posix -C $TMPD -cvf ${CONTAINERFILE_WITH_ERR_TAR} containerfile &> /dev/null +t POST "build?q=1&dockerfile=containerfile" $CONTAINERFILE_WITH_ERR_TAR 200 +response_output=$(cat "$WORKDIR/curl.result.out") +if [[ ${response_output} == *"some error"* ]];then + _show_ok 0 "compat quiet build" "~ $response_output" "found output from stderr in API" +fi + cleanBuildTest # vim: filetype=sh diff --git a/test/buildah-bud/apply-podman-deltas b/test/buildah-bud/apply-podman-deltas index 1ca171c4a..e2ca45728 100755 --- a/test/buildah-bud/apply-podman-deltas +++ b/test/buildah-bud/apply-podman-deltas @@ -193,6 +193,22 @@ skip_if_remote "volumes don't work with podman-remote" \ "buildah bud --volume" \ "buildah-bud-policy" +# Most of this should work in podman remote after API implementation other than where context is host. +skip_if_remote "--build-context option not implemented in podman-remote" \ + "build-with-additional-build-context and COPY, test pinning image" \ + "build-with-additional-build-context and COPY, stagename and additional-context conflict" \ + "build-with-additional-build-context and COPY, additionalContext and numeric value of stage" \ + "build-with-additional-build-context and COPY, additionalContext and numeric value of stage" \ + "build-with-additional-build-context and COPY, additional context from host" \ + "build-with-additional-build-context and COPY, additional context from external URL" \ + "build-with-additional-build-context and RUN --mount=from=, additional-context is URL and mounted from subdir" \ + "build-with-additional-build-context and RUN --mount=from=, additional-context not image and also test conflict with stagename" \ + "build-with-additional-build-context and RUN --mount=from=, additional-context and also test conflict with stagename" \ + "bud-multiple-platform for --all-platform with additional-build-context" \ + "build-with-additional-build-context and FROM, stagename and additional-context conflict" \ + "bud with Containerfile.in, via envariable" \ + "build-with-additional-build-context and FROM, pin busybox to alpine" + # Requires a local file outside context dir skip_if_remote "local keyfile not sent to podman-remote" \ "bud with encrypted FROM image" diff --git a/test/e2e/build_test.go b/test/e2e/build_test.go index dcdd17143..86dc76116 100644 --- a/test/e2e/build_test.go +++ b/test/e2e/build_test.go @@ -178,6 +178,32 @@ var _ = Describe("Podman build", func() { Expect(session).Should(Exit(0)) }) + It("podman build verify explicit cache use with squash-all and --layers", func() { + session := podmanTest.Podman([]string{"build", "--pull-never", "-f", "build/squash/Dockerfile.squash-c", "--squash-all", "--layers", "-t", "test-squash-d:latest", "build/squash"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"inspect", "--format", "{{.RootFS.Layers}}", "test-squash-d"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + // Check for one layers + Expect(strings.Fields(session.OutputToString())).To(HaveLen(1)) + + // Second build must use last squashed build from cache + session = podmanTest.Podman([]string{"build", "--pull-never", "-f", "build/squash/Dockerfile.squash-c", "--squash-all", "--layers", "-t", "test", "build/squash"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + // Test if entire build is used from cache + Expect(session.OutputToString()).To(ContainSubstring("Using cache")) + + session = podmanTest.Podman([]string{"inspect", "--format", "{{.RootFS.Layers}}", "test-squash-d"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + // Check for one layers + Expect(strings.Fields(session.OutputToString())).To(HaveLen(1)) + + }) + It("podman build Containerfile locations", func() { // Given // Switch to temp dir and restore it afterwards diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go index 787178cd3..1da199714 100644 --- a/test/e2e/checkpoint_test.go +++ b/test/e2e/checkpoint_test.go @@ -676,8 +676,8 @@ var _ = Describe("Podman checkpoint", func() { }) It("podman checkpoint and restore container with root file-system changes using --ignore-rootfs during restore", func() { // Start the container - localRunString := getRunString([]string{"--rm", ALPINE, "top"}) - session := podmanTest.Podman(localRunString) + // test that restore works without network namespace (https://github.com/containers/podman/issues/14389) + session := podmanTest.Podman([]string{"run", "--network=none", "-d", "--rm", ALPINE, "top"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) diff --git a/test/e2e/kill_test.go b/test/e2e/kill_test.go index 552a7c15d..2a9a86729 100644 --- a/test/e2e/kill_test.go +++ b/test/e2e/kill_test.go @@ -128,6 +128,26 @@ var _ = Describe("Podman kill", func() { Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) }) + It("podman kill paused container", func() { + ctrName := "testctr" + session := podmanTest.RunTopContainer(ctrName) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + pause := podmanTest.Podman([]string{"pause", ctrName}) + pause.WaitWithDefaultTimeout() + Expect(pause).Should(Exit(0)) + + kill := podmanTest.Podman([]string{"kill", ctrName}) + kill.WaitWithDefaultTimeout() + Expect(kill).Should(Exit(0)) + + inspect := podmanTest.Podman([]string{"inspect", "-f", "{{.State.Status}}", ctrName}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).Should(Exit(0)) + Expect(inspect.OutputToString()).To(Or(Equal("stopped"), Equal("exited"))) + }) + It("podman kill --cidfile", func() { tmpDir, err := ioutil.TempDir("", "") Expect(err).To(BeNil()) diff --git a/test/e2e/logs_test.go b/test/e2e/logs_test.go index 4e6dcb8af..0d24a7e17 100644 --- a/test/e2e/logs_test.go +++ b/test/e2e/logs_test.go @@ -102,12 +102,12 @@ var _ = Describe("Podman logs", func() { It("tail 99 lines: "+log, func() { skipIfJournaldInContainer() - logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) + name := "test1" + logc := podmanTest.Podman([]string{"run", "--name", name, "--log-driver", log, ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"}) logc.WaitWithDefaultTimeout() Expect(logc).To(Exit(0)) - cid := logc.OutputToString() - results := podmanTest.Podman([]string{"logs", "--tail", "99", cid}) + results := podmanTest.Podman([]string{"logs", "--tail", "99", name}) results.WaitWithDefaultTimeout() Expect(results).To(Exit(0)) Expect(results.OutputToStringArray()).To(HaveLen(3)) @@ -116,11 +116,17 @@ var _ = Describe("Podman logs", func() { It("tail 800 lines: "+log, func() { skipIfJournaldInContainer() + // this uses -d so that we do not have 1000 unnecessary lines printed in every test log logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "i=1; while [ \"$i\" -ne 1000 ]; do echo \"line $i\"; i=$((i + 1)); done"}) logc.WaitWithDefaultTimeout() Expect(logc).To(Exit(0)) cid := logc.OutputToString() + // make sure we wait for the container to finish writing its output + wait := podmanTest.Podman([]string{"wait", cid}) + wait.WaitWithDefaultTimeout() + Expect(wait).To(Exit(0)) + results := podmanTest.Podman([]string{"logs", "--tail", "800", cid}) results.WaitWithDefaultTimeout() Expect(results).To(Exit(0)) diff --git a/test/e2e/network_connect_disconnect_test.go b/test/e2e/network_connect_disconnect_test.go index a0716c84d..019bb4617 100644 --- a/test/e2e/network_connect_disconnect_test.go +++ b/test/e2e/network_connect_disconnect_test.go @@ -114,6 +114,11 @@ var _ = Describe("Podman network connect and disconnect", func() { exec3.WaitWithDefaultTimeout() Expect(exec3).Should(Exit(0)) Expect(strings.Contains(exec3.OutputToString(), ns)).To(BeFalse()) + + // make sure stats still works https://github.com/containers/podman/issues/13824 + stats := podmanTest.Podman([]string{"stats", "test", "--no-stream"}) + stats.WaitWithDefaultTimeout() + Expect(stats).Should(Exit(0)) }) It("bad network name in connect should result in error", func() { @@ -237,6 +242,11 @@ var _ = Describe("Podman network connect and disconnect", func() { Expect(exec3).Should(Exit(0)) Expect(strings.Contains(exec3.OutputToString(), ns)).To(BeTrue()) + // make sure stats works https://github.com/containers/podman/issues/13824 + stats := podmanTest.Podman([]string{"stats", "test", "--no-stream"}) + stats.WaitWithDefaultTimeout() + Expect(stats).Should(Exit(0)) + // make sure no logrus errors are shown https://github.com/containers/podman/issues/9602 rm := podmanTest.Podman([]string{"rm", "--time=0", "-f", "test"}) rm.WaitWithDefaultTimeout() diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go index 3b32b4b82..4081ec45b 100644 --- a/test/e2e/run_networking_test.go +++ b/test/e2e/run_networking_test.go @@ -381,7 +381,7 @@ EXPOSE 2004-2005/tcp`, ALPINE) session := podmanTest.Podman([]string{"run", "-dt", "-p", fmt.Sprintf("%d:%d", port1, port2), ALPINE, "/bin/sh"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - results := SystemExec("iptables", []string{"-t", "nat", "-L"}) + results := SystemExec("iptables", []string{"-t", "nat", "-nvL"}) Expect(results).Should(Exit(0)) Expect(results.OutputToString()).To(ContainSubstring(fmt.Sprintf("%d", port2))) diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go index 64677ba54..d37d8fd1a 100644 --- a/test/e2e/search_test.go +++ b/test/e2e/search_test.go @@ -455,7 +455,6 @@ registries = ['{{.Host}}:{{.Port}}']` }) It("podman search with wildcards", func() { - Skip("FIXME: search on registry.redhat.io is broken (Dec 16 '21)") search := podmanTest.Podman([]string{"search", "registry.redhat.io/*openshift*"}) search.WaitWithDefaultTimeout() Expect(search).Should(Exit(0)) diff --git a/test/e2e/volume_create_test.go b/test/e2e/volume_create_test.go index 0bf5acbf1..499283cab 100644 --- a/test/e2e/volume_create_test.go +++ b/test/e2e/volume_create_test.go @@ -110,15 +110,24 @@ var _ = Describe("Podman volume create", func() { Expect(session.OutputToString()).To(ContainSubstring("hello")) }) - It("podman import volume should fail", func() { + It("podman import/export volume should fail", func() { // try import on volume or source which does not exists - if podmanTest.RemoteTest { - Skip("Volume export check does not work with a remote client") - } + SkipIfRemote("Volume export check does not work with a remote client") session := podmanTest.Podman([]string{"volume", "import", "notfound", "notfound.tar"}) session.WaitWithDefaultTimeout() Expect(session).To(ExitWithError()) + Expect(session.ErrorToString()).To(ContainSubstring("open notfound.tar: no such file or directory")) + + session = podmanTest.Podman([]string{"volume", "import", "notfound", "-"}) + session.WaitWithDefaultTimeout() + Expect(session).To(ExitWithError()) + Expect(session.ErrorToString()).To(ContainSubstring("no such volume notfound")) + + session = podmanTest.Podman([]string{"volume", "export", "notfound"}) + session.WaitWithDefaultTimeout() + Expect(session).To(ExitWithError()) + Expect(session.ErrorToString()).To(ContainSubstring("no such volume notfound")) }) It("podman create volume with bad volume option", func() { diff --git a/test/system/015-help.bats b/test/system/015-help.bats index 5757d51dc..1356c99a0 100644 --- a/test/system/015-help.bats +++ b/test/system/015-help.bats @@ -34,10 +34,16 @@ function check_help() { # has no ' [options]' is "$usage " " $command_string .*" "Usage string matches command" + # Strip off the leading command string; we no longer need it + usage=$(sed -e "s/^ $command_string \?//" <<<"$usage") + # If usage ends in '[command]', recurse into subcommands - if expr "$usage" : '.*\[command\]$' >/dev/null; then + if expr "$usage" : '\[command\]' >/dev/null; then found[subcommands]=1 - check_help "$@" $cmd + # (except for 'podman help', which is a special case) + if [[ $cmd != "help" ]]; then + check_help "$@" $cmd + fi continue fi @@ -49,10 +55,26 @@ function check_help() { assert "$usage" !~ '[A-Z].*\[option' \ "'options' must precede arguments in usage" + # Strip off '[options]' but remember if we've seen it. + local has_options= + if [[ $usage =~ \[options\] ]]; then + has_options=1 + usage=$(sed -e 's/^\[options\] \?//' <<<"$usage") + fi + + # From this point on, remaining argument descriptions must be UPPER CASE + # e.g., 'podman cmd [options] arg' or 'podman cmd [arg]' are invalid. + assert "$usage" !~ '[a-z]' \ + "$command_string: argument names must be UPPER CASE" + + # It makes no sense to have an optional arg followed by a mandatory one + assert "$usage" !~ '\[.*\] [A-Z]' \ + "$command_string: optional args must be _after_ required ones" + # Cross-check: if usage includes '[options]', there must be a # longer 'Options:' section in the full --help output; vice-versa, # if 'Options:' is in full output, usage line must have '[options]'. - if expr "$usage" : '.*\[option' >/dev/null; then + if [[ $has_options ]]; then if ! expr "$full_help" : ".*Options:" >/dev/null; then die "$command_string: Usage includes '[options]' but has no 'Options:' subsection" fi @@ -95,9 +117,7 @@ function check_help() { fi # If usage has required arguments, try running without them. - # The expression here is 'first capital letter is not in [BRACKETS]'. - # It is intended to handle 'podman foo [options] ARG' but not ' [ARG]'. - if expr "$usage" : '[^A-Z]\+ [A-Z]' >/dev/null; then + if expr "$usage" : '[A-Z]' >/dev/null; then # Exceptions: these commands don't work rootless if is_rootless; then # "pause is not supported for rootless containers" @@ -126,25 +146,15 @@ function check_help() { # the required args, then invoke with one extra. We should get a # usage error. if ! expr "$usage" : ".*\.\.\."; then - # "podman help" can take infinite args, so skip that one - if [ "$cmd" != "help" ]; then - # Get the args part of the command line; this should be - # everything from the first CAPITAL LETTER onward. We - # don't actually care about the letter itself, so just - # make it 'X'. And we don't care about [OPTIONAL] brackets - # either. What we do care about is stuff like 'IMAGE | CTR' - # which is actually one argument; convert to 'IMAGE-or-CTR' - local rhs=$(sed -e 's/^[^A-Z]\+[A-Z]/X/' -e 's/ | /-or-/g' <<<"$usage") - local n_args=$(wc -w <<<"$rhs") - - run_podman '?' "$@" $cmd $(seq --format='x%g' 0 $n_args) - is "$status" 125 \ - "'$usage' indicates a maximum of $n_args args. I invoked it with more, and expected this exit status" - is "$output" "Error:.* \(takes no arguments\|requires exactly $n_args arg\|accepts at most\|too many arguments\|accepts $n_args arg(s), received\|accepts between .* and .* arg(s), received \)" \ - "'$usage' indicates a maximum of $n_args args. I invoked it with more, and expected one of these error messages" + local n_args=$(wc -w <<<"$usage") - found[fixed_args]=1 - fi + run_podman '?' "$@" $cmd $(seq --format='x%g' 0 $n_args) + is "$status" 125 \ + "'$usage' indicates a maximum of $n_args args. I invoked it with more, and expected this exit status" + is "$output" "Error:.* \(takes no arguments\|requires exactly $n_args arg\|accepts at most\|too many arguments\|accepts $n_args arg(s), received\|accepts between .* and .* arg(s), received \)" \ + "'$usage' indicates a maximum of $n_args args. I invoked it with more, and expected one of these error messages" + + found[fixed_args]=1 fi count=$(expr $count + 1) diff --git a/test/system/030-run.bats b/test/system/030-run.bats index 283c3aea9..241831257 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -855,4 +855,15 @@ EOF run_podman rmi $test_image } +@test "podman create --security-opt" { + run_podman create --security-opt no-new-privileges=true $IMAGE + run_podman rm $output + run_podman create --security-opt no-new-privileges:true $IMAGE + run_podman rm $output + run_podman create --security-opt no-new-privileges=false $IMAGE + run_podman rm $output + run_podman create --security-opt no-new-privileges $IMAGE + run_podman rm $output +} + # vim: filetype=sh diff --git a/test/system/060-mount.bats b/test/system/060-mount.bats index 7addbd88e..2735d2afd 100644 --- a/test/system/060-mount.bats +++ b/test/system/060-mount.bats @@ -50,6 +50,10 @@ load helpers run_podman image mount $IMAGE mount_path="$output" + # Make sure that `mount -a` prints a table + run_podman image mount -a + is "$output" "$IMAGE .*$mount_path" + test -d $mount_path # Image is custom-built and has a file containing the YMD tag. Check it. @@ -62,8 +66,8 @@ load helpers run_podman image mount is "$output" "$IMAGE *$mount_path" "podman image mount with no args" - # Clean up - run_podman image umount $IMAGE + # Clean up: -f since we mounted it twice + run_podman image umount -f $IMAGE is "$output" "$iid" "podman image umount: image ID of what was umounted" run_podman image umount $IMAGE diff --git a/test/system/160-volumes.bats b/test/system/160-volumes.bats index 5b0460723..797883ec6 100644 --- a/test/system/160-volumes.bats +++ b/test/system/160-volumes.bats @@ -411,4 +411,43 @@ NeedsChown | true fi } +@test "podman --image-volume" { + tmpdir=$PODMAN_TMPDIR/volume-test + mkdir -p $tmpdir + containerfile=$tmpdir/Containerfile + cat >$containerfile <<EOF +FROM $IMAGE +VOLUME /data +EOF + fs=$(stat -f -c %T .) + run_podman build -t volume_image $tmpdir + + containersconf=$tmpdir/containers.conf + cat >$containersconf <<EOF +[engine] +image_volume_mode="tmpfs" +EOF + + run_podman run --image-volume tmpfs --rm volume_image stat -f -c %T /data + is "$output" "tmpfs" "Should be tmpfs" + + run_podman 1 run --image-volume ignore --rm volume_image stat -f -c %T /data + is "$output" "stat: can't read file system information for '/data': No such file or directory" "Should fail with /data does not exists" + + CONTAINERS_CONF="$containersconf" run_podman run --rm volume_image stat -f -c %T /data + is "$output" "tmpfs" "Should be tmpfs" + + CONTAINERS_CONF="$containersconf" run_podman run --image-volume bind --rm volume_image stat -f -c %T /data + assert "$output" != "tmpfs" "Should match hosts $fs" + + CONTAINERS_CONF="$containersconf" run_podman run --image-volume tmpfs --rm volume_image stat -f -c %T /data + is "$output" "tmpfs" "Should be tmpfs" + + CONTAINERS_CONF="$containersconf" run_podman 1 run --image-volume ignore --rm volume_image stat -f -c %T /data + is "$output" "stat: can't read file system information for '/data': No such file or directory" "Should fail with /data does not exists" + + run_podman rm --all --force -t 0 + run_podman image rm --force localhost/volume_image +} + # vim: filetype=sh diff --git a/test/system/170-run-userns.bats b/test/system/170-run-userns.bats index b80351902..46cb37b9d 100644 --- a/test/system/170-run-userns.bats +++ b/test/system/170-run-userns.bats @@ -38,10 +38,12 @@ function _require_crun() { @test "rootful pod with custom ID mapping" { skip_if_rootless "does not work rootless - rootful feature" - skip_if_remote "remote --uidmap is broken (see #14233)" random_pod_name=$(random_string 30) run_podman pod create --uidmap 0:200000:5000 --name=$random_pod_name run_podman pod start $random_pod_name + run_podman pod inspect --format '{{.InfraContainerID}}' $random_pod_name + run podman inspect --format '{{.HostConfig.IDMappings.UIDMap}}' $output + is "$output" ".*0:200000:5000" "UID Map Successful" # Remove the pod and the pause image run_podman pod rm $random_pod_name diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats index 4250f2680..404ad67ec 100644 --- a/test/system/200-pod.bats +++ b/test/system/200-pod.bats @@ -335,8 +335,15 @@ EOF is "$output" ".*Invalid kernel namespace to share: bogus. Options are: cgroup, ipc, net, pid, uts or none" \ "pod test for bogus --share option" run_podman pod create --share ipc --name $pod_name + run_podman pod inspect $pod_name --format "{{.SharedNamespaces}}" + is "$output" "[ipc]" run_podman run --rm --pod $pod_name --hostname foobar $IMAGE hostname is "$output" "foobar" "--hostname should work with non share UTS namespace" + run_podman pod create --share +pid --replace --name $pod_name + run_podman pod inspect $pod_name --format "{{.SharedNamespaces}}" + for ns in uts pid ipc net; do + is "$output" ".*$ns" + done } @test "podman pod create --pod new:$POD --hostname" { @@ -387,20 +394,20 @@ EOF is "$output" "false" "Default network sharing should be false" run_podman pod rm test - run_podman pod create --name test --share ipc --network private + run_podman pod create --share ipc --network private test run_podman pod inspect test --format {{.InfraConfig.HostNetwork}} is "$output" "false" "Private network sharing with only ipc should be false" run_podman pod rm test - run_podman pod create --name test --share net --network private - run_podman pod inspect test --format {{.InfraConfig.HostNetwork}} + local name="$(random_string 10 | tr A-Z a-z)" + run_podman pod create --name $name --share net --network private + run_podman pod inspect $name --format {{.InfraConfig.HostNetwork}} is "$output" "false" "Private network sharing with only net should be false" - run_podman pod rm test - run_podman pod create --name test --share net --network host - run_podman pod inspect test --format {{.InfraConfig.HostNetwork}} + run_podman pod create --share net --network host --replace $name + run_podman pod inspect $name --format {{.InfraConfig.HostNetwork}} is "$output" "true" "Host network sharing with only net should be true" - run_podman pod rm test + run_podman pod rm $name run_podman pod create --name test --share ipc --network host run_podman pod inspect test --format {{.InfraConfig.HostNetwork}} diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats index 567fa89c1..110d425d2 100644 --- a/test/system/250-systemd.bats +++ b/test/system/250-systemd.bats @@ -80,12 +80,6 @@ function service_cleanup() { run_podman logs $cname is "$output" ".*WAITING.*" "running is waiting for signal" - # Exercise `podman auto-update`. - # TODO: this will at least run auto-update code but won't perform an update - # since the image didn't change. We need to improve on that and run - # an image from a local registry instead. - run_podman auto-update - # All good. Stop service, clean up. # Also make sure the service is in the `inactive` state (see #11304). service_cleanup inactive diff --git a/test/system/600-completion.bats b/test/system/600-completion.bats index 018e95e78..2de9b1ae1 100644 --- a/test/system/600-completion.bats +++ b/test/system/600-completion.bats @@ -8,6 +8,16 @@ load helpers +function setup() { + # $PODMAN may be a space-separated string, e.g. if we include a --url. + local -a podman_as_array=($PODMAN) + # __completeNoDesc must be the first arg if we running the completion cmd + # set the var for the run_completion function + PODMAN_COMPLETION="${podman_as_array[0]} __completeNoDesc ${podman_as_array[@]:1}" + + basic_setup +} + # Returns true if we are able to podman-pause function _can_pause() { # Even though we're just trying completion, not an actual unpause, @@ -88,8 +98,14 @@ function check_shell_completion() { continue 2 fi + name=$random_container_name + # special case podman cp suggest containers names with a colon + if [[ $cmd = "cp" ]]; then + name="$name:" + fi + run_completion "$@" $cmd "${extra_args[@]}" "" - is "$output" ".*-$random_container_name${nl}" \ + is "$output" ".*-$name${nl}" \ "$* $cmd: actual container listed in suggestions" match=true @@ -175,7 +191,7 @@ function check_shell_completion() { _check_completion_end NoSpace else _check_completion_end Default - assert "${#lines[@]}" -eq 2 "$* $cmd: Suggestions are in the output" + _check_no_suggestions fi ;; @@ -205,16 +221,7 @@ function check_shell_completion() { if [[ ! ${args##* } =~ "..." ]]; then run_completion "$@" $cmd "${extra_args[@]}" "" _check_completion_end NoFileComp - if [ ${#lines[@]} -gt 2 ]; then - # checking for line count is not enough since we may include additional debug output - # lines starting with [Debug] are allowed - i=0 - length=$(( ${#lines[@]} - 2 )) - while [[ i -lt length ]]; do - assert "${lines[$i]:0:7}" == "[Debug]" "Suggestions are in the output" - i=$(( i + 1 )) - done - fi + _check_no_suggestions fi done @@ -231,6 +238,24 @@ function _check_completion_end() { is "${lines[-1]}" "Completion ended with directive: ShellCompDirective$1" "Completion has wrong ShellCompDirective set" } +# Check that there are no suggestions in the output. +# We could only check stdout and not stderr but this is not possible with bats. +# By default we always have two extra lines at the end for the ShellCompDirective. +# Then we could also have other extra lines for debugging, they will always start +# with [Debug], e.g. `[Debug] [Error] no container with name or ID "t12" found: no such container`. +function _check_no_suggestions() { + if [ ${#lines[@]} -gt 2 ]; then + # Checking for line count is not enough since we may include additional debug output. + # Lines starting with [Debug] are allowed. + local i=0 + length=$((${#lines[@]} - 2)) + while [[ i -lt length ]]; do + assert "${lines[$i]:0:7}" == "[Debug]" "Unexpected non-Debug output line: ${lines[$i]}" + i=$((i + 1)) + done + fi +} + @test "podman shell completion test" { @@ -280,11 +305,6 @@ function _check_completion_end() { # create secret run_podman secret create $random_secret_name $secret_file - # $PODMAN may be a space-separated string, e.g. if we include a --url. - local -a podman_as_array=($PODMAN) - # __completeNoDesc must be the first arg if we running the completion cmd - PODMAN_COMPLETION="${podman_as_array[0]} __completeNoDesc ${podman_as_array[@]:1}" - # Called with no args -- start with 'podman --help'. check_shell_completion() will # recurse for any subcommands. check_shell_completion @@ -316,3 +336,41 @@ function _check_completion_end() { done <<<"$output" } + +@test "podman shell completion for paths in container/image" { + skip_if_remote "mounting via remote does not work" + for cmd in create run; do + run_completion $cmd $IMAGE "" + assert "$output" =~ ".*^/etc\$.*^/home\$.*^/root\$.*" "root directories suggested (cmd: podman $cmd)" + + # check completion for subdirectory + run_completion $cmd $IMAGE "/etc" + # It should be safe to assume the os-release file always exists in $IMAGE + assert "$output" =~ ".*^/etc/os-release\$.*" "/etc files suggested (cmd: podman $cmd /etc)" + # check completion for partial file name + run_completion $cmd $IMAGE "/etc/os-" + assert "$output" =~ ".*^/etc/os-release\$.*" "/etc files suggested (cmd: podman $cmd /etc/os-)" + + # check completion with relative path components + # It is important the we will still use the image root and not escape to the host + run_completion $cmd $IMAGE "../../" + assert "$output" =~ ".*^../../etc\$.*^../../home\$.*" "relative root directories suggested (cmd: podman $cmd ../../)" + done + + random_name=$(random_string 30) + random_file=$(random_string 30) + run_podman run --name $random_name $IMAGE touch /tmp/$random_file + + # check completion for podman cp + run_completion cp "" + assert "$output" =~ ".*^$random_name\:\$.*" "podman cp suggest container names" + + run_completion cp "$random_name:" + assert "$output" =~ ".*^$random_name\:/etc\$.*" "podman cp suggest paths in container" + + run_completion cp "$random_name:/tmp" + assert "$output" =~ ".*^$random_name\:/tmp/$random_file\$.*" "podman cp suggest custom file in container" + + # cleanup container + run_podman rm $random_name +} |