Files
podman/test/system/280-update.bats
Paul Holzinger 247a80db45 test/system: remove distro-integration bats tag
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>
2025-09-02 12:10:08 +02:00

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