mirror of
https://github.com/containers/podman.git
synced 2025-10-17 19:24:04 +08:00

The distro-integration tag was added for fedora openQA to only run a subset of tests. However since it was added only a few new tests have been labelled like that and in general a normal contributor or even maintianer has no idea when to add this tag. We also have been seeing several regressions getting into fedora that these tests would have caught. As such I worked with Adam to enable all tests for fedora openQA so we actually have proper coverage. This has been working for a few weeks so I think we can dop these tags so upstream does not need to bother with them at all. https://pagure.io/fedora-qa/os-autoinst-distri-fedora/issue/373 Signed-off-by: Paul Holzinger <pholzing@redhat.com>
352 lines
12 KiB
Bash
352 lines
12 KiB
Bash
#!/usr/bin/env bats -*- bats -*-
|
|
#
|
|
# Tests for podman update
|
|
#
|
|
|
|
load helpers
|
|
|
|
LOOPDEVICE=
|
|
|
|
function teardown() {
|
|
if [[ -n "$LOOPDEVICE" ]]; then
|
|
losetup -d $LOOPDEVICE
|
|
LOOPDEVICE=
|
|
fi
|
|
basic_teardown
|
|
}
|
|
|
|
|
|
@test "podman update - test all options" {
|
|
local cgv=1
|
|
if is_cgroupsv2; then
|
|
cgv=2;
|
|
fi
|
|
|
|
# Need a block device for blkio-weight-device testing
|
|
local pass_loop_device=
|
|
if ! is_rootless; then
|
|
if is_cgroupsv2; then
|
|
lofile=${PODMAN_TMPDIR}/disk.img
|
|
fallocate -l 1k ${lofile}
|
|
LOOPDEVICE=$(losetup --show -f $lofile)
|
|
pass_loop_device="--device $LOOPDEVICE"
|
|
|
|
# Get maj:min (tr needed because losetup seems to use %2d)
|
|
lomajmin=$(losetup -l --noheadings --output MAJ:MIN $LOOPDEVICE | tr -d ' ')
|
|
fi
|
|
fi
|
|
|
|
# Shortcuts to make the table narrower
|
|
local -a gig=(0 1073741824 2147483648 3221225472)
|
|
local devicemax="1:5 rbps=10485760 wbps=31457280 riops=2000 wiops=4000"
|
|
local mm=memory/memory
|
|
|
|
# Format:
|
|
# --<option> = <value> | rootless? | check: cgroups v1 | check: cgroups v2
|
|
#
|
|
# Requires very wide window to read. Sorry.
|
|
#
|
|
# FIXMEs:
|
|
# cpu-rt-period (cgv1 only, on cpu/cpu.rt_period_us) works on RHEL8 but not on Ubuntu
|
|
# cpu-rt-runtime (cgv1 only, on cpu/cpu.rt_runtime_us) fails: error setting cgroup config for procHooks ...
|
|
tests="
|
|
cpu-shares = 512 | - | cpu/cpu.shares = 512 | cpu.weight = 20
|
|
cpus = 5 | - | cpu/cpu.cfs_quota_us = 500000 | cpu.max = 500000 100000
|
|
cpuset-cpus = 0 | - | cpuset/cpuset.cpus = 0 | cpuset.cpus = 0
|
|
cpuset-mems = 0 | - | cpuset/cpuset.mems = 0 | cpuset.mems = 0
|
|
|
|
memory = 1G | 2 | $mm.limit_in_bytes = ${gig[1]} | memory.max = ${gig[1]}
|
|
memory-swap = 3G | 2 | $mm.memsw.limit_in_bytes = ${gig[3]} | memory.swap.max = ${gig[2]}
|
|
memory-reservation = 400M | 2 | $mm.soft_limit_in_bytes = 419430400 | memory.low = 419430400
|
|
|
|
blkio-weight = 321 | - | - | io.bfq.weight = default 321 $lomajmin 98
|
|
blkio-weight-device = $LOOPDEVICE:98 | - | - | io.bfq.weight = default 321 $lomajmin 98
|
|
|
|
device-read-bps = $LOOPDEVICE:10mb | - | - | io.max = $devicemax
|
|
device-read-iops = $LOOPDEVICE:2000 | - | - | io.max = $devicemax
|
|
device-write-bps = $LOOPDEVICE:30mb | - | - | io.max = $devicemax
|
|
device-write-iops = $LOOPDEVICE:4000 | - | - | io.max = $devicemax
|
|
"
|
|
|
|
# Run a container
|
|
run_podman run ${pass_loop_device} -d $IMAGE sleep infinity
|
|
cid="$output"
|
|
|
|
# Pass 1: read the table above, gather up the options applicable
|
|
# to this test environment (root/rootless, cgroups v1/v2)
|
|
local -a opts
|
|
local -A check
|
|
while read opt works_rootless cgv1 cgv2; do
|
|
if is_rootless; then
|
|
local skipping="skipping --$opt : does not work rootless"
|
|
if [[ $works_rootless = '-' ]]; then
|
|
echo "[ $skipping ]"
|
|
continue
|
|
fi
|
|
if [[ ! $works_rootless =~ $cgv ]]; then
|
|
echo "[ $skipping on cgroups v$cgv ]"
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
# Determine the "path = newvalue" string for this cgroup
|
|
tuple=$cgv1
|
|
if is_cgroupsv2; then
|
|
tuple=$cgv2
|
|
fi
|
|
if [[ $tuple = '-' ]]; then
|
|
echo "[ skipping --$opt : N/A on cgroups v$cgv ]"
|
|
continue
|
|
fi
|
|
|
|
# Sigh. bfq doesn't exist on Debian (2024-03)
|
|
read path op expect <<<"$tuple"
|
|
if [[ ! -e /sys/fs/cgroup/$path ]]; then
|
|
echo "[ skipping --$opt : /sys/fs/cgroup/$path does not exist ]"
|
|
continue
|
|
fi
|
|
|
|
# OK: setting is applicable. Preserve it. (First removing whitespace)
|
|
opt=${opt// /}
|
|
opts+=("--$opt")
|
|
check["--$opt"]=$tuple
|
|
done < <(parse_table "$tests")
|
|
|
|
# Now do the update in one fell swoop
|
|
run_podman update "${opts[@]}" $cid
|
|
|
|
# ...and check one by one
|
|
defer-assertion-failures
|
|
for opt in "${opts[@]}"; do
|
|
read path op expect <<<"${check[$opt]}"
|
|
run_podman exec $cid cat /sys/fs/cgroup/$path
|
|
|
|
# Magic echo of unquoted-output converts newlines to spaces;
|
|
# important for otherwise multiline blkio file.
|
|
updated="$(echo $output)"
|
|
assert "$updated" $op "$expect" "$opt ($path)"
|
|
done
|
|
immediate-assertion-failures
|
|
|
|
# Clean up
|
|
run_podman rm -f -t0 $cid
|
|
if [[ -n "$LOOPDEVICE" ]]; then
|
|
losetup -d $LOOPDEVICE
|
|
LOOPDEVICE=
|
|
fi
|
|
}
|
|
|
|
@test "podman update - set restart policy" {
|
|
touch ${PODMAN_TMPDIR}/sentinel
|
|
run_podman run --security-opt label=disable --name testctr -v ${PODMAN_TMPDIR}:/testdir -d $IMAGE sh -c "touch /testdir/alive; while test -e /testdir/sentinel; do sleep 0.1; done;"
|
|
|
|
run_podman container inspect testctr --format "{{ .HostConfig.RestartPolicy.Name }}"
|
|
is "$output" "no"
|
|
|
|
run_podman update --restart always testctr
|
|
|
|
run_podman container inspect testctr --format "{{ .HostConfig.RestartPolicy.Name }}"
|
|
is "$output" "always"
|
|
|
|
# Ensure the container is alive
|
|
wait_for_file ${PODMAN_TMPDIR}/alive
|
|
|
|
rm -f ${PODMAN_TMPDIR}/alive
|
|
rm -f ${PODMAN_TMPDIR}/sentinel
|
|
|
|
# Restart should ensure that the container comes back up and recreates the file
|
|
wait_for_file ${PODMAN_TMPDIR}/alive
|
|
|
|
run_podman rm -f -t0 testctr
|
|
}
|
|
|
|
# HealthCheck configuration
|
|
|
|
function nrand() {
|
|
# 1-59 seconds. Don't exceed 59, because podman then shows as "1mXXs"
|
|
echo $((1 + RANDOM % 58))
|
|
}
|
|
|
|
# bats test_tags=ci:parallel
|
|
@test "podman update - test all HealthCheck flags" {
|
|
local ctrname="c-h-$(safename)"
|
|
local msg="healthmsg-$(random_string)"
|
|
local TMP_DIR_HEALTHCHECK="$PODMAN_TMPDIR/healthcheck"
|
|
mkdir $TMP_DIR_HEALTHCHECK
|
|
|
|
# flag-name | value | inspect format, .Config.Xxx
|
|
tests="
|
|
cmd | echo $msg | Healthcheck.Test
|
|
interval | $(nrand)s | Healthcheck.Interval
|
|
log-destination | $TMP_DIR_HEALTHCHECK | HealthLogDestination
|
|
max-log-count | $(nrand) | HealthMaxLogCount
|
|
max-log-size | $(nrand) | HealthMaxLogSize
|
|
on-failure | restart | HealthcheckOnFailureAction
|
|
retries | $(nrand) | Healthcheck.Retries
|
|
timeout | $(nrand)s | Healthcheck.Timeout
|
|
start-period | $(nrand)s | Healthcheck.StartPeriod
|
|
startup-cmd | echo $msg | StartupHealthCheck.Test
|
|
startup-interval | $(nrand)s | StartupHealthCheck.Interval
|
|
startup-retries | $(nrand) | StartupHealthCheck.Retries
|
|
startup-success | $(nrand) | StartupHealthCheck.Successes
|
|
startup-timeout | $(nrand)s | StartupHealthCheck.Timeout
|
|
"
|
|
|
|
run_podman run -d --name $ctrname $IMAGE top
|
|
cid="$output"
|
|
|
|
# Pass 1: read the table above, gather up the options, format and expected values
|
|
local -a opts
|
|
local -A formats
|
|
local -A checks
|
|
while read opt value format ; do
|
|
fullopt="--health-$opt=$value"
|
|
opts+=("$fullopt")
|
|
formats["$fullopt"]="{{.Config.$format}}"
|
|
expected=$value
|
|
# Special case for commands
|
|
if [[ $opt =~ cmd ]]; then
|
|
expected="[CMD-SHELL $value]"
|
|
fi
|
|
checks["$fullopt"]=$expected
|
|
done < <(parse_table "$tests")
|
|
|
|
# Now do the update in one fell swoop
|
|
run_podman update "${opts[@]}" $ctrname
|
|
|
|
# ...and check one by one
|
|
defer-assertion-failures
|
|
for opt in "${opts[@]}"; do
|
|
run_podman inspect $ctrname --format "${formats[$opt]}"
|
|
assert "$output" == "${checks[$opt]}" "$opt"
|
|
done
|
|
immediate-assertion-failures
|
|
|
|
# Clean up
|
|
run_podman rm -f -t0 $cid
|
|
}
|
|
|
|
# bats test_tags=ci:parallel
|
|
@test "podman update - test HealthCheck flags without HealthCheck commands" {
|
|
local ctrname="c-h-$(safename)"
|
|
|
|
# flag-name=value
|
|
tests="
|
|
interval=10s
|
|
retries=5
|
|
timeout=10s
|
|
start-period=10s
|
|
startup-interval=10s
|
|
startup-retries=5
|
|
startup-success=10
|
|
startup-timeout=10s
|
|
"
|
|
|
|
run_podman run -d --name $ctrname $IMAGE top
|
|
cid="$output"
|
|
|
|
defer-assertion-failures
|
|
for opt in $tests; do
|
|
run_podman 125 update "--health-$opt" $ctrname
|
|
assert "$output" =~ "healthcheck command is not set" "--$opt with no startup"
|
|
done
|
|
immediate-assertion-failures
|
|
|
|
run_podman rm -f -t0 $cid
|
|
}
|
|
|
|
# bats test_tags=ci:parallel
|
|
@test "podman update - --no-healthcheck" {
|
|
local msg="healthmsg-$(random_string)"
|
|
local ctrname="c-h-$(safename)"
|
|
|
|
run_podman run -d --name $ctrname \
|
|
--health-cmd "echo $msg" \
|
|
--health-startup-cmd "echo startup$msg" \
|
|
$IMAGE /home/podman/pause
|
|
cid="$output"
|
|
|
|
run_podman update $ctrname --no-healthcheck
|
|
|
|
run_podman inspect $ctrname --format {{.Config.Healthcheck.Test}}
|
|
assert "$output" == "[NONE]" "HealthCheck command is disabled"
|
|
|
|
run_podman inspect $ctrname --format {{.Config.StartupHealthCheck}}
|
|
assert "$output" == "<nil>" "startup HealthCheck command is disabled"
|
|
|
|
run_podman rm -t 0 -f $ctrname
|
|
}
|
|
|
|
# bats test_tags=ci:parallel
|
|
@test "podman update - check behavior - change cmd and destination healthcheck" {
|
|
local TMP_DIR_HEALTHCHECK="$PODMAN_TMPDIR/healthcheck"
|
|
mkdir $TMP_DIR_HEALTHCHECK
|
|
local ctrname="c-h-$(safename)"
|
|
local msg="healthmsg-$(random_string)"
|
|
|
|
run_podman run -d --name $ctrname \
|
|
--health-cmd "echo $msg" \
|
|
$IMAGE /home/podman/pause
|
|
cid="$output"
|
|
|
|
run_podman healthcheck run $ctrname
|
|
is "$output" "" "output from 'podman healthcheck run'"
|
|
|
|
# Run podman update in two separate runs to make sure HealthCheck is overwritten correctly.
|
|
run_podman update $ctrname --health-cmd "echo healthmsg-new"
|
|
|
|
run_podman update $ctrname --health-log-destination $TMP_DIR_HEALTHCHECK
|
|
|
|
run_podman healthcheck run $ctrname
|
|
is "$output" "" "output from 'podman healthcheck run'"
|
|
|
|
healthcheck_log_path="${TMP_DIR_HEALTHCHECK}/${cid}-healthcheck.log"
|
|
# The healthcheck is triggered by the podman when the container is started, but its execution depends on systemd.
|
|
# And since `run_podman healthcheck run` is also run manually, it will result in two runs.
|
|
count=$(grep -co "healthmsg-new" $healthcheck_log_path)
|
|
assert "$count" -ge 1 "Number of matching health log messages"
|
|
|
|
run_podman rm -t 0 -f $ctrname
|
|
}
|
|
|
|
# bats test_tags=ci:parallel
|
|
@test "podman update - resources on update are not changed unless requested" {
|
|
local ctrname="c-h-$(safename)"
|
|
run_podman run -d --name $ctrname \
|
|
--pids-limit 1024 \
|
|
$IMAGE /home/podman/pause
|
|
|
|
run_podman update $ctrname --memory 100M
|
|
|
|
# A Pid check is performed to ensure that other resource settings are not unset. https://github.com/containers/podman/issues/24610
|
|
run_podman inspect $ctrname --format "{{.HostConfig.Memory}}\n{{.HostConfig.PidsLimit}}"
|
|
assert ${lines[0]} == "104857600" ".HostConfig.Memory"
|
|
assert ${lines[1]} == "1024" ".HostConfig.PidsLimit"
|
|
|
|
run_podman rm -t 0 -f $ctrname
|
|
}
|
|
|
|
# bats test_tags=ci:parallel
|
|
@test "podman update - non-block device rejected by --*device* options" {
|
|
local dev=/dev/zero # Not a block device.
|
|
local block_opts=(
|
|
"--blkio-weight-device=$dev:123"
|
|
"--device-read-bps=$dev:10mb"
|
|
"--device-write-bps=$dev:10mb"
|
|
"--device-read-iops=$dev:1000"
|
|
"--device-write-iops=$dev:1000"
|
|
)
|
|
run_podman run -d "$IMAGE" /home/podman/pause
|
|
cid="$output"
|
|
|
|
defer-assertion-failures
|
|
for opt in "${block_opts[@]}"; do
|
|
run_podman 125 update "$cid" "$opt"
|
|
assert "$output" =~ "$dev: not a block device"
|
|
done
|
|
immediate-assertion-failures
|
|
|
|
run_podman rm -t 0 -f "$cid"
|
|
}
|
|
# vim: filetype=sh
|