#!/usr/bin/env bats -*- bats -*- # # Basic tests for podman logs # load helpers # bats test_tags=ci:parallel @test "podman logs - basic test" { rand_string=$(random_string 40) run_podman create $IMAGE echo $rand_string cid="$output" run_podman logs $cid is "$output" "" "logs on created container: empty" run_podman start --attach --interactive $cid is "$output" "$rand_string" "output from podman-start on created ctr" is "$output" "$rand_string" "logs of started container" run_podman logs $cid is "$output" "$rand_string" "output from podman-logs after container is run" # test --since with Unix timestamps run_podman logs --since 1000 $cid # test --until with Unix timestamps run_podman logs --until 1000 $cid run_podman rm $cid } function _log_test_tail() { local driver=$1 run_podman run -d --log-driver=$driver $IMAGE sh -c "echo test1; echo test2" cid="$output" run_podman wait $cid run_podman logs --tail 1 --timestamps $cid log1="$output" assert "$log1" =~ "^[0-9-]+T[0-9:.]+([\+-][0-9:]+|Z) test2" \ "logs should only show last line" # Sigh. I hate doing this, but podman-remote --timestamp only has 1-second # resolution (regular podman has sub-second). For the timestamps-differ # check below, we need to force a different second. if is_remote; then sleep 2 fi run_podman restart $cid run_podman wait $cid run_podman logs -t --tail 1 $cid log2="$output" assert "$log2" =~ "^[0-9-]+T[0-9:.]+([\+-][0-9:]+|Z) test2" \ "logs, after restart, shows only last line" assert "$log2" != "$log1" "log timestamps should differ" run_podman rm $cid } # CANNOT BE PARALLELIZED - #23750, events-backend=file cannot coexist with journal @test "podman logs - tail test, k8s-file" { _log_test_tail k8s-file } # bats test_tags=ci:parallel @test "podman logs - tail test, journald" { # We can't use journald on RHEL as rootless: rhbz#1895105 skip_if_journald_unavailable _log_test_tail journald } function _additional_events_backend() { local driver=$1 # Since PR#10431, 'logs -f' with journald driver is only supported with journald events backend. if [[ $driver = "journald" ]]; then run_podman info --format '{{.Host.EventLogger}}' >/dev/null if [[ $output != "journald" ]]; then echo "--events-backend journald" fi fi } function _log_test_multi() { local driver=$1 skip_if_remote "logs does not support multiple containers when run remotely" local events_backend=$(_additional_events_backend $driver) # Simple helper to make the container starts, below, easier to read local cname1="c-ltm-1-$(safename)" local cname2="c-ltm-2-$(safename)" local -a cid doit() { run_podman ${events_backend} run --log-driver=$driver -d \ --name "$1" $IMAGE sh -c "$2"; cid+=($(echo "${output:0:12}")) } doit $cname1 "echo a1; echo a2" doit $cname2 "echo b1; echo b2" # Reading logs only guarantees the order for a single container, # when using multiple containers the line order between them can vary. run_podman ${events_backend} logs -f $cname1 $cname2 assert "$output" =~ \ ".*^${cid[0]} a1\$.* ${cid[0]} a2" "Sequential output from c1" assert "$output" =~ \ ".*^${cid[1]} b1\$.* ${cid[1]} b2" "Sequential output from c2" run_podman rm -f -t0 ${cid[0]} ${cid[1]} } # CANNOT BE PARALLELIZED - #23750, events-backend=file cannot coexist with journal @test "podman logs - multi k8s-file" { _log_test_multi k8s-file } # bats test_tags=ci:parallel @test "podman logs - multi journald" { # We can't use journald on RHEL as rootless: rhbz#1895105 skip_if_journald_unavailable _log_test_multi journald } function _log_test_restarted() { local driver=$1 local events_backend=$(_additional_events_backend $driver) if [[ -n "${events_backend}" ]]; then skip_if_remote "remote does not support --events-backend" fi cname="c-ltr-$(safename)" run_podman run --log-driver=$driver ${events_backend} --name $cname $IMAGE sh -c 'start=0; if test -s log; then start=`tail -n 1 log`; fi; seq `expr $start + 1` `expr $start + 10` | tee -a log' run_podman ${events_backend} start -a $cname logfile=$(mktemp -p ${PODMAN_TMPDIR} logfileXXXXXXXX) "${PODMAN_CMD[@]}" $_PODMAN_TEST_OPTS ${events_backend} logs -f $cname > $logfile expected=$(mktemp -p ${PODMAN_TMPDIR} expectedXXXXXXXX) seq 1 20 > $expected diff -u ${expected} ${logfile} run_podman rm -f -t0 $cname } # CANNOT BE PARALLELIZED - #23750, events-backend=file cannot coexist with journal @test "podman logs restarted - k8s-file" { _log_test_restarted k8s-file } # bats test_tags=ci:parallel @test "podman logs restarted journald" { # We can't use journald on RHEL as rootless: rhbz#1895105 skip_if_journald_unavailable _log_test_restarted journald } # CANNOT BE PARALLELIZED - #23750, events-backend=file cannot coexist with journal @test "podman logs - journald log driver requires journald events backend" { skip_if_remote "remote does not support --events-backend" # We can't use journald on RHEL as rootless: rhbz#1895105 skip_if_journald_unavailable cname="c-$(safename)" run_podman --events-backend=file run --log-driver=journald -d --name $cname --replace $IMAGE ls / run_podman --events-backend=file logs $cname 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" "journald logger requires journald eventer" run_podman rm $cname } function _log_test_since() { local driver=$1 s_before="before_$(random_string)_${driver}" s_after="after_$(random_string)_${driver}" cname="c-lts-$(safename)" before=$(date --iso-8601=seconds) run_podman run --log-driver=$driver -d --name $cname $IMAGE sh -c \ "echo $s_before; trap 'echo $s_after; exit' SIGTERM; while :; do sleep 0.1; done" wait_for_output "$s_before" $cname # sleep a second to make sure the date is after the first echo # (We could instead use iso-8601=ns but seconds feels more real-world) sleep 1 after=$(date --iso-8601=seconds) run_podman stop $cname run_podman logs $cname is "$output" \ "$s_before $s_after" run_podman logs --since $before $cname is "$output" \ "$s_before $s_after" run_podman logs --since $after $cname is "$output" "$s_after" run_podman rm -t 1 -f $cname } # CANNOT BE PARALLELIZED - #23750, events-backend=file cannot coexist with journal @test "podman logs - since k8s-file" { _log_test_since k8s-file } # bats test_tags=ci:parallel @test "podman logs - since journald" { # We can't use journald on RHEL as rootless: rhbz#1895105 skip_if_journald_unavailable _log_test_since journald } function _log_test_until() { local driver=$1 s_before="before_$(random_string)_${driver}" s_after="after_$(random_string)_${driver}" cname="c-ltu-$(safename)" before=$(date --iso-8601=seconds) sleep 1 run_podman run --log-driver=$driver -d --name $cname $IMAGE sh -c \ "echo $s_before; trap 'echo $s_after; exit' SIGTERM; while :; do sleep 0.1; done" # sleep a second to make sure the date is after the first echo sleep 1 run_podman stop $cname run_podman wait $cname # Sigh. Stupid journald has a lag. Wait a few seconds for it to catch up. retries=20 s_both="$s_before $s_after" while [[ $retries -gt 0 ]]; do run_podman logs $cname if [[ "$output" = "$s_both" ]]; then break fi retries=$((retries - 1)) sleep 0.1 done assert $retries -gt 0 \ "Timed out waiting for before&after in podman logs: $output" run_podman logs --until $before $cname is "$output" "" "podman logs --until before" after=$(date --date='+1 second' --iso-8601=ns) run_podman logs --until $after $cname is "$output" "$s_both" "podman logs --until after" run_podman rm -t 0 -f $cname } # CANNOT BE PARALLELIZED - #23750, events-backend=file cannot coexist with journal @test "podman logs - until k8s-file" { _log_test_until k8s-file } # bats test_tags=ci:parallel @test "podman logs - until journald" { # We can't use journald on RHEL as rootless: rhbz#1895105 skip_if_journald_unavailable _log_test_until journald } function _log_test_follow() { local driver=$1 cname="c-ltf-$(safename)" contentA=$(random_string) contentB=$(random_string) contentC=$(random_string) local events_backend=$(_additional_events_backend $driver) if [[ -n "${events_backend}" ]]; then skip_if_remote "remote does not support --events-backend" fi # Note: it seems we need at least three log lines to hit #11461. run_podman ${events_backend} run --log-driver=$driver --name $cname $IMAGE sh -c "echo $contentA; echo $contentB; echo $contentC" run_podman ${events_backend} logs -f $cname is "$output" "$contentA $contentB $contentC" "logs -f on exited container works" run_podman ${events_backend} rm -t 0 -f $cname } # CANNOT BE PARALLELIZED - #23750, events-backend=file cannot coexist with journal @test "podman logs - --follow k8s-file" { _log_test_follow k8s-file } # bats test_tags=ci:parallel @test "podman logs - --follow journald" { # We can't use journald on RHEL as rootless: rhbz#1895105 skip_if_journald_unavailable _log_test_follow journald } function _log_test_follow_since() { local driver=$1 cname="c-ltfs-$(safename)" content=$(random_string) local events_backend=$(_additional_events_backend $driver) if [[ -n "${events_backend}" ]]; then skip_if_remote "remote does not support --events-backend" fi run_podman ${events_backend} run --log-driver=$driver --name $cname $IMAGE echo "$content" # Using --since 0s can flake because the log might written in the second as the logs call is made. # The -1s makes sure we only read logs that would be created 1s in the future which cannot happen. run_podman ${events_backend} logs --since -1s -f $cname assert "$output" == "" "logs --since -f on exited container works" run_podman ${events_backend} rm -t 0 -f $cname # Now do the same with a running container to check #16950. run_podman ${events_backend} run --log-driver=$driver --name $cname -d $IMAGE \ sh -c "sleep 1; while :; do echo $content && sleep 1; done" # sleep is required to make sure the podman event backend no longer sees the start event in the log # This value must be greater or equal than the value given in --since below sleep 0.2 # Make sure podman logs actually follows by giving a low timeout and check that the command times out # Option after container name should work as well: https://github.com/containers/podman/issues/25653 PODMAN_TIMEOUT=3 run_podman 124 ${events_backend} logs --since 0.1s $cname -f assert "$output" =~ "$content timeout: sending signal TERM to command.*" "logs --since -f on running container works" run_podman ${events_backend} rm -t 0 -f $cname } # CANNOT BE PARALLELIZED - #23750, events-backend=file cannot coexist with journal @test "podman logs - --since --follow k8s-file" { _log_test_follow_since k8s-file } # bats test_tags=ci:parallel @test "podman logs - --since --follow journald" { # We can't use journald on RHEL as rootless: rhbz#1895105 skip_if_journald_unavailable _log_test_follow_since journald } function _log_test_follow_until() { local driver=$1 cname="c-ltfu-$(safename)" content=$(random_string) local events_backend=$(_additional_events_backend $driver) if [[ -n "${events_backend}" ]]; then skip_if_remote "remote does not support --events-backend" fi run_podman ${events_backend} run --log-driver=$driver --name $cname -d $IMAGE \ sh -c "n=1;while :; do echo $content--\$n; n=\$((n+1));sleep 0.1; done" t0=$(date +%s%3N) # The logs command should exit after the until time even when follow is set PODMAN_TIMEOUT=10 run_podman ${events_backend} logs --until 3s -f $cname t1=$(date +%s%3N) logs_seen="$output" # The delta should be 3 but could be longer on a slow CI system delta_t_ms=$(( $t1 - $t0 )) assert $delta_t_ms -gt 2000 "podman logs --until: exited too early!" assert $delta_t_ms -lt 5000 "podman logs --until: exited too late!" # Impossible to know how many lines we'll see, but require at least two assert "$logs_seen" =~ "$content--1 $content--2.*" "logs --until -f on running container works" run_podman ${events_backend} rm -t 0 -f $cname } # CANNOT BE PARALLELIZED - #23750, events-backend=file cannot coexist with journal @test "podman logs - --until --follow k8s-file" { _log_test_follow_until k8s-file } # bats test_tags=ci:parallel @test "podman logs - --until --follow journald" { # We can't use journald on RHEL as rootless: rhbz#1895105 skip_if_journald_unavailable _log_test_follow_until journald } # https://github.com/containers/podman/issues/19545 # CANNOT BE PARALLELIZED - #23750, events-backend=file cannot coexist with journal @test "podman logs --tail, k8s-file with partial lines" { cname="c-$(safename)" # "-t" gives us ^Ms (CRs) in the log run_podman run --name $cname --log-driver k8s-file -t $IMAGE echo hi # Hand-craft a log file with partial lines and carriage returns run_podman inspect --format '{{.HostConfig.LogConfig.Path}}' $cname logpath="$output" timestamp=$(head -n1 "$logpath" | awk '{print $1}') cr=$'\r' nl=$'\n' # Delete, don't overwrite, in case conmon still has the fd open rm -f $logpath cat > $logpath <