summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/apiv2/50-secrets.at33
-rw-r--r--test/e2e/build/envwithtab/Dockerfile3
-rw-r--r--test/e2e/checkpoint_test.go6
-rw-r--r--test/e2e/inspect_test.go18
-rw-r--r--test/e2e/play_kube_test.go100
-rw-r--r--test/e2e/search_test.go6
-rw-r--r--test/system/005-info.bats1
-rw-r--r--test/system/035-logs.bats27
-rw-r--r--test/system/070-build.bats27
-rw-r--r--test/system/075-exec.bats28
-rw-r--r--test/system/150-login.bats7
-rw-r--r--test/system/200-pod.bats18
-rw-r--r--test/system/250-systemd.bats23
-rw-r--r--test/system/255-auto-update.bats6
-rw-r--r--test/system/271-tcp-cors-server.bats4
-rw-r--r--test/system/500-networking.bats12
-rw-r--r--test/system/700-play.bats10
-rw-r--r--test/system/helpers.bash19
-rwxr-xr-xtest/system/helpers.t10
-rw-r--r--test/testvol/main.go4
-rw-r--r--test/upgrade/helpers.bash8
-rw-r--r--test/upgrade/test-upgrade.bats62
22 files changed, 373 insertions, 59 deletions
diff --git a/test/apiv2/50-secrets.at b/test/apiv2/50-secrets.at
index 034ec080a..ed0e8fb6b 100644
--- a/test/apiv2/50-secrets.at
+++ b/test/apiv2/50-secrets.at
@@ -27,8 +27,37 @@ t GET secrets 200 \
.[0].Spec.Name=mysecret \
.[0].Version.Index=1
-# secret list unsupported filters
-t GET secrets?filters='{"name":["foo1"]}' 400
+# secret list with filters
+t GET secrets?filters='{"name":["mysecret"]}' 200 \
+ length=1 \
+ .[0].Spec.Name=mysecret \
+ .[0].Version.Index=1
+
+t GET secrets?filters='{"name":["mysecret2"]}' 200 \
+ length=0 \
+
+# secret libpod list with filters
+t GET libpod/secrets/json?filters='{"name":["mysecret"]}' 200 \
+ length=1 \
+ .[0].Spec.Name=mysecret \
+
+t GET libpod/secrets/json?filters='{"name":["mysecret2"]}' 200 \
+ length=0 \
+
+# secret list with unsupported filters
+t GET secrets?filters='{"label":["xyz"]}' 500
+
+#compat api list secrets sanity checks
+t GET secrets?filters='garb1age}' 500 \
+ .cause="invalid character 'g' looking for beginning of value"
+t GET secrets?filters='{"label":["testl' 500 \
+ .cause="unexpected end of JSON input"
+
+#libpod api list secrets sanity checks
+t GET libpod/secrets/json?filters='garb1age}' 500 \
+ .cause="invalid character 'g' looking for beginning of value"
+t GET libpod/secrets/json?filters='{"label":["testl' 500 \
+ .cause="unexpected end of JSON input"
# secret rm
t DELETE secrets/mysecret 204
diff --git a/test/e2e/build/envwithtab/Dockerfile b/test/e2e/build/envwithtab/Dockerfile
new file mode 100644
index 000000000..0d8480c04
--- /dev/null
+++ b/test/e2e/build/envwithtab/Dockerfile
@@ -0,0 +1,3 @@
+FROM alpine
+
+ENV TEST=" t"
diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go
index 1c9a8dc6f..403d739f0 100644
--- a/test/e2e/checkpoint_test.go
+++ b/test/e2e/checkpoint_test.go
@@ -93,6 +93,12 @@ var _ = Describe("Podman checkpoint", func() {
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited"))
+ inspect := podmanTest.Podman([]string{"inspect", cid})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect).Should(Exit(0))
+ inspectOut := inspect.InspectContainerToJSON()
+ Expect(inspectOut[0].State.Checkpointed).To(BeTrue())
+
result = podmanTest.Podman([]string{"container", "restore", cid})
result.WaitWithDefaultTimeout()
diff --git a/test/e2e/inspect_test.go b/test/e2e/inspect_test.go
index 89859e74f..59615d009 100644
--- a/test/e2e/inspect_test.go
+++ b/test/e2e/inspect_test.go
@@ -50,6 +50,24 @@ var _ = Describe("Podman inspect", func() {
Expect(session).To(ExitWithError())
})
+ It("podman inspect filter should work if result contains tab", func() {
+ session := podmanTest.Podman([]string{"build", "--tag", "envwithtab", "build/envwithtab"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ // Verify that OS and Arch are being set
+ inspect := podmanTest.Podman([]string{"inspect", "-f", "{{ .Config.Env }}", "envwithtab"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect).Should(Exit(0))
+ // output should not be empty
+ // test validates fix for https://github.com/containers/podman/issues/8785
+ Expect(strings.Contains(inspect.OutputToString(), "TEST"))
+
+ session = podmanTest.Podman([]string{"rmi", "envwithtab"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ })
+
It("podman inspect with GO format", func() {
session := podmanTest.Podman([]string{"inspect", "--format", "{{.ID}}", ALPINE})
session.WaitWithDefaultTimeout()
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index ab496f0eb..fa30f068c 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -11,6 +11,7 @@ import (
"text/template"
"time"
+ "github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/pkg/util"
. "github.com/containers/podman/v3/test/utils"
"github.com/containers/storage/pkg/stringid"
@@ -30,6 +31,22 @@ metadata:
spec:
hostname: unknown
`
+var checkInfraImagePodYaml = `
+apiVersion: v1
+kind: Pod
+metadata:
+ labels:
+ app: check-infra-image
+ name: check-infra-image
+spec:
+ containers:
+ - name: alpine
+ image: quay.io/libpod/alpine:latest
+ command:
+ - sleep
+ - 24h
+status: {}
+`
var sharedNamespacePodYaml = `
apiVersion: v1
kind: Pod
@@ -1098,6 +1115,55 @@ var _ = Describe("Podman play kube", func() {
Expect(label).To(ContainSubstring("unconfined_u:system_r:spc_t:s0"))
})
+ It("podman play kube should use default infra_image", func() {
+ err := writeYaml(checkInfraImagePodYaml, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube).Should(Exit(0))
+
+ podInspect := podmanTest.Podman([]string{"inspect", "check-infra-image", "--format", "{{ .InfraContainerID }}"})
+ podInspect.WaitWithDefaultTimeout()
+ infraContainerID := podInspect.OutputToString()
+
+ conInspect := podmanTest.Podman([]string{"inspect", infraContainerID, "--format", "{{ .ImageName }}"})
+ conInspect.WaitWithDefaultTimeout()
+ infraContainerImage := conInspect.OutputToString()
+ Expect(infraContainerImage).To(Equal(config.DefaultInfraImage))
+ })
+
+ It("podman play kube should use customized infra_image", func() {
+ conffile := filepath.Join(podmanTest.TempDir, "container.conf")
+
+ infraImage := "k8s.gcr.io/pause:3.2"
+ err := ioutil.WriteFile(conffile, []byte(fmt.Sprintf("[engine]\ninfra_image=\"%s\"\n", infraImage)), 0644)
+ Expect(err).To(BeNil())
+
+ os.Setenv("CONTAINERS_CONF", conffile)
+ defer os.Unsetenv("CONTAINERS_CONF")
+
+ if IsRemote() {
+ podmanTest.RestartRemoteService()
+ }
+
+ err = writeYaml(checkInfraImagePodYaml, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube).Should(Exit(0))
+
+ podInspect := podmanTest.Podman([]string{"inspect", "check-infra-image", "--format", "{{ .InfraContainerID }}"})
+ podInspect.WaitWithDefaultTimeout()
+ infraContainerID := podInspect.OutputToString()
+
+ conInspect := podmanTest.Podman([]string{"inspect", infraContainerID, "--format", "{{ .ImageName }}"})
+ conInspect.WaitWithDefaultTimeout()
+ infraContainerImage := conInspect.OutputToString()
+ Expect(infraContainerImage).To(Equal(infraImage))
+ })
+
It("podman play kube should share ipc,net,uts when shareProcessNamespace is set", func() {
SkipIfRootless("Requires root privileges for sharing few namespaces")
err := writeYaml(sharedNamespacePodYaml, kubeYaml)
@@ -1289,6 +1355,40 @@ var _ = Describe("Podman play kube", func() {
Expect(logs.OutputToString()).To(ContainSubstring("hello world"))
})
+ It("podman pod logs test", func() {
+ SkipIfRemote("podman-remote pod logs -c is mandatory for remote machine")
+ p := getPod(withCtr(getCtr(withCmd([]string{"echo", "hello"}), withArg([]string{"world"}))))
+
+ err := generateKubeYaml("pod", p, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube).Should(Exit(0))
+
+ logs := podmanTest.Podman([]string{"pod", "logs", p.Name})
+ logs.WaitWithDefaultTimeout()
+ Expect(logs).Should(Exit(0))
+ Expect(logs.OutputToString()).To(ContainSubstring("hello world"))
+ })
+
+ It("podman-remote pod logs test", func() {
+ // -c or --container is required in podman-remote due to api limitation.
+ p := getPod(withCtr(getCtr(withCmd([]string{"echo", "hello"}), withArg([]string{"world"}))))
+
+ err := generateKubeYaml("pod", p, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube).Should(Exit(0))
+
+ logs := podmanTest.Podman([]string{"pod", "logs", "-c", getCtrNameInPod(p), p.Name})
+ logs.WaitWithDefaultTimeout()
+ Expect(logs).Should(Exit(0))
+ Expect(logs.OutputToString()).To(ContainSubstring("hello world"))
+ })
+
It("podman play kube test restartPolicy", func() {
// podName, set, expect
testSli := [][]string{
diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go
index b0faabf6c..f82c3d9d1 100644
--- a/test/e2e/search_test.go
+++ b/test/e2e/search_test.go
@@ -148,7 +148,7 @@ registries = ['{{.Host}}:{{.Port}}']`
search := podmanTest.Podman([]string{"search", "docker.io/alpine"})
search.WaitWithDefaultTimeout()
Expect(search).Should(Exit(0))
- Expect(len(search.OutputToStringArray())).To(Equal(26))
+ Expect(len(search.OutputToStringArray())).To(BeNumerically(">", 10))
search = podmanTest.Podman([]string{"search", "--limit", "3", "docker.io/alpine"})
search.WaitWithDefaultTimeout()
@@ -462,7 +462,7 @@ registries = ['{{.Host}}:{{.Port}}']`
search = podmanTest.Podman([]string{"search", "--list-tags", "docker.io/library/alpine"})
search.WaitWithDefaultTimeout()
Expect(search).Should(Exit(0))
- Expect(len(search.OutputToStringArray()) > 2).To(BeTrue())
+ Expect(len(search.OutputToStringArray())).To(BeNumerically(">", 2))
search = podmanTest.Podman([]string{"search", "--filter=is-official", "--list-tags", "docker.io/library/alpine"})
search.WaitWithDefaultTimeout()
@@ -477,6 +477,6 @@ registries = ['{{.Host}}:{{.Port}}']`
search := podmanTest.Podman([]string{"search", "--limit", "130", "registry.redhat.io/rhel"})
search.WaitWithDefaultTimeout()
Expect(search).Should(Exit(0))
- Expect(len(search.OutputToStringArray())).To(Equal(131))
+ Expect(len(search.OutputToStringArray())).To(BeNumerically("<=", 131))
})
})
diff --git a/test/system/005-info.bats b/test/system/005-info.bats
index 96ca2c1bd..0ea0f8356 100644
--- a/test/system/005-info.bats
+++ b/test/system/005-info.bats
@@ -9,6 +9,7 @@ load helpers
buildahVersion: *[0-9.]\\\+
conmon:\\\s\\\+package:
distribution:
+logDriver:
ociRuntime:\\\s\\\+name:
os:
rootless:
diff --git a/test/system/035-logs.bats b/test/system/035-logs.bats
index 32282c8e1..a04d2ac74 100644
--- a/test/system/035-logs.bats
+++ b/test/system/035-logs.bats
@@ -174,4 +174,31 @@ $s_after"
_log_test_until journald
}
+function _log_test_follow() {
+ local driver=$1
+ cname=$(random_string)
+ contentA=$(random_string)
+ contentB=$(random_string)
+ contentC=$(random_string)
+
+ # Note: it seems we need at least three log lines to hit #11461.
+ run_podman run --log-driver=$driver --name $cname $IMAGE sh -c "echo $contentA; echo $contentB; echo $contentC"
+ run_podman logs -f $cname
+ is "$output" "$contentA
+$contentB
+$contentC" "logs -f on exitted container works"
+
+ run_podman rm -f $cname
+}
+
+@test "podman logs - --follow k8s-file" {
+ _log_test_follow k8s-file
+}
+
+@test "podman logs - --follow journald" {
+ # We can't use journald on RHEL as rootless: rhbz#1895105
+ skip_if_journald_unavailable
+
+ _log_test_follow journald
+}
# vim: filetype=sh
diff --git a/test/system/070-build.bats b/test/system/070-build.bats
index 0f58b2784..47db08eb1 100644
--- a/test/system/070-build.bats
+++ b/test/system/070-build.bats
@@ -929,6 +929,33 @@ EOF
is "$output" ".*test1" "test1 should exists in the final image"
}
+@test "podman build build context ownership" {
+ tmpdir=$PODMAN_TMPDIR/build-test
+ subdir=$tmpdir/subdir
+ mkdir -p $subdir
+
+ touch $tmpdir/empty-file.txt
+ if is_remote && ! is_rootless ; then
+ # TODO: set this file's owner to a UID:GID that will not be mapped
+ # in the context where the remote server is running, which generally
+ # requires us to be root (or running with more mapped IDs) on the
+ # client, but not root (or running with fewer mapped IDs) on the
+ # remote server
+ # 4294967292:4294967292 (0xfffffffc:0xfffffffc) isn't that, but
+ # it will catch errors where a remote server doesn't apply the right
+ # default as it copies content into the container
+ chown 4294967292:4294967292 $tmpdir/empty-file.txt
+ fi
+ cat >$tmpdir/Dockerfile <<EOF
+FROM $IMAGE
+COPY empty-file.txt .
+RUN echo 0:0 | tee expected.txt
+RUN stat -c "%u:%g" empty-file.txt | tee actual.txt
+RUN cmp expected.txt actual.txt
+EOF
+ run_podman build -t build_test $tmpdir
+}
+
function teardown() {
# A timeout or other error in 'build' can leave behind stale images
# that podman can't even see and which will cascade into subsequent
diff --git a/test/system/075-exec.bats b/test/system/075-exec.bats
index 3e8c3c1ea..b7367d153 100644
--- a/test/system/075-exec.bats
+++ b/test/system/075-exec.bats
@@ -101,4 +101,32 @@ load helpers
run_podman rm $cid
}
+# #11496: podman-remote loses output
+@test "podman exec/run - missing output" {
+ local bigfile=${PODMAN_TMPDIR}/bigfile
+ local newfile=${PODMAN_TMPDIR}/newfile
+ # create a big file, bigger than the 8K buffer size
+ base64 /dev/urandom | head -c 20K > $bigfile
+
+ run_podman run --rm -v $bigfile:/tmp/test:Z $IMAGE cat /tmp/test
+ printf "%s" "$output" > $newfile
+ # use cmp to compare the files, this is very helpful since it will
+ # tell us the first wrong byte in case this fails
+ run cmp $bigfile $newfile
+ is "$output" "" "run output is identical with the file"
+
+ run_podman run -d --stop-timeout 0 -v $bigfile:/tmp/test:Z $IMAGE sleep inf
+ cid="$output"
+
+ run_podman exec $cid cat /tmp/test
+ printf "%s" "$output" > $newfile
+ # use cmp to compare the files, this is very helpful since it will
+ # tell us the first wrong byte in case this fails
+ run cmp $bigfile $newfile
+ is "$output" "" "exec output is identical with the file"
+
+ # Clean up
+ run_podman rm -f $cid
+}
+
# vim: filetype=sh
diff --git a/test/system/150-login.bats b/test/system/150-login.bats
index b6c04db08..ed925044c 100644
--- a/test/system/150-login.bats
+++ b/test/system/150-login.bats
@@ -22,12 +22,7 @@ fi
# Randomly-assigned port in the 5xxx range
if [ -z "${PODMAN_LOGIN_REGISTRY_PORT}" ]; then
- for port in $(shuf -i 5000-5999);do
- if ! { exec 3<> /dev/tcp/127.0.0.1/$port; } &>/dev/null; then
- export PODMAN_LOGIN_REGISTRY_PORT=$port
- break
- fi
- done
+ export PODMAN_LOGIN_REGISTRY_PORT=$(random_free_port)
fi
# Override any user-set path to an auth file
diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats
index 266f91298..027abf9dc 100644
--- a/test/system/200-pod.bats
+++ b/test/system/200-pod.bats
@@ -76,11 +76,7 @@ function teardown() {
fi
# Randomly-assigned port in the 5xxx range
- for port in $(shuf -i 5000-5999);do
- if ! { exec 3<> /dev/tcp/127.0.0.1/$port; } &>/dev/null; then
- break
- fi
- done
+ port=$(random_free_port)
# Listener. This will exit as soon as it receives a message.
run_podman run -d --pod $podname $IMAGE nc -l -p $port
@@ -183,16 +179,8 @@ function random_ip() {
pod_id_file=${PODMAN_TMPDIR}/pod-id-file
# Randomly-assigned ports in the 5xxx and 6xxx range
- for port_in in $(shuf -i 5000-5999);do
- if ! { exec 3<> /dev/tcp/127.0.0.1/$port_in; } &>/dev/null; then
- break
- fi
- done
- for port_out in $(shuf -i 6000-6999);do
- if ! { exec 3<> /dev/tcp/127.0.0.1/$port_out; } &>/dev/null; then
- break
- fi
- done
+ port_in=$(random_free_port 5000-5999)
+ port_out=$(random_free_port 6000-6999)
# Create a pod with all the desired options
# FIXME: --ip=$ip fails:
diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats
index 08fad5e7c..4578d9e60 100644
--- a/test/system/250-systemd.bats
+++ b/test/system/250-systemd.bats
@@ -136,6 +136,29 @@ function service_cleanup() {
service_cleanup
}
+# Regression test for #11438
+@test "podman generate systemd - restart policy" {
+ cname=$(random_string)
+ run_podman create --restart=always --name $cname $IMAGE
+ run_podman generate systemd --new $cname
+ is "$output" ".*Restart=always.*" "Use container's restart policy if set"
+ run_podman generate systemd --new --restart-policy=on-failure $cname
+ is "$output" ".*Restart=on-failure.*" "Override container's restart policy"
+
+ cname2=$(random_string)
+ run_podman create --restart=unless-stopped --name $cname2 $IMAGE
+ run_podman generate systemd --new $cname2
+ is "$output" ".*Restart=always.*" "unless-stopped translated to always"
+
+ cname3=$(random_string)
+ run_podman create --restart=on-failure:42 --name $cname3 $IMAGE
+ run_podman generate systemd --new $cname3
+ is "$output" ".*Restart=on-failure.*" "on-failure:xx is parsed correclty"
+ is "$output" ".*StartLimitBurst=42.*" "on-failure:xx is parsed correctly"
+
+ run_podman rm -f $cname $cname2 $cname3
+}
+
function set_listen_env() {
export LISTEN_PID="100" LISTEN_FDS="1" LISTEN_FDNAMES="listen_fdnames"
}
diff --git a/test/system/255-auto-update.bats b/test/system/255-auto-update.bats
index b172bb917..bb4b5c13f 100644
--- a/test/system/255-auto-update.bats
+++ b/test/system/255-auto-update.bats
@@ -339,6 +339,8 @@ EOF
}
@test "podman auto-update using systemd" {
+ skip_if_journald_unavailable
+
generate_service alpine image
cat >$UNIT_DIR/podman-auto-update-$cname.timer <<EOF
@@ -386,7 +388,9 @@ EOF
done
if [[ -n "$failed_start" ]]; then
- die "Did not find expected string '$expect' in journalctl output for $cname"
+ echo "journalctl output:"
+ sed -e 's/^/ /' <<<"$output"
+ die "Did not find expected string '$expect' in journalctl output for $cname"
fi
_confirm_update $cname $ori_image
diff --git a/test/system/271-tcp-cors-server.bats b/test/system/271-tcp-cors-server.bats
index cdfa82e82..d8e4eb3df 100644
--- a/test/system/271-tcp-cors-server.bats
+++ b/test/system/271-tcp-cors-server.bats
@@ -14,7 +14,7 @@ SOCKET_FILE="$UNIT_DIR/$SERVICE_NAME.socket"
@test "podman system service - tcp CORS" {
skip_if_remote "system service tests are meaningless over remote"
- PORT=$(( ((RANDOM<<15)|RANDOM) % 63001 + 2000 ))
+ PORT=$(random_free_port 63000-64999)
run_podman system service --cors="*" tcp:$SERVICE_TCP_HOST:$PORT -t 20 &
podman_pid="$!"
sleep 5s
@@ -26,7 +26,7 @@ SOCKET_FILE="$UNIT_DIR/$SERVICE_NAME.socket"
@test "podman system service - tcp without CORS" {
skip_if_remote "system service tests are meaningless over remote"
- PORT=$(( ((RANDOM<<15)|RANDOM) % 63001 + 2000 ))
+ PORT=$(random_free_port 63000-64999)
run_podman system service tcp:$SERVICE_TCP_HOST:$PORT -t 20 &
podman_pid="$!"
sleep 5s
diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats
index 3ebe45e63..ad5891dd9 100644
--- a/test/system/500-networking.bats
+++ b/test/system/500-networking.bats
@@ -23,7 +23,7 @@ load helpers
random_1=$(random_string 30)
random_2=$(random_string 30)
- HOST_PORT=8080
+ HOST_PORT=$(random_free_port)
SERVER=http://127.0.0.1:$HOST_PORT
# Create a test file with random content
@@ -114,11 +114,8 @@ load helpers
# Issue #5466 - port-forwarding doesn't work with this option and -d
@test "podman networking: port with --userns=keep-id" {
- # FIXME: randomize port, and create second random host port
- myport=54321
-
for cidr in "" "$(random_rfc1918_subnet).0/24"; do
- myport=$(( myport + 1 ))
+ myport=$(random_free_port 52000-52999)
if [[ -z $cidr ]]; then
# regex to match that we are in 10.X subnet
match="10\..*"
@@ -188,6 +185,7 @@ load helpers
# "network create" now works rootless, with the help of a special container
@test "podman network create" {
+ # Deliberately use a fixed port, not random_open_port, because of #10806
myport=54322
local mynetname=testnet-$(random_string 10)
@@ -244,7 +242,7 @@ load helpers
skip_if_remote "podman network reload does not have remote support"
random_1=$(random_string 30)
- HOST_PORT=12345
+ HOST_PORT=$(random_free_port)
SERVER=http://127.0.0.1:$HOST_PORT
# Create a test file with random content
@@ -396,7 +394,7 @@ load helpers
# Test for https://github.com/containers/podman/issues/10052
@test "podman network connect/disconnect with port forwarding" {
random_1=$(random_string 30)
- HOST_PORT=12345
+ HOST_PORT=$(random_free_port)
SERVER=http://127.0.0.1:$HOST_PORT
# Create a test file with random content
diff --git a/test/system/700-play.bats b/test/system/700-play.bats
index 7f35877aa..2b05cdd84 100644
--- a/test/system/700-play.bats
+++ b/test/system/700-play.bats
@@ -98,6 +98,16 @@ RELABEL="system_u:object_r:container_file_t:s0"
run_podman 125 play kube --network host $PODMAN_TMPDIR/test.yaml
is "$output" ".*invalid value passed to --network: bridge or host networking must be configured in YAML" "podman plan-network should fail with --network host"
run_podman play kube --network slirp4netns:port_handler=slirp4netns $PODMAN_TMPDIR/test.yaml
+ run_podman pod inspect --format {{.InfraContainerID}} "${lines[1]}"
+ infraID="$output"
+ run_podman container inspect --format "{{.HostConfig.NetworkMode}}" $infraID
+ is "$output" "slirp4netns" "network mode slirp4netns is set for the container"
+ run_podman pod rm -f test_pod
+ run_podman play kube --network none $PODMAN_TMPDIR/test.yaml
+ run_podman pod inspect --format {{.InfraContainerID}} "${lines[1]}"
+ infraID="$output"
+ run_podman container inspect --format "{{.HostConfig.NetworkMode}}" $infraID
+ is "$output" "none" "network mode none is set for the container"
run_podman pod rm -f test_pod
}
diff --git a/test/system/helpers.bash b/test/system/helpers.bash
index bd9471ace..28ea924bb 100644
--- a/test/system/helpers.bash
+++ b/test/system/helpers.bash
@@ -278,6 +278,23 @@ function wait_for_ready {
wait_for_output 'READY' "$@"
}
+######################
+# random_free_port # Pick an available port within a specified range
+######################
+function random_free_port() {
+ local range=${1:-5000-5999}
+
+ local port
+ for port in $(shuf -i ${range}); do
+ if ! { exec {unused_fd}<> /dev/tcp/127.0.0.1/$port; } &>/dev/null; then
+ echo $port
+ return
+ fi
+ done
+
+ die "Could not find open port in range $range"
+}
+
###################
# wait_for_port # Returns once port is available on host
###################
@@ -288,7 +305,7 @@ function wait_for_port() {
# Wait
while [ $_timeout -gt 0 ]; do
- { exec 5<> /dev/tcp/$host/$port; } &>/dev/null && return
+ { exec {unused_fd}<> /dev/tcp/$host/$port; } &>/dev/null && return
sleep 1
_timeout=$(( $_timeout - 1 ))
done
diff --git a/test/system/helpers.t b/test/system/helpers.t
index 190e8ba35..b83d9a89b 100755
--- a/test/system/helpers.t
+++ b/test/system/helpers.t
@@ -213,8 +213,16 @@ declare -a lines=(
)
check_same_dev "zero-line output"
-
# END remove_same_dev_warning
###############################################################################
+# BEGIN random_free_port
+
+# Assumes that 16700 is open
+found=$(random_free_port 16700-16700)
+
+check_result "$found" "16700" "random_free_port"
+
+# END random_free_port
+###############################################################################
exit $rc
diff --git a/test/testvol/main.go b/test/testvol/main.go
index 14f253aa7..721f47bcd 100644
--- a/test/testvol/main.go
+++ b/test/testvol/main.go
@@ -224,13 +224,13 @@ func (d *DirDriver) Remove(req *volume.RemoveRequest) error {
vol, exists := d.volumes[req.Name]
if !exists {
logrus.Debugf("Did not find volume %s", req.Name)
- return errors.Errorf("no volume with name %s found")
+ return errors.Errorf("no volume with name %s found", req.Name)
}
logrus.Debugf("Found volume %s", req.Name)
if len(vol.mounts) > 0 {
logrus.Debugf("Cannot remove %s, is mounted", req.Name)
- return errors.Errorf("volume %s is mounted and cannot be removed")
+ return errors.Errorf("volume %s is mounted and cannot be removed", req.Name)
}
delete(d.volumes, req.Name)
diff --git a/test/upgrade/helpers.bash b/test/upgrade/helpers.bash
index 41d9279e6..16fedb053 100644
--- a/test/upgrade/helpers.bash
+++ b/test/upgrade/helpers.bash
@@ -9,3 +9,11 @@ setup() {
teardown() {
:
}
+
+# skip a test when the given version is older than the currently tested one
+skip_if_version_older() {
+ # use ${PODMAN_UPGRADE_FROM##v} to trim the leading "v"
+ if printf '%s\n%s\n' "${PODMAN_UPGRADE_FROM##v}" "$1" | sort --check=quiet --version-sort; then
+ skip "${2-test is only meaningful when upgrading from $1 or later}"
+ fi
+}
diff --git a/test/upgrade/test-upgrade.bats b/test/upgrade/test-upgrade.bats
index ca478e263..5cb302a85 100644
--- a/test/upgrade/test-upgrade.bats
+++ b/test/upgrade/test-upgrade.bats
@@ -21,9 +21,7 @@ if [ -z "${RANDOM_STRING_1}" ]; then
export LABEL_CREATED=$(random_string 16)
export LABEL_FAILED=$(random_string 17)
export LABEL_RUNNING=$(random_string 18)
-
- # FIXME: randomize this
- HOST_PORT=34567
+ export HOST_PORT=$(random_free_port)
fi
# Version string of the podman we're actually testing, e.g. '3.0.0-dev-d1a26013'
@@ -44,7 +42,8 @@ setup() {
false
fi
- export _PODMAN_TEST_OPTS="--root=$PODMAN_UPGRADE_WORKDIR/root --runroot=$PODMAN_UPGRADE_WORKDIR/runroot --tmpdir=$PODMAN_UPGRADE_WORKDIR/tmp"
+ # cgroup-manager=systemd does not work inside a container
+ export _PODMAN_TEST_OPTS="--cgroup-manager=cgroupfs --root=$PODMAN_UPGRADE_WORKDIR/root --runroot=$PODMAN_UPGRADE_WORKDIR/runroot --tmpdir=$PODMAN_UPGRADE_WORKDIR/tmp"
}
###############################################################################
@@ -76,8 +75,8 @@ setup() {
cat >| $pmscript <<EOF
#!/bin/bash
-# cgroup-manager=systemd does not work inside a container
-opts="--cgroup-manager=cgroupfs --events-backend=file $_PODMAN_TEST_OPTS"
+# events-backend=journald does not work inside a container
+opts="--events-backend=file $_PODMAN_TEST_OPTS"
set -ex
@@ -95,22 +94,17 @@ podman \$opts run --name mydonecontainer $IMAGE echo ++$RANDOM_STRING_1++
podman \$opts run --name myfailedcontainer --label mylabel=$LABEL_FAILED \
$IMAGE sh -c 'exit 17' || true
-# FIXME: add "-p $HOST_PORT:80"
-# ...I tried and tried, and could not get this to work. I could never
-# connect to the port from the host, nor even from the podman_parent
-# container; I could never see the port listed in 'ps' nor 'inspect'.
-# And, finally, I ended up in a state where the container wouldn't
-# even start, and via complicated 'podman logs' found out:
-# httpd: bind: Address in use
-# So I just give up for now.
-#
podman \$opts run -d --name myrunningcontainer --label mylabel=$LABEL_RUNNING \
+ --network bridge \
+ -p $HOST_PORT:80 \
-v $pmroot/var/www:/var/www \
-w /var/www \
$IMAGE /bin/busybox-extras httpd -f -p 80
podman \$opts pod create --name mypod
+podman \$opts network create mynetwork
+
echo READY
while :;do
if [ -e /stop ]; then
@@ -140,6 +134,7 @@ EOF
#
# mount /etc/containers/storage.conf to use the same storage settings as on the host
# mount /dev/shm because the container locks are stored there
+ # mount /var/lib/cni and /etc/cni/net.d for cni networking
#
$PODMAN run -d --name podman_parent --pid=host \
--privileged \
@@ -149,6 +144,9 @@ EOF
-v /etc/containers/storage.conf:/etc/containers/storage.conf \
-v /dev/fuse:/dev/fuse \
-v /run/crun:/run/crun \
+ -v /run/netns:/run/netns:rshared \
+ -v /var/lib/cni:/var/lib/cni \
+ -v /etc/cni/net.d:/etc/cni/net.d \
-v /dev/shm:/dev/shm \
-v $pmroot:$pmroot \
$OLD_PODMAN $pmroot/setup
@@ -187,7 +185,7 @@ EOF
is "${lines[1]}" "mycreatedcontainer--Created----$LABEL_CREATED" "created"
is "${lines[2]}" "mydonecontainer--Exited (0).*----<no value>" "done"
is "${lines[3]}" "myfailedcontainer--Exited (17) .*----$LABEL_FAILED" "fail"
- is "${lines[4]}" "myrunningcontainer--Up .*----$LABEL_RUNNING" "running"
+ is "${lines[4]}" "myrunningcontainer--Up .*--0.0.0.0:$HOST_PORT->80/tcp--$LABEL_RUNNING" "running"
# For debugging: dump containers and IDs
if [[ -n "$PODMAN_UPGRADE_TEST_DEBUG" ]]; then
@@ -212,6 +210,30 @@ failed | exited | 17
done < <(parse_table "$tests")
}
+@test "network - curl" {
+ run curl --max-time 3 -s 127.0.0.1:$HOST_PORT/index.txt
+ is "$output" "$RANDOM_STRING_1" "curl on running container"
+}
+
+# IMPORTANT: connect should happen before restart, we want to check
+# if we can connect on an existing running container
+@test "network - connect" {
+ skip_if_version_older 2.2.0
+ run_podman network connect mynetwork myrunningcontainer
+ run_podman network disconnect podman myrunningcontainer
+ run curl --max-time 3 -s 127.0.0.1:$HOST_PORT/index.txt
+ is "$output" "$RANDOM_STRING_1" "curl on container with second network connected"
+}
+
+@test "network - restart" {
+ # restart the container and check if we can still use the port
+ run_podman stop -t0 myrunningcontainer
+ run_podman start myrunningcontainer
+ run curl --max-time 3 -s 127.0.0.1:$HOST_PORT/index.txt
+ is "$output" "$RANDOM_STRING_1" "curl on restarted container"
+}
+
+
@test "logs" {
run_podman logs mydonecontainer
is "$output" "++$RANDOM_STRING_1++" "podman logs on stopped container"
@@ -235,7 +257,7 @@ failed | exited | 17
run_podman pod inspect mypod
is "$output" ".*mypod.*"
- run_podman --cgroup-manager=cgroupfs pod start mypod
+ run_podman pod start mypod
is "$output" "[0-9a-f]\\{64\\}" "podman pod start"
run_podman pod ps
@@ -245,7 +267,7 @@ failed | exited | 17
run_podman pod stop mypod
is "$output" "[0-9a-f]\\{64\\}" "podman pod stop"
- run_podman --cgroup-manager=cgroupfs pod rm mypod
+ run_podman pod rm mypod
# FIXME: CI runs show this (non fatal) error:
# Error updating pod <ID> conmon cgroup PID limit: open /sys/fs/cgroup/libpod_parent/<ID>/conmon/pids.max: no such file or directory
# Investigate how to fix this (likely a race condition)
@@ -257,7 +279,7 @@ failed | exited | 17
@test "start" {
- run_podman --cgroup-manager=cgroupfs start -a mydonecontainer
+ run_podman start -a mydonecontainer
is "$output" "++$RANDOM_STRING_1++" "start on already-run container"
}
@@ -295,6 +317,8 @@ failed | exited | 17
run_podman logs podman_parent
run_podman rm -f podman_parent
+ run_podman network rm -f mynetwork
+
umount $PODMAN_UPGRADE_WORKDIR/root/overlay || true
rm -rf $PODMAN_UPGRADE_WORKDIR