mirror of
https://github.com/containers/podman.git
synced 2025-10-16 02:32:55 +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>
446 lines
18 KiB
Bash
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"
|
|
}
|