Files
podman/test/system/090-events.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

446 lines
18 KiB
Bash

#!/usr/bin/env bats -*- bats -*-
#
# tests for podman events functionality
#
load helpers
load helpers.network
# bats test_tags=ci:parallel
@test "events with a filter by label and --no-trunc option" {
cname=test-$(safename)
labelname=labelname-$(safename)
labelvalue=labelvalue-$(safename)-$(random_string 15)
before=$(date --iso-8601=seconds)
run_podman run -d --label $labelname=$labelvalue --name $cname --rm $IMAGE true
id="$output"
expect=".* container start $id (image=$IMAGE, name=$cname,.* ${labelname}=${labelvalue}"
run_podman events --since "$before" --filter type=container -f container=$cname --filter label=${labelname}=${labelvalue} --filter event=start --stream=false
is "$output" "$expect" "filtering by container name and label"
# Same thing, but without the container-name filter
run_podman system events --since "$before" -f type=container --filter label=${labelname}=${labelvalue} --filter event=start --stream=false
is "$output" "$expect" "filtering just by label"
# Now filter just by container name, no label
run_podman events --since "$before" --filter type=container --filter container=$cname --filter event=start --stream=false
is "$output" "$expect" "filtering just by container"
# Filter just by label key (without value)
run_podman events --since "$before" --filter type=container --filter label=${labelname} --filter event=start --stream=false
is "$output" "$expect" "filtering by label key only"
# check --no-trunc=false
truncID=${id:0:12}
run_podman events --since "$before" --filter container=$cname --filter event=start --stream=false --no-trunc=false
is "$output" ".* $truncID " "filtering by container name trunc id"
# Wait for container to truly be gone.
# 99% of the time this will return immediately with a "no such container" error,
# which is fine. Under heavy load, it might actually catch the container while
# it's being cleaned up. Either way, this guarantees the "died" event is logged.
PODMAN_TIMEOUT=4 run_podman '?' wait $id
# --no-trunc does not affect --format; we always get the full ID
run_podman events --since "$before" --filter container=$cname --filter event=died --stream=false --format='{{.ID}}--{{.Image}}' --no-trunc=false
assert "$output" = "${id}--${IMAGE}"
}
# CANNOT BE PARALLELIZED: depends on consecutive events, also, #23750
@test "image events" {
skip_if_remote "remote does not support --events-backend"
pushedDir=$PODMAN_TMPDIR/dir
mkdir -p $pushedDir
tarball=$PODMAN_TMPDIR/ball.tar
run_podman image inspect --format "{{.ID}}" $IMAGE
imageID="$output"
t0=$(date --iso-8601=seconds)
tag=registry.com/img-$(safename)
bogus_image="localhost:$(random_free_port)/bogus"
# Force using the file backend since the journal backend is eating events
# (see containers/podman/pull/10219#issuecomment-842325032).
run_podman --events-backend=file push $IMAGE dir:$pushedDir
run_podman --events-backend=file save $IMAGE -o $tarball
run_podman --events-backend=file load -i $tarball
run_podman --events-backend=file pull docker-archive:$tarball
run_podman 125 --events-backend=file pull --retry 0 $bogus_image
run_podman --events-backend=file tag $IMAGE $tag
run_podman --events-backend=file untag $IMAGE $tag
run_podman --events-backend=file tag $IMAGE $tag
run_podman --events-backend=file rmi -f $imageID
run_podman --events-backend=file load -i $tarball
run_podman --events-backend=file events --stream=false --filter type=image --since $t0
is "$output" ".*image push $imageID dir:$pushedDir
.*image save $imageID $tarball
.*image loadfromarchive $imageID $tarball
.*image pull $imageID docker-archive:$tarball
.*image pull-error $bogus_image .*pinging container registry localhost.*connection refused
.*image tag $imageID $tag
.*image untag $imageID $tag:latest
.*image tag $imageID $tag
.*image untag $imageID $tag:latest
.*image untag $imageID $IMAGE
.*image remove $imageID $imageID" \
"podman events"
# With --format we can check the _exact_ output, not just substrings
local -a expect=("push--dir:$pushedDir"
"save--$tarball"
"loadfromarchive--$tarball"
"pull--docker-archive:$tarball"
"pull-error--$bogus_image"
"tag--$tag"
"untag--$tag:latest"
"tag--$tag"
"untag--$tag:latest"
"untag--$IMAGE"
"remove--$imageID"
"loadfromarchive--$tarball"
)
run_podman --events-backend=file events --stream=false --filter type=image --since $t0 --format '{{.Status}}--{{.Name}}'
for i in $(seq 0 ${#expect[@]}); do
assert "${lines[$i]}" = "${expect[$i]}" "events, line $i"
done
assert "${#lines[@]}" = "${#expect[@]}" "Total lines of output"
}
function _events_disjunctive_filters() {
local backend=$1
c1=c1-$(safename)
c2=c2-$(safename)
# Regression test for #10507: make sure that filters with the same key are
# applied in disjunction.
t0=$(date --iso-8601=seconds)
run_podman $backend run --name $c1 --rm $IMAGE ls
run_podman $backend run --name $c2 --rm $IMAGE ls
run_podman $backend events --stream=false --since=$t0 --filter container=$c1 --filter container=$c2 --filter event=start
is "$output" ".* container start .* name=${c1}.*
.* container start .* name=${c2}.*"
}
# CANNOT BE PARALLELIZED - #23750, events-backend=file cannot coexist with journal
@test "events with disjunctive filters - file" {
skip_if_remote "remote does not support --events-backend"
_events_disjunctive_filters --events-backend=file
}
# bats test_tags=ci:parallel
@test "events with disjunctive filters - journald" {
skip_if_remote "remote does not support --events-backend"
skip_if_journald_unavailable "system does not support journald events"
_events_disjunctive_filters --events-backend=journald
}
# CANNOT BE PARALLELIZED - #23750, events-backend=file cannot coexist with journal
@test "events with file backend and journald logdriver with --follow failure" {
skip_if_remote "remote does not support --events-backend"
skip_if_journald_unavailable "system does not support journald events"
cname=c-$(safename)
run_podman --events-backend=file run --log-driver=journald --name=$cname $IMAGE echo hi
is "$output" "hi" "Should support events-backend=file"
run_podman 125 --events-backend=file logs --follow $cname
is "$output" "Error: using --follow with the journald --log-driver but without the journald --events-backend (file) is not supported" \
"Should fail with reasonable error message when events-backend and events-logger do not match"
run_podman rm $cname
}
# bats test_tags=ci:parallel
@test "events with disjunctive filters - default" {
_events_disjunctive_filters ""
}
# bats test_tags=ci:parallel
@test "events with events_logfile_path in containers.conf" {
skip_if_remote "remote does not support --events-backend"
events_file=$PODMAN_TMPDIR/events.log
containersconf=$PODMAN_TMPDIR/containers.conf
cat >$containersconf <<EOF
[engine]
events_logfile_path="$events_file"
EOF
CONTAINERS_CONF_OVERRIDE="$containersconf" run_podman --events-backend=file pull $IMAGE
assert "$(< $events_file)" =~ "\"Name\":\"$IMAGE\"" "Image found in events"
}
function _populate_events_file() {
# Create 100 duplicate entries to populate the events log file.
local events_file=$1
truncate --size=0 $events_file
for i in {0..99}; do
printf '{"Name":"busybox","Status":"pull","Time":"2022-04-06T11:26:42.7236679%02d+02:00","Type":"image","Attributes":null}\n' $i >> $events_file
done
}
# bats test_tags=ci:parallel
@test "events log-file rotation" {
skip_if_remote "setting CONTAINERS_CONF_OVERRIDE logger options does not affect remote client"
# Make sure that the events log file is (not) rotated depending on the
# settings in containers.conf.
# Config without a limit
eventsFile=$PODMAN_TMPDIR/events.txt
containersConf=$PODMAN_TMPDIR/containers.conf
cat >$containersConf <<EOF
[engine]
events_logger="file"
events_logfile_path="$eventsFile"
EOF
# Check that a non existing event file does not cause a hang (#15688)
CONTAINERS_CONF_OVERRIDE=$containersConf run_podman events --stream=false
_populate_events_file $eventsFile
# Create events *without* a limit and make sure that it has not been
# rotated/truncated.
contentBefore=$(head -n100 $eventsFile)
CONTAINERS_CONF_OVERRIDE=$containersConf run_podman run --rm $IMAGE true
contentAfter=$(head -n100 $eventsFile)
is "$contentBefore" "$contentAfter" "events file has not been rotated"
# Repopulate events file
rm $eventsFile
_populate_events_file $eventsFile
# Config with a limit
rm $containersConf
cat >$containersConf <<EOF
[engine]
events_logger="file"
events_logfile_path="$eventsFile"
# The limit of 4750 is the *exact* half of the initial events file.
events_logfile_max_size=4750
EOF
# Create events *with* a limit and make sure that it has been
# rotated/truncated. Once rotated, the events file should only contain the
# second half of its previous events plus the new ones.
expectedContentAfterTruncation=$PODMAN_TMPDIR/truncated.txt
run_podman create $IMAGE
ctrID=$output
CONTAINERS_CONF_OVERRIDE=$containersConf run_podman rm $ctrID
tail -n52 $eventsFile >> $expectedContentAfterTruncation
# Make sure the events file looks as expected.
is "$(cat $eventsFile)" "$(cat $expectedContentAfterTruncation)" "events file has been rotated"
# Make sure that `podman events` can read the file, and that it returns the
# same amount of events. We checked the contents before.
CONTAINERS_CONF_OVERRIDE=$containersConf run_podman events --stream=false --since="2022-03-06T11:26:42.723667984+02:00" --format=json
assert "${#lines[@]}" = 52 "Number of events returned"
is "${lines[0]}" "{\"Name\":\"$eventsFile\",\"Status\":\"log-rotation\",\"time\":[0-9]\+,\"timeNano\":[0-9]\+,\"Type\":\"system\",\"Attributes\":{\"io.podman.event.rotate\":\"begin\"}}"
is "${lines[-2]}" "{\"Name\":\"$eventsFile\",\"Status\":\"log-rotation\",\"time\":[0-9]\+,\"timeNano\":[0-9]\+,\"Type\":\"system\",\"Attributes\":{\"io.podman.event.rotate\":\"end\"}}"
is "${lines[-1]}" "{\"ID\":\"$ctrID\",\"Image\":\"$IMAGE\",\"Name\":\".*\",\"Status\":\"remove\",\"time\":[0-9]\+,\"timeNano\":[0-9]\+,\"Type\":\"container\",\"Attributes\":{.*}}"
}
# bats test_tags=ci:parallel
@test "events log-file no duplicates" {
skip_if_remote "setting CONTAINERS_CONF_OVERRIDE logger options does not affect remote client"
# This test makes sure that events are not returned more than once when
# streaming during a log-file rotation.
eventsFile=$PODMAN_TMPDIR/events.txt
eventsJSON=$PODMAN_TMPDIR/events.json
containersConf=$PODMAN_TMPDIR/containers.conf
cat >$containersConf <<EOF
[engine]
events_logger="file"
events_logfile_path="$eventsFile"
# The populated file has a size of 11300, so let's create a couple of events to
# force a log rotation.
events_logfile_max_size=11300
EOF
_populate_events_file $eventsFile
CONTAINERS_CONF_OVERRIDE=$containersConf timeout --kill=10 20 \
$PODMAN events --stream=true --since="2022-03-06T11:26:42.723667984+02:00" --format=json > $eventsJSON &
# Now wait for the above podman-events process to write to the eventsJSON
# file, so we know it's reading.
retries=20
while [[ $retries -gt 0 ]]; do
if [ -s $eventsJSON ]; then
break
fi
retries=$((retries - 1))
sleep 0.5
done
assert $retries -gt 0 \
"Timed out waiting for podman-events to start reading pre-existing events"
CONTAINERS_CONF_OVERRIDE=$containersConf run_podman create $IMAGE
ctrID=$output
CONTAINERS_CONF_OVERRIDE=$containersConf run_podman rm -f $ctrID
# Now wait for the last event above to be read by the `podman-events`
# process above.
retries=20
while [[ $retries -gt 0 ]]; do
run grep "\"Status\"\:\"remove\"," $eventsJSON
if [[ $status -eq 0 ]]; then
break
fi
retries=$((retries - 1))
sleep 0.5
done
test "$status" = 0 || die "Did not find expected 'Status:remove' line in log"
# Make sure that the log file has been rotated as expected.
run cat $eventsFile
assert "${#lines[@]}" = 54 "Number of events in $eventsFile" # 49 previous + 2 rotation + pull/create/rm
is "${lines[0]}" "{\"Name\":\"$eventsFile\",\"Status\":\"log-rotation\",\"Time\":\".*\",\"Type\":\"system\",\"Attributes\":{\"io.podman.event.rotate\":\"begin\"}}"
is "${lines[1]}" "{\"Name\":\"busybox\",\"Status\":\"pull\",\"Time\":\"2022-04-06T11:26:42.723667951+02:00\",\"Type\":\"image\",\"Attributes\":null}"
is "${lines[49]}" "{\"Name\":\"busybox\",\"Status\":\"pull\",\"Time\":\"2022-04-06T11:26:42.723667999+02:00\",\"Type\":\"image\",\"Attributes\":null}"
is "${lines[50]}" "{\"Name\":\"$eventsFile\",\"Status\":\"log-rotation\",\"Time\":\".*\",\"Type\":\"system\",\"Attributes\":{\"io.podman.event.rotate\":\"end\"}}"
is "${lines[53]}" "{\"ID\":\"$ctrID\",\"Image\":\"$IMAGE\",\"Name\":\".*\",\"Status\":\"remove\",\"Time\":\".*\",\"Type\":\"container\",\"Attributes\":{.*}}"
# Make sure that the JSON stream looks as expected. That means it has all
# events and no duplicates.
run cat $eventsJSON
is "${lines[0]}" "{\"Name\":\"busybox\",\"Status\":\"pull\",\"time\":1649237202,\"timeNano\":1649237202723[0-9]\+,\"Type\":\"image\",\"Attributes\":null}"
is "${lines[99]}" "{\"Name\":\"busybox\",\"Status\":\"pull\",\"time\":1649237202,\"timeNano\":1649237202723[0-9]\+,\"Type\":\"image\",\"Attributes\":null}"
is "${lines[100]}" "{\"Name\":\"$eventsFile\",\"Status\":\"log-rotation\",\"time\":[0-9]\+,\"timeNano\":[0-9]\+,\"Type\":\"system\",\"Attributes\":{\"io.podman.event.rotate\":\"end\"}}"
is "${lines[103]}" "{\"ID\":\"$ctrID\",\"Image\":\"$IMAGE\",\"Name\":\".*\",\"Status\":\"remove\",\"time\":[0-9]\+,\"timeNano\":[0-9]\+,\"Type\":\"container\",\"Attributes\":{.*}}"
}
# Prior to #15633, container labels would not appear in 'die' log events
# CANNOT BE PARALLELIZED - #23750, events-backend=file cannot coexist with journal
@test "events - labels included in container die" {
skip_if_remote "remote does not support --events-backend"
local cname=c-$(safename)
local lname=label$(safename | tr -d -)
local lvalue="labelvalue-$(safename) $(random_string 5)"
run_podman 17 --events-backend=file run --rm \
--name=$cname \
--label=$lname="$lvalue" \
$IMAGE sh -c 'exit 17'
run_podman --events-backend=file events \
--filter=container=$cname \
--filter=status=died \
--stream=false \
--format="{{.Attributes.$lname}}"
assert "$output" = "$lvalue" "podman-events output includes container label"
}
# bats test_tags=ci:parallel
@test "events - backend none should error" {
skip_if_remote "remote does not support --events-backend"
run_podman 125 --events-backend none events
is "$output" "Error: cannot read events with the \"none\" backend" "correct error message"
run_podman 125 --events-backend none events --stream=false
is "$output" "Error: cannot read events with the \"none\" backend" "correct error message"
}
function _events_container_create_inspect_data {
containersConf=$PODMAN_TMPDIR/containers.conf
cat >$containersConf <<EOF
[engine]
events_logger="$1"
events_container_create_inspect_data=true
EOF
local cname=c-$1-$(safename)
t0=$(date --iso-8601=seconds)
# Create a base image, airgapped from $IMAGE so this test is
# isolated from tag/label changes.
baseimage=i-$1-$(safename)
run_podman create -q $IMAGE true
local tmpcid=$output
run_podman commit -q $tmpcid $baseimage
run_podman rm $tmpcid
CONTAINERS_CONF_OVERRIDE=$containersConf run_podman create --name=$cname $baseimage
CONTAINERS_CONF_OVERRIDE=$containersConf run_podman container inspect --size=true $cname
inspect_json=$(jq -r --tab . <<< "$output")
CONTAINERS_CONF_OVERRIDE=$containersConf run_podman --events-backend=$1 events \
--since="$t0" \
--filter=status=$cname \
--filter=status=create \
--stream=false \
--format="{{.ContainerInspectData}}"
events_json=$(jq -r --tab . <<< "[$output]")
assert "$events_json" = "$inspect_json" "JSON payload in event attributes is the same as the inspect one"
# Make sure that the inspect data doesn't show by default in
# podman-events.
CONTAINERS_CONF_OVERRIDE=$containersConf run_podman --events-backend=$1 events \
--since="$t0" \
--filter=status=$cname \
--filter=status=create \
--stream=false
assert "$output" != ".*ConmonPidFile.*"
assert "$output" != ".*EffectiveCaps.*"
run_podman rm $cname
run_podman rmi $baseimage
}
# bats test_tags=ci:parallel
@test "events - container inspect data - journald" {
skip_if_remote "remote does not support --events-backend"
skip_if_journald_unavailable
_events_container_create_inspect_data journald
}
# CANNOT BE PARALLELIZED - #23750, events-backend=file cannot coexist with journal
@test "events - container inspect data - file" {
skip_if_remote "remote does not support --events-backend"
_events_container_create_inspect_data file
}
# bats test_tags=ci:parallel
@test "events - docker compat" {
local cname=c-$(safename)
t0=$(date --iso-8601=ns)
run_podman run --name=$cname --rm $IMAGE true
run_podman events \
--since="$t0" \
--filter=container=$cname \
--filter=status=die \
--stream=false
assert "${lines[0]}" =~ ".* container died [0-9a-f]+ \(image=$IMAGE, name=$cname, .*\)"
}
# bats test_tags=ci:parallel
@test "events - volume events" {
local vname=v-$(safename)
run_podman volume create $vname
run_podman volume rm $vname
run_podman events --since=1m --stream=false --filter volume=$vname
notrunc_results="$output"
assert "${lines[0]}" =~ ".* volume create $vname"
assert "${lines[1]}" =~ ".* volume remove $vname"
# Prefix test
run_podman events --since=1m --stream=false --filter volume=${vname:0:9}
assert "$output" = "$notrunc_results"
}
# bats test_tags=ci:parallel
@test "events - invalid filter" {
run_podman 125 events --since="the dawn of time...ish"
assert "$output" =~ "failed to parse event filters"
}