1
#!/usr/bin/env bats -*- bats -*-
3
# Basic tests for podman logs
8
@test "podman logs - basic test" {
9
rand_string=$(random_string 40)
11
run_podman create $IMAGE echo $rand_string
15
is "$output" "" "logs on created container: empty"
17
run_podman start --attach --interactive $cid
18
is "$output" "$rand_string" "output from podman-start on created ctr"
19
is "$output" "$rand_string" "logs of started container"
22
is "$output" "$rand_string" "output from podman-logs after container is run"
24
# test --since with Unix timestamps
25
run_podman logs --since 1000 $cid
27
# test --until with Unix timestamps
28
run_podman logs --until 1000 $cid
33
function _log_test_tail() {
36
run_podman run -d --log-driver=$driver $IMAGE sh -c "echo test1; echo test2"
40
run_podman logs --tail 1 --timestamps $cid
42
assert "$log1" =~ "^[0-9-]+T[0-9:.]+([\+-][0-9:]+|Z) test2" \
43
"logs should only show last line"
45
# Sigh. I hate doing this, but podman-remote --timestamp only has 1-second
46
# resolution (regular podman has sub-second). For the timestamps-differ
47
# check below, we need to force a different second.
52
run_podman restart $cid
55
run_podman logs -t --tail 1 $cid
57
assert "$log2" =~ "^[0-9-]+T[0-9:.]+([\+-][0-9:]+|Z) test2" \
58
"logs, after restart, shows only last line"
60
assert "$log2" != "$log1" "log timestamps should differ"
65
@test "podman logs - tail test, k8s-file" {
66
_log_test_tail k8s-file
69
@test "podman logs - tail test, journald" {
70
# We can't use journald on RHEL as rootless: rhbz#1895105
71
skip_if_journald_unavailable
73
_log_test_tail journald
76
function _additional_events_backend() {
78
# Since PR#10431, 'logs -f' with journald driver is only supported with journald events backend.
79
if [[ $driver = "journald" ]]; then
80
run_podman info --format '{{.Host.EventLogger}}' >/dev/null
81
if [[ $output != "journald" ]]; then
82
echo "--events-backend journald"
87
function _log_test_multi() {
90
skip_if_remote "logs does not support multiple containers when run remotely"
92
# Under k8s file, 'podman logs' returns just the facts, Ma'am.
93
# Under journald, there may be other cruft (e.g. container removals)
95
if [[ $driver =~ journal ]]; then
99
local events_backend=$(_additional_events_backend $driver)
101
# Simple helper to make the container starts, below, easier to read
104
run_podman ${events_backend} run --log-driver=$driver --rm -d --name "$1" $IMAGE sh -c "$2";
105
cid+=($(echo "${output:0:12}"))
108
# Not really a guarantee that we'll get a-b-c-d in order, but it's
109
# the best we can do. The trailing 'sleep' in each container
110
# minimizes the chance of a race condition in which the container
111
# is removed before 'podman logs' has a chance to wake up and read
113
doit c1 "echo a;sleep 10;echo d;sleep 3"
114
doit c2 "sleep 1;echo b;sleep 2;echo c;sleep 3"
116
run_podman ${events_backend} logs -f c1 c2
117
assert "$output" =~ \
121
${cid[0]} d" "Sequential output from logs"
124
@test "podman logs - multi k8s-file" {
125
_log_test_multi k8s-file
128
@test "podman logs - multi journald" {
129
# We can't use journald on RHEL as rootless: rhbz#1895105
130
skip_if_journald_unavailable
132
_log_test_multi journald
135
function _log_test_restarted() {
137
local events_backend=$(_additional_events_backend $driver)
138
if [[ -n "${events_backend}" ]]; then
139
skip_if_remote "remote does not support --events-backend"
141
run_podman run --log-driver=$driver ${events_backend} --name logtest $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'
143
# run/start is flaking for remote so let's wait for the container condition
144
# to stop wasting energy until the root cause gets fixed.
145
run_podman container wait --condition=exited --condition=stopped logtest
146
run_podman ${events_backend} start -a logtest
147
logfile=$(mktemp -p ${PODMAN_TMPDIR} logfileXXXXXXXX)
148
$PODMAN $_PODMAN_TEST_OPTS ${events_backend} logs -f logtest > $logfile
149
expected=$(mktemp -p ${PODMAN_TMPDIR} expectedXXXXXXXX)
151
diff -u ${expected} ${logfile}
154
@test "podman logs restarted - k8s-file" {
155
_log_test_restarted k8s-file
158
@test "podman logs restarted journald" {
159
# We can't use journald on RHEL as rootless: rhbz#1895105
160
skip_if_journald_unavailable
162
_log_test_restarted journald
165
@test "podman logs - journald log driver requires journald events backend" {
166
skip_if_remote "remote does not support --events-backend"
167
# We can't use journald on RHEL as rootless: rhbz#1895105
168
skip_if_journald_unavailable
170
run_podman --events-backend=file run --log-driver=journald -d --name test --replace $IMAGE ls /
171
run_podman --events-backend=file logs test
172
run_podman 125 --events-backend=file logs --follow test
173
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"
176
function _log_test_since() {
179
s_before="before_$(random_string)_${driver}"
180
s_after="after_$(random_string)_${driver}"
182
before=$(date --iso-8601=seconds)
183
run_podman run --log-driver=$driver -d --name test $IMAGE sh -c \
184
"echo $s_before; trap 'echo $s_after; exit' SIGTERM; while :; do sleep 0.1; done"
185
wait_for_output "$s_before" test
187
# sleep a second to make sure the date is after the first echo
188
# (We could instead use iso-8601=ns but seconds feels more real-world)
190
after=$(date --iso-8601=seconds)
198
run_podman logs --since $before test
203
run_podman logs --since $after test
204
is "$output" "$s_after"
205
run_podman rm -t 1 -f test
208
@test "podman logs - since k8s-file" {
209
_log_test_since k8s-file
212
@test "podman logs - since journald" {
213
# We can't use journald on RHEL as rootless: rhbz#1895105
214
skip_if_journald_unavailable
216
_log_test_since journald
219
function _log_test_until() {
222
s_before="before_$(random_string)_${driver}"
223
s_after="after_$(random_string)_${driver}"
225
before=$(date --iso-8601=seconds)
227
run_podman run --log-driver=$driver -d --name test $IMAGE sh -c \
228
"echo $s_before; trap 'echo $s_after; exit' SIGTERM; while :; do sleep 0.1; done"
230
# sleep a second to make sure the date is after the first echo
235
# Sigh. Stupid journald has a lag. Wait a few seconds for it to catch up.
239
while [[ $retries -gt 0 ]]; do
241
if [[ "$output" = "$s_both" ]]; then
244
retries=$((retries - 1))
247
assert $retries -gt 0 \
248
"Timed out waiting for before&after in podman logs: $output"
250
run_podman logs --until $before test
251
is "$output" "" "podman logs --until before"
253
after=$(date --date='+1 second' --iso-8601=ns)
255
run_podman logs --until $after test
256
is "$output" "$s_both" "podman logs --until after"
257
run_podman rm -t 0 -f test
260
@test "podman logs - until k8s-file" {
261
_log_test_until k8s-file
264
@test "podman logs - until journald" {
265
# We can't use journald on RHEL as rootless: rhbz#1895105
266
skip_if_journald_unavailable
268
_log_test_until journald
271
function _log_test_follow() {
273
cname=$(random_string)
274
contentA=$(random_string)
275
contentB=$(random_string)
276
contentC=$(random_string)
277
local events_backend=$(_additional_events_backend $driver)
279
if [[ -n "${events_backend}" ]]; then
280
skip_if_remote "remote does not support --events-backend"
283
# Note: it seems we need at least three log lines to hit #11461.
284
run_podman ${events_backend} run --log-driver=$driver --name $cname $IMAGE sh -c "echo $contentA; echo $contentB; echo $contentC"
285
run_podman ${events_backend} logs -f $cname
286
is "$output" "$contentA
288
$contentC" "logs -f on exited container works"
290
run_podman ${events_backend} rm -t 0 -f $cname
293
@test "podman logs - --follow k8s-file" {
294
_log_test_follow k8s-file
297
@test "podman logs - --follow journald" {
298
# We can't use journald on RHEL as rootless: rhbz#1895105
299
skip_if_journald_unavailable
301
_log_test_follow journald
304
function _log_test_follow_since() {
306
cname=$(random_string)
307
content=$(random_string)
308
local events_backend=$(_additional_events_backend $driver)
310
if [[ -n "${events_backend}" ]]; then
311
skip_if_remote "remote does not support --events-backend"
314
run_podman ${events_backend} run --log-driver=$driver --name $cname $IMAGE echo "$content"
315
# Using --since 0s can flake because the log might written in the second as the logs call is made.
316
# The -1s makes sure we only read logs that would be created 1s in the future which cannot happen.
317
run_podman ${events_backend} logs --since -1s -f $cname
318
assert "$output" == "" "logs --since -f on exited container works"
320
run_podman ${events_backend} rm -t 0 -f $cname
322
# Now do the same with a running container to check #16950.
323
run_podman ${events_backend} run --log-driver=$driver --name $cname -d $IMAGE \
324
sh -c "sleep 1; while :; do echo $content && sleep 5; done"
326
# sleep is required to make sure the podman event backend no longer sees the start event in the log
327
# This value must be greater or equal than the value given in --since below
330
# Make sure podman logs actually follows by giving a low timeout and check that the command times out
331
PODMAN_TIMEOUT=3 run_podman 124 ${events_backend} logs --since 0.1s -f $cname
332
assert "$output" =~ "^$content
333
timeout: sending signal TERM to command.*" "logs --since -f on running container works"
335
run_podman ${events_backend} rm -t 0 -f $cname
338
@test "podman logs - --since --follow k8s-file" {
339
_log_test_follow_since k8s-file
342
# bats test_tags=distro-integration
343
@test "podman logs - --since --follow journald" {
344
# We can't use journald on RHEL as rootless: rhbz#1895105
345
skip_if_journald_unavailable
347
_log_test_follow_since journald
350
function _log_test_follow_until() {
352
cname=$(random_string)
353
content=$(random_string)
354
local events_backend=$(_additional_events_backend $driver)
356
if [[ -n "${events_backend}" ]]; then
357
skip_if_remote "remote does not support --events-backend"
360
run_podman ${events_backend} run --log-driver=$driver --name $cname -d $IMAGE \
361
sh -c "n=1;while :; do echo $content--\$n; n=\$((n+1));sleep 0.1; done"
364
# The logs command should exit after the until time even when follow is set
365
PODMAN_TIMEOUT=10 run_podman ${events_backend} logs --until 3s -f $cname
369
# The delta should be 3 but because it could be a bit longer on a slow system such as CI we also accept 4.
370
delta_t=$(( $t1 - $t0 ))
371
assert $delta_t -gt 2 "podman logs --until: exited too early!"
372
assert $delta_t -lt 5 "podman logs --until: exited too late!"
374
# Impossible to know how many lines we'll see, but require at least two
375
assert "$logs_seen" =~ "$content--1
376
$content--2.*" "logs --until -f on running container works"
378
run_podman ${events_backend} rm -t 0 -f $cname
381
@test "podman logs - --until --follow k8s-file" {
382
_log_test_follow_until k8s-file
385
# bats test_tags=distro-integration
386
@test "podman logs - --until --follow journald" {
387
# We can't use journald on RHEL as rootless: rhbz#1895105
388
skip_if_journald_unavailable
390
_log_test_follow_until journald
393
# https://github.com/containers/podman/issues/19545
394
@test "podman logs --tail, k8s-file with partial lines" {
395
cname="tail_container"
397
# "-t" gives us ^Ms (CRs) in the log
398
run_podman run --name $cname --log-driver k8s-file -t $IMAGE echo hi
400
# Hand-craft a log file with partial lines and carriage returns
401
run_podman inspect --format '{{.HostConfig.LogConfig.Path}}' $cname
403
timestamp=$(head -n1 "$logpath" | awk '{print $1}')
406
# Delete, don't overwrite, in case conmon still has the fd open
409
$timestamp stdout F podman1$cr
410
$timestamp stdout P podman2
411
$timestamp stdout F $cr
412
$timestamp stdout F podman3$cr
415
# FIXME: remove after 2024-01-01 if no more flakes seen.
418
expect1="podman3${cr}"
419
expect2="podman2${cr}${nl}podman3${cr}"
420
expect3="podman1${cr}${nl}podman2${cr}${nl}podman3${cr}"
423
run_podman logs --tail 1 $cname
424
assert "$output" = "$expect1" "--tail 1"
426
# Prior to this PR, the first line would be "^M" without the podman
427
run_podman logs --tail 2 $cname
428
assert "$output" = "$expect2" "--tail 2"
430
# Confirm that we won't overrun
432
run_podman logs --tail $i $cname
433
assert "$output" = "$expect3" "--tail $i"