diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/apiv2/10-images.at | 2 | ||||
-rw-r--r-- | test/apiv2/12-imagesMore.at | 56 | ||||
-rw-r--r-- | test/apiv2/15-manifest.at | 24 | ||||
-rw-r--r-- | test/apiv2/20-containers.at | 10 | ||||
-rw-r--r-- | test/apiv2/60-auth.at | 4 | ||||
-rw-r--r-- | test/apiv2/70-short-names.at | 2 | ||||
-rwxr-xr-x | test/apiv2/test-apiv2 | 90 | ||||
-rwxr-xr-x | test/buildah-bud/apply-podman-deltas | 6 | ||||
-rw-r--r-- | test/e2e/build_test.go | 2 | ||||
-rw-r--r-- | test/e2e/pod_infra_container_test.go | 16 | ||||
-rw-r--r-- | test/system/065-cp.bats | 100 | ||||
-rw-r--r-- | test/system/520-checkpoint.bats | 30 | ||||
-rw-r--r-- | test/system/600-completion.bats | 18 |
13 files changed, 275 insertions, 85 deletions
diff --git a/test/apiv2/10-images.at b/test/apiv2/10-images.at index 13aaea317..f03b95786 100644 --- a/test/apiv2/10-images.at +++ b/test/apiv2/10-images.at @@ -53,7 +53,7 @@ t POST "images/create?fromImage=alpine" 200 .error~null .status~".*Download comp t POST "images/create?fromImage=alpine&tag=latest" 200 # 10977 - handle platform parameter correctly -t POST "images/create?fromImage=testimage:20210610&platform=linux/arm64" 200 +t POST "images/create?fromImage=quay.io/libpod/testimage:20210610&platform=linux/arm64" 200 t GET "images/testimage:20210610/json" 200 \ .Architecture=arm64 diff --git a/test/apiv2/12-imagesMore.at b/test/apiv2/12-imagesMore.at index 67b4f1c79..57d5e114d 100644 --- a/test/apiv2/12-imagesMore.at +++ b/test/apiv2/12-imagesMore.at @@ -6,6 +6,8 @@ red='\e[31m' nc='\e[0m' +start_registry + podman pull -q $IMAGE t GET libpod/images/json 200 \ @@ -20,48 +22,38 @@ t GET libpod/images/$IMAGE/tree 200 \ t POST "libpod/images/nonesuch/tag?repo=myrepo&tag=mytag" 404 # Tag the image -t POST "libpod/images/$IMAGE/tag?repo=localhost:5000/myrepo&tag=mytag" 201 +t POST "libpod/images/$IMAGE/tag?repo=localhost:$REGISTRY_PORT/myrepo&tag=mytag" 201 t GET libpod/images/$IMAGE/json 200 \ - .RepoTags[1]=localhost:5000/myrepo:mytag - -# Run registry container -# FIXME this fails if python tests have been run first... -podman run -d --name registry -p 5000:5000 quay.io/libpod/registry:2.7 /entrypoint.sh /etc/docker/registry/config.yml -wait_for_port localhost 5000 - -# Push to local registry and check output -while read -r LINE -do - if echo "${LINE}" | jq --exit-status 'select( .status != null) | select ( .status | contains("digest: sha256:"))' &>/dev/null; then - GOT_DIGEST="1" - fi -done < <(curl -sL "http://$HOST:$PORT/images/localhost:5000/myrepo/push?tlsVerify=false&tag=mytag" -XPOST) -if [ -z "${GOT_DIGEST}" ] ; then - echo -e "${red}not ok: did not found digest in output${nc}" 1>&2; -fi - -# Push to local registry -t POST "images/localhost:5000/myrepo/push?tlsVerify=false&tag=mytag" 200 + .RepoTags[1]=localhost:$REGISTRY_PORT/myrepo:mytag + +# Push to local registry... +t POST "images/localhost:$REGISTRY_PORT/myrepo/push?tlsVerify=false&tag=mytag" 200 + +# ...and check output. We can't use our built-in checks because this output +# is a sequence of JSON objects, i.e., individual ones, not in a JSON array. +# The lines themselves are valid JSON, but taken together they are not. +readarray lines <<<"$output" +s0=$(jq -r .status <<<"${lines[0]}") +is "$s0" "The push refers to repository [localhost:$REGISTRY_PORT/myrepo:mytag]" \ + "Push to local registry: first status line" + +# FIXME: is there a way to test the actual digest? +s1=$(jq -r .status <<<"${lines[1]}") +like "$s1" "mytag: digest: sha256:[0-9a-f]\{64\} size: [0-9]\+" \ + "Push to local registry: second status line" # Untag the image -t POST "libpod/images/$iid/untag?repo=localhost:5000/myrepo&tag=mytag" 201 +t POST "libpod/images/$iid/untag?repo=localhost:$REGISTRY_PORT/myrepo&tag=mytag" 201 # Try to push non-existing image -t POST "images/localhost:5000/idonotexist/push?tlsVerify=false" 404 +t POST "images/localhost:$REGISTRY_PORT/idonotexist/push?tlsVerify=false" 404 t GET libpod/images/$IMAGE/json 200 \ .RepoTags[-1]=$IMAGE -# Remove the registry container -t DELETE libpod/containers/registry?force=true 200 - -# Remove images +# Remove image t DELETE libpod/images/$IMAGE 200 \ .ExitCode=0 -t DELETE libpod/images/quay.io/libpod/registry:2.7 200 \ - .ExitCode=0 -if [ -z "${GOT_DIGEST}" ] ; then - exit 1; -fi +stop_registry diff --git a/test/apiv2/15-manifest.at b/test/apiv2/15-manifest.at index 0dd7026fa..970bed5a8 100644 --- a/test/apiv2/15-manifest.at +++ b/test/apiv2/15-manifest.at @@ -2,18 +2,40 @@ # # Tests for manifest list endpoints +start_registry + t POST /v3.4.0/libpod/manifests/create?name=abc 200 \ .Id~[0-9a-f]\\{64\\} id_abc=$(jq -r '.Id' <<<"$output") t POST /v4.0.0/libpod/manifests/xyz 201 \ .Id~[0-9a-f]\\{64\\} -echo xyz $output id_xyz=$(jq -r '.Id' <<<"$output") t GET /v3.4.0/libpod/manifests/$id_abc/exists 204 t GET /v4.0.0/libpod/manifests/$id_xyz/exists 204 +id_abc_image=$($PODMAN_BIN --root $WORKDIR/server_root image build -q --format=docker -<<EOF +FROM alpine +RUN >file1 +EOF +) + +id_xyz_image=$($PODMAN_BIN --root $WORKDIR/server_root image build -q --format=docker -<<EOF +FROM alpine +RUN >file2 +EOF +) + +t POST /v3.4.0/libpod/manifests/$id_abc/add images="[\"containers-storage:$id_abc_image\"]" 200 +t PUT /v4.0.0/libpod/manifests/$id_xyz operation='update' images="[\"containers-storage:$id_xyz_image\"]" 200 + +t POST "/v3.4.0/libpod/manifests/abc:latest/push?destination=localhost:$REGISTRY_PORT%2Fabc:latest&tlsVerify=false&all=true" 200 +t POST "/v4.0.0/libpod/manifests/xyz:latest/registry/localhost:$REGISTRY_PORT%2Fxyz:latest?tlsVerify=false&all=true" 200 + # /v3.x cannot delete a manifest list t DELETE /v4.0.0/libpod/manifests/$id_abc 200 t DELETE /v4.0.0/libpod/manifests/$id_xyz 200 + +podman rmi -a +stop_registry diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at index 4d32a1031..383c527b4 100644 --- a/test/apiv2/20-containers.at +++ b/test/apiv2/20-containers.at @@ -45,16 +45,16 @@ t GET libpod/containers/json?all=true 200 \ .[0].IsInfra=false # Test compat API for Network Settings (.Network is N/A when rootless) -network_expect= +network_expect="Networks=null" if root; then - network_expect='.[0].NetworkSettings.Networks.podman.NetworkID=podman' + network_expect="Networks.podman.NetworkID=podman" fi t GET /containers/json?all=true 200 \ length=1 \ .[0].Id~[0-9a-f]\\{64\\} \ .[0].Image=$IMAGE \ .[0].Mounts~.*/tmp \ - $network_expect + .[0].NetworkSettings.$network_expect # compat API imageid with sha256: prefix t GET containers/json?limit=1 200 \ @@ -239,6 +239,7 @@ t GET containers/$cid/json 200 \ t POST containers/create Image=$IMAGE Entrypoint='["top"]' 201 \ .Id~[0-9a-f]\\{64\\} cid_top=$(jq -r '.Id' <<<"$output") + t GET containers/${cid_top}/json 200 \ .Config.Entrypoint[0]="top" \ .Config.Cmd='[]' \ @@ -477,7 +478,8 @@ for endpoint in containers/create libpod/containers/create; do t POST libpod/containers/$cid/init 204 - t GET libpod/containers/$cid/json 200 + t GET libpod/containers/$cid/json 200 \ + .HostsPath="" t DELETE containers/$cid 204 done diff --git a/test/apiv2/60-auth.at b/test/apiv2/60-auth.at index 1e087d12b..465b0a96d 100644 --- a/test/apiv2/60-auth.at +++ b/test/apiv2/60-auth.at @@ -3,7 +3,7 @@ # registry-related tests # -start_registry +start_registry htpasswd # Test unreachable t POST /v1.40/auth username=$REGISTRY_USERNAME password=WrOnGPassWord serveraddress=does.not.exist.io:1234/ \ @@ -26,3 +26,5 @@ t POST /v1.40/auth username=$REGISTRY_USERNAME password=$REGISTRY_PASSWORD serve 200 \ .Status="Login Succeeded" \ .IdentityToken="" + +stop_registry diff --git a/test/apiv2/70-short-names.at b/test/apiv2/70-short-names.at index dbf816f55..bd7f8e7bd 100644 --- a/test/apiv2/70-short-names.at +++ b/test/apiv2/70-short-names.at @@ -128,7 +128,7 @@ t DELETE "containers/$cid" # disable the docker.io enforcement. stop_service -CONTAINERS_CONF=$(pwd)/test/apiv2/containers.conf start_service +CONTAINERS_CONF=$TESTS_DIR/containers.conf start_service t POST "images/create?fromImage=quay.io/libpod/alpine:latest" 200 .error~null .status~".*Download complete.*" t POST "images/alpine/tag?repo=foo" 201 diff --git a/test/apiv2/test-apiv2 b/test/apiv2/test-apiv2 index c3545522e..8ecc2aa2d 100755 --- a/test/apiv2/test-apiv2 +++ b/test/apiv2/test-apiv2 @@ -62,7 +62,7 @@ clean_up_server() { podman rm -a podman rmi -af - stop_registry + stop_registry --cleanup stop_service fi } @@ -87,6 +87,7 @@ trap err_handler ERR ######### function die() { echo "$ME: $*" >&2 + clean_up_server exit 1 } @@ -219,19 +220,19 @@ function jsonify() { function t() { local method=$1; shift local path=$1; shift - local curl_args + local -a curl_args local content_type="application/json" local testname="$method $path" - # POST requests may be followed by one or more key=value pairs. + # POST and PUT requests may be followed by one or more key=value pairs. # Slurp the command line until we see a 3-digit status code. - if [[ $method = "POST" ]]; then + if [[ $method = "POST" || $method == "PUT" ]]; then local -a post_args for arg; do case "$arg" in *=*) post_args+=("$arg"); shift;; - *.tar) curl_args="--data-binary @$arg" ; + *.tar) curl_args+=(--data-binary @$arg); content_type="application/x-tar"; shift;; application/*) content_type="$arg"; @@ -241,8 +242,8 @@ function t() { esac done if [[ -z "$curl_args" ]]; then - curl_args="-d $(jsonify ${post_args[@]})" - testname="$testname [$curl_args]" + curl_args=(-d $(jsonify ${post_args[@]})) + testname="$testname [${curl_args[@]}]" fi fi @@ -269,7 +270,7 @@ function t() { # curl -X HEAD but without --head seems to wait for output anyway if [[ $method == "HEAD" ]]; then - curl_args="--head" + curl_args+=("--head") fi local expected_code=$1; shift @@ -281,7 +282,7 @@ function t() { # -s = silent, but --write-out 'format' gives us important response data # The hairy "{ ...;rc=$?; } || :" lets us capture curl's exit code and # give a helpful diagnostic if it fails. - { response=$(curl -s -X $method ${curl_args} \ + { response=$(curl -s -X $method "${curl_args[@]}" \ -H "Content-type: $content_type" \ --dump-header $WORKDIR/curl.headers.out \ --write-out '%{http_code}^%{content_type}^%{time_total}' \ @@ -289,8 +290,7 @@ function t() { # Any error from curl is instant bad news, from which we can't recover if [[ $rc -ne 0 ]]; then - echo "FATAL: curl failure ($rc) on $url - cannot continue" >&2 - exit 1 + die "curl failure ($rc) on $url - cannot continue" fi # Show returned headers (without trailing ^M or empty lines) in log file. @@ -380,11 +380,6 @@ function start_service() { die "Cannot start service on non-localhost ($HOST)" fi - echo "rootdir: "$WORKDIR - # Some tests use shortnames; force registry override to work around - # docker.io throttling. -# FIXME esm revisit pulling expected images re: shortnames caused tests to fail -# env CONTAINERS_REGISTRIES_CONF=$TESTS_DIR/../registries.conf $PODMAN_BIN \ --root $WORKDIR/server_root --syslog=true \ system service \ @@ -411,15 +406,17 @@ REGISTRY_PORT= REGISTRY_USERNAME= REGISTRY_PASSWORD= function start_registry() { - # We can be invoked multiple times, e.g. from different subtests, but - # let's assume that once started we only kill it at the end of tests. + # We can be called multiple times, but each time should start a new + # registry container with (possibly) different configuration. That + # means that all callers must be responsible for invoking stop_registry. if [[ -n "$REGISTRY_PORT" ]]; then - return + die "start_registry invoked twice in succession, without stop_registry" fi + # First arg is auth type (default: "none", but can also be "htpasswd") + local auth="${1:-none}" + REGISTRY_PORT=$(random_port) - REGISTRY_USERNAME=u$(random_string 7) - REGISTRY_PASSWORD=p$(random_string 7) local REGDIR=$WORKDIR/registry local AUTHDIR=$REGDIR/auth @@ -433,24 +430,39 @@ function start_registry() { podman ${PODMAN_REGISTRY_ARGS} pull $REGISTRY_IMAGE || podman ${PODMAN_REGISTRY_ARGS} pull $REGISTRY_IMAGE - # Create a local cert and credentials - # FIXME: is there a hidden "--quiet" flag? This is too noisy. - openssl req -newkey rsa:4096 -nodes -sha256 \ - -keyout $AUTHDIR/domain.key -x509 -days 2 \ - -out $AUTHDIR/domain.crt \ - -subj "/C=US/ST=Foo/L=Bar/O=Red Hat, Inc./CN=registry host certificate" \ - -addext subjectAltName=DNS:localhost - htpasswd -Bbn ${REGISTRY_USERNAME} ${REGISTRY_PASSWORD} \ - > $AUTHDIR/htpasswd + # Create a local cert (no need to do this more than once) + if [[ ! -e $AUTHDIR/domain.key ]]; then + # FIXME: is there a hidden "--quiet" flag? This is too noisy. + openssl req -newkey rsa:4096 -nodes -sha256 \ + -keyout $AUTHDIR/domain.key -x509 -days 2 \ + -out $AUTHDIR/domain.crt \ + -subj "/C=US/ST=Foo/L=Bar/O=Red Hat, Inc./CN=registry host certificate" \ + -addext subjectAltName=DNS:localhost + fi + + # If invoked with auth=htpasswd, create credentials + REGISTRY_USERNAME= + REGISTRY_PASSWORD= + declare -a registry_auth_params=(-e "REGISTRY_AUTH=$auth") + if [[ "$auth" = "htpasswd" ]]; then + REGISTRY_USERNAME=u$(random_string 7) + REGISTRY_PASSWORD=p$(random_string 7) + + htpasswd -Bbn ${REGISTRY_USERNAME} ${REGISTRY_PASSWORD} \ + > $AUTHDIR/htpasswd + + registry_auth_params+=( + -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" + -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" + ) + fi # Run the registry, and wait for it to come up podman ${PODMAN_REGISTRY_ARGS} run -d \ -p ${REGISTRY_PORT}:5000 \ --name registry \ -v $AUTHDIR:/auth:Z \ - -e "REGISTRY_AUTH=htpasswd" \ - -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ - -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ + "${registry_auth_params[@]}" \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/auth/domain.crt \ -e REGISTRY_HTTP_TLS_KEY=/auth/domain.key \ ${REGISTRY_IMAGE} @@ -462,13 +474,19 @@ function stop_registry() { local REGDIR=${WORKDIR}/registry if [[ -d $REGDIR ]]; then local OPTS="--root ${REGDIR}/root --runroot ${REGDIR}/runroot" - podman $OPTS stop -f -t 0 -a + podman $OPTS stop -i -t 0 registry # rm/rmi are important when running rootless: without them we # get EPERMS in tmpdir cleanup because files are owned by subuids. - podman $OPTS rm -f -a - podman $OPTS rmi -f -a + podman $OPTS rm -f -i registry + if [[ "$1" = "--cleanup" ]]; then + podman $OPTS rmi -f -a + fi fi + + REGISTRY_PORT= + REGISTRY_USERNAME= + REGISTRY_PASSWORD= } ################# diff --git a/test/buildah-bud/apply-podman-deltas b/test/buildah-bud/apply-podman-deltas index 6ff564aaa..50db0255e 100755 --- a/test/buildah-bud/apply-podman-deltas +++ b/test/buildah-bud/apply-podman-deltas @@ -217,6 +217,12 @@ skip_if_remote "--output option not implemented in podman-remote" \ "build with custom build output and output rootfs to tar by pipe" \ "build with custom build output must fail for bad input" +# https://github.com/containers/podman/issues/14544 +skip_if_remote "logfile not implemented on remote" "bud-logfile-with-split-logfile-by-platform" + +# https://github.com/containers/podman/issues/14547 +skip_if_remote "omit-history not implemented on remote" "build-with-omit-history-to-true should not add history" + ############################################################################### # BEGIN tests which are skipped due to actual podman or podman-remote bugs. diff --git a/test/e2e/build_test.go b/test/e2e/build_test.go index 0b766dcc8..9ecc2f8c6 100644 --- a/test/e2e/build_test.go +++ b/test/e2e/build_test.go @@ -555,7 +555,7 @@ subdir**` dd := exec.Command("dd", "if=/dev/random", "of="+randomFile, "bs=1G", "count=1") ddSession, err := Start(dd, GinkgoWriter, GinkgoWriter) Expect(err).ToNot(HaveOccurred()) - Eventually(ddSession).Should(Exit(0)) + Eventually(ddSession, "10s", "1s").Should(Exit(0)) // make cwd as context root path Expect(os.Chdir(contextDir)).ToNot(HaveOccurred()) diff --git a/test/e2e/pod_infra_container_test.go b/test/e2e/pod_infra_container_test.go index ad2db2411..20794a29c 100644 --- a/test/e2e/pod_infra_container_test.go +++ b/test/e2e/pod_infra_container_test.go @@ -130,14 +130,24 @@ var _ = Describe("Podman pod create", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - session = podmanTest.Podman([]string{"run", "-dt", "--pod", session.OutputToString(), ALPINE}) + session = podmanTest.Podman([]string{"run", "--name", "hostCtr", "--pod", session.OutputToString(), ALPINE, "readlink", "/proc/self/ns/net"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - session = podmanTest.Podman([]string{"inspect", "--format", "'{{.NetworkSettings.SandboxKey}}'", session.OutputToString()}) + ns := SystemExec("readlink", []string{"/proc/self/ns/net"}) + ns.WaitWithDefaultTimeout() + Expect(ns).Should(Exit(0)) + netns := ns.OutputToString() + Expect(netns).ToNot(BeEmpty()) + + Expect(session.OutputToString()).To(Equal(netns)) + + // Sanity Check for podman inspect + session = podmanTest.Podman([]string{"inspect", "--format", "'{{.NetworkSettings.SandboxKey}}'", "hostCtr"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - Expect(session.OutputToString()).Should(ContainSubstring("''")) // no network path... host + Expect(session.OutputToString()).Should(Equal("''")) // no network path... host + }) It("podman pod correctly sets up IPCNS", func() { diff --git a/test/system/065-cp.bats b/test/system/065-cp.bats index cfbeff3ae..12c6e1a01 100644 --- a/test/system/065-cp.bats +++ b/test/system/065-cp.bats @@ -949,9 +949,107 @@ ${randomcontent[1]}" "$description" run_podman rm -t 0 -f cpcontainer } +@test "podman cp --overwrite file - ctr/ctr" { + rand_content_file=$(random_string 50) + rand_content_dir=$(random_string 50) + + run_podman run -d --name ctr-file $IMAGE sh -c "echo '$rand_content_file' > /tmp/foo; sleep infinity" + run_podman run -d --name ctr-dir $IMAGE sh -c "mkdir /tmp/foo; echo '$rand_content_dir' > /tmp/foo/file.txt; sleep infinity" + + # overwrite a directory with a file + run_podman 125 cp ctr-file:/tmp/foo ctr-dir:/tmp + if ! is_remote; then # remote just returns a 500 + is "$output" ".* error creating \"/tmp/foo\": .*: file exists.*" + fi + run_podman cp --overwrite ctr-file:/tmp/foo ctr-dir:/tmp + run_podman exec ctr-dir cat /tmp/foo + is "$output" "$rand_content_file" + + # reset the ctr-dir container + run_podman exec ctr-dir sh -c "rm -rf /tmp/foo; mkdir /tmp/foo; echo '$rand_content_dir' > /tmp/foo/file.txt" + + # overwrite a file with a directory + run_podman 125 cp ctr-dir:/tmp/foo ctr-file:/tmp + if ! is_remote; then # remote just returns a 500 + is "$output" ".* error creating \"/tmp/foo\": .*: file exists.*" + fi + run_podman cp --overwrite ctr-dir:/tmp/foo ctr-file:/tmp + run_podman exec ctr-file cat /tmp/foo/file.txt + is "$output" "$rand_content_dir" + + run_podman rm -t 0 -f ctr-file ctr-dir +} + +@test "podman cp --overwrite file - ctr/host" { + hostdir=$PODMAN_TMPDIR/cp-test + mkdir -p $hostdir + + rand_content_file=$(random_string 50) + rand_content_dir=$(random_string 50) + + run_podman run -d --name ctr-file $IMAGE sh -c "echo '$rand_content_file' > /tmp/foo; sleep infinity" + run_podman run -d --name ctr-dir $IMAGE sh -c "mkdir /tmp/foo; echo '$rand_content_dir' > /tmp/foo/file.txt; sleep infinity" + + # overwrite a directory with a file + mkdir $hostdir/foo + run_podman 125 cp ctr-file:/tmp/foo $hostdir + if ! is_remote; then # remote just returns a 500 + is "$output" ".* error creating \"/foo\": .*: file exists.*" + fi + run_podman cp --overwrite ctr-file:/tmp/foo $hostdir + is "$(< $hostdir/foo)" "$rand_content_file" + + # overwrite a file with a directory + rm -rf $hostdir/foo + touch $hostdir/foo + run_podman 125 cp ctr-dir:/tmp/foo $hostdir + if ! is_remote; then # remote just returns a 500 + is "$output" ".* error creating \"/foo\": .*: file exists.*" + fi + run_podman cp --overwrite ctr-dir:/tmp/foo $hostdir + is "$(< $hostdir/foo/file.txt)" "$rand_content_dir" + + run_podman rm -t 0 -f ctr-file ctr-dir +} + +@test "podman cp --overwrite file - host/ctr" { + hostdir=$PODMAN_TMPDIR/cp-test + mkdir -p $hostdir + + rand_content_file=$(random_string 50) + rand_content_dir=$(random_string 50) + + run_podman run -d --name ctr-dir $IMAGE sh -c "mkdir /tmp/foo; sleep infinity" + run_podman run -d --name ctr-file $IMAGE sh -c "touch /tmp/foo; sleep infinity" + + # overwrite a directory with a file + echo "$rand_content_file" > $hostdir/foo + run_podman 125 cp $hostdir/foo ctr-dir:/tmp + if ! is_remote; then # remote just returns a 500 + is "$output" ".* error creating \"/tmp/foo\": .*: file exists.*" + fi + run_podman cp --overwrite $hostdir/foo ctr-dir:/tmp + run_podman exec ctr-dir cat /tmp/foo + is "$output" "$rand_content_file" + + # overwrite a file with a directory + rm -f $hostdir/foo + mkdir $hostdir/foo + echo "$rand_content_dir" > $hostdir/foo/file.txt + run_podman 125 cp $hostdir/foo ctr-file:/tmp + if ! is_remote; then # remote just returns a 500 + is "$output" ".* error creating \"/tmp/foo\": .*: file exists.*" + fi + run_podman cp --overwrite $hostdir/foo ctr-file:/tmp + run_podman exec ctr-file cat /tmp/foo/file.txt + is "$output" "$rand_content_dir" + + run_podman rm -t 0 -f ctr-file ctr-dir +} + function teardown() { # In case any test fails, clean up the container we left behind - run_podman rm -t 0 f cpcontainer + run_podman rm -t 0 -f --ignore cpcontainer basic_teardown } diff --git a/test/system/520-checkpoint.bats b/test/system/520-checkpoint.bats index c16a8c35d..7f60f01b3 100644 --- a/test/system/520-checkpoint.bats +++ b/test/system/520-checkpoint.bats @@ -170,4 +170,34 @@ function teardown() { # FIXME: test --leave-running +@test "podman checkpoint --file-locks" { + action='flock test.lock sh -c "while [ -e /wait ];do sleep 0.5;done;for i in 1 2 3;do echo \$i;sleep 0.5;done"' + run_podman run -d $IMAGE sh -c "touch /wait; touch test.lock; echo READY; $action & $action & wait" + local cid="$output" + + # Wait for container to start emitting output + wait_for_ready $cid + + # Checkpoint, and confirm via inspect + run_podman container checkpoint --file-locks $cid + is "$output" "$cid" "podman container checkpoint" + + run_podman container inspect \ + --format '{{.State.Status}}:{{.State.Running}}:{{.State.Paused}}:{{.State.Checkpointed}}' $cid + is "$output" "exited:false:false:true" "State. Status:Running:Pause:Checkpointed" + + # Restart immediately and confirm state + run_podman container restore --file-locks $cid + is "$output" "$cid" "podman container restore" + + # Signal the container to continue; this is where the 1-2-3s will come from + run_podman exec $cid rm /wait + + # Wait for the container to stop + run_podman wait $cid + + run_podman logs $cid + trim=$(sed -z -e 's/[\r\n]\+//g' <<<"$output") + is "$trim" "READY123123" "File lock restored" +} # vim: filetype=sh diff --git a/test/system/600-completion.bats b/test/system/600-completion.bats index 2de9b1ae1..cb4a2c5f8 100644 --- a/test/system/600-completion.bats +++ b/test/system/600-completion.bats @@ -341,7 +341,9 @@ function _check_no_suggestions() { 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)" + assert "$output" =~ ".*^/etc/\$.*" "etc directory suggested (cmd: podman $cmd)" + assert "$output" =~ ".*^/home/\$.*" "home directory suggested (cmd: podman $cmd)" + assert "$output" =~ ".*^/root/\$.*" "root directory suggested (cmd: podman $cmd)" # check completion for subdirectory run_completion $cmd $IMAGE "/etc" @@ -354,23 +356,31 @@ function _check_no_suggestions() { # 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 ../../)" + assert "$output" =~ ".*^../../etc/\$.*" "relative etc directory suggested (cmd: podman $cmd ../../)" + assert "$output" =~ ".*^../../home/\$.*" "relative home directory 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 + run_podman run --name $random_name $IMAGE sh -c "touch /tmp/$random_file && touch /tmp/${random_file}2 && mkdir /emptydir" # 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" + 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" + run_completion cp "$random_name:/tmp/$random_file" + assert "$output" =~ ".*^$random_name\:/tmp/$random_file\$.*" "podman cp suggest /tmp/$random_file file in container" + assert "$output" =~ ".*^$random_name\:/tmp/${random_file}2\$.*" "podman cp suggest /tmp/${random_file}2 file in container" + + run_completion cp "$random_name:/emptydir" + assert "$output" =~ ".*^$random_name\:/emptydir/\$.*ShellCompDirectiveNoSpace" "podman cp suggest empty dir with no space directive (:2)" + # cleanup container run_podman rm $random_name } |