podman

Форк
0
/
035-logs.bats 
439 строк · 13.6 Кб
1
#!/usr/bin/env bats   -*- bats -*-
2
#
3
# Basic tests for podman logs
4
#
5

6
load helpers
7

8
@test "podman logs - basic test" {
9
    rand_string=$(random_string 40)
10

11
    run_podman create $IMAGE echo $rand_string
12
    cid="$output"
13

14
    run_podman logs $cid
15
    is "$output" ""  "logs on created container: empty"
16

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"
20

21
    run_podman logs $cid
22
    is "$output" "$rand_string" "output from podman-logs after container is run"
23

24
    # test --since with Unix timestamps
25
    run_podman logs --since 1000 $cid
26

27
    # test --until with Unix timestamps
28
    run_podman logs --until 1000 $cid
29

30
    run_podman rm $cid
31
}
32

33
function _log_test_tail() {
34
    local driver=$1
35

36
    run_podman run -d --log-driver=$driver $IMAGE sh -c "echo test1; echo test2"
37
    cid="$output"
38

39
    run_podman wait $cid
40
    run_podman logs --tail 1 --timestamps $cid
41
    log1="$output"
42
    assert "$log1" =~ "^[0-9-]+T[0-9:.]+([\+-][0-9:]+|Z) test2" \
43
           "logs should only show last line"
44

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.
48
    if is_remote; then
49
        sleep 2
50
    fi
51

52
    run_podman restart $cid
53
    run_podman wait $cid
54

55
    run_podman logs -t --tail 1 $cid
56
    log2="$output"
57
    assert "$log2" =~ "^[0-9-]+T[0-9:.]+([\+-][0-9:]+|Z) test2" \
58
           "logs, after restart, shows only last line"
59

60
    assert "$log2" != "$log1" "log timestamps should differ"
61

62
    run_podman rm $cid
63
}
64

65
@test "podman logs - tail test, k8s-file" {
66
    _log_test_tail k8s-file
67
}
68

69
@test "podman logs - tail test, journald" {
70
    # We can't use journald on RHEL as rootless: rhbz#1895105
71
    skip_if_journald_unavailable
72

73
    _log_test_tail journald
74
}
75

76
function _additional_events_backend() {
77
    local driver=$1
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"
83
        fi
84
    fi
85
}
86

87
function _log_test_multi() {
88
    local driver=$1
89

90
    skip_if_remote "logs does not support multiple containers when run remotely"
91

92
    # Under k8s file, 'podman logs' returns just the facts, Ma'am.
93
    # Under journald, there may be other cruft (e.g. container removals)
94
    local etc=
95
    if [[ $driver =~ journal ]]; then
96
        etc='.*'
97
    fi
98

99
    local events_backend=$(_additional_events_backend $driver)
100

101
    # Simple helper to make the container starts, below, easier to read
102
    local -a cid
103
    doit() {
104
        run_podman ${events_backend} run --log-driver=$driver --rm -d --name "$1" $IMAGE sh -c "$2";
105
        cid+=($(echo "${output:0:12}"))
106
    }
107

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
112
    # the final output.
113
    doit c1         "echo a;sleep 10;echo d;sleep 3"
114
    doit c2 "sleep 1;echo b;sleep  2;echo c;sleep 3"
115

116
    run_podman ${events_backend} logs -f c1 c2
117
    assert "$output" =~ \
118
       "${cid[0]} a$etc
119
${cid[1]} b$etc
120
${cid[1]} c$etc
121
${cid[0]} d"   "Sequential output from logs"
122
}
123

124
@test "podman logs - multi k8s-file" {
125
    _log_test_multi k8s-file
126
}
127

128
@test "podman logs - multi journald" {
129
    # We can't use journald on RHEL as rootless: rhbz#1895105
130
    skip_if_journald_unavailable
131

132
    _log_test_multi journald
133
}
134

135
function _log_test_restarted() {
136
    local driver=$1
137
    local events_backend=$(_additional_events_backend $driver)
138
    if [[ -n "${events_backend}" ]]; then
139
        skip_if_remote "remote does not support --events-backend"
140
    fi
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'
142
    # FIXME: #9597
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)
150
    seq 1 20  > $expected
151
    diff -u ${expected} ${logfile}
152
}
153

154
@test "podman logs restarted - k8s-file" {
155
    _log_test_restarted k8s-file
156
}
157

158
@test "podman logs restarted journald" {
159
    # We can't use journald on RHEL as rootless: rhbz#1895105
160
    skip_if_journald_unavailable
161

162
    _log_test_restarted journald
163
}
164

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
169

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"
174
}
175

176
function _log_test_since() {
177
    local driver=$1
178

179
    s_before="before_$(random_string)_${driver}"
180
    s_after="after_$(random_string)_${driver}"
181

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
186

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)
189
    sleep 1
190
    after=$(date --iso-8601=seconds)
191
    run_podman stop test
192

193
    run_podman logs test
194
    is "$output" \
195
        "$s_before
196
$s_after"
197

198
    run_podman logs --since $before test
199
    is "$output" \
200
        "$s_before
201
$s_after"
202

203
    run_podman logs --since $after test
204
    is "$output" "$s_after"
205
    run_podman rm -t 1 -f test
206
}
207

208
@test "podman logs - since k8s-file" {
209
    _log_test_since k8s-file
210
}
211

212
@test "podman logs - since journald" {
213
    # We can't use journald on RHEL as rootless: rhbz#1895105
214
    skip_if_journald_unavailable
215

216
    _log_test_since journald
217
}
218

219
function _log_test_until() {
220
    local driver=$1
221

222
    s_before="before_$(random_string)_${driver}"
223
    s_after="after_$(random_string)_${driver}"
224

225
    before=$(date --iso-8601=seconds)
226
    sleep 1
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"
229

230
    # sleep a second to make sure the date is after the first echo
231
    sleep 1
232
    run_podman stop test
233
    run_podman wait test
234

235
    # Sigh. Stupid journald has a lag. Wait a few seconds for it to catch up.
236
    retries=20
237
    s_both="$s_before
238
$s_after"
239
    while [[ $retries -gt 0 ]]; do
240
        run_podman logs test
241
        if [[ "$output" = "$s_both" ]]; then
242
            break
243
        fi
244
        retries=$((retries - 1))
245
        sleep 0.1
246
    done
247
    assert $retries -gt 0 \
248
           "Timed out waiting for before&after in podman logs: $output"
249

250
    run_podman logs --until $before test
251
    is "$output" "" "podman logs --until before"
252

253
    after=$(date --date='+1 second' --iso-8601=ns)
254

255
    run_podman logs --until $after test
256
    is "$output" "$s_both" "podman logs --until after"
257
    run_podman rm -t 0 -f test
258
}
259

260
@test "podman logs - until k8s-file" {
261
    _log_test_until k8s-file
262
}
263

264
@test "podman logs - until journald" {
265
    # We can't use journald on RHEL as rootless: rhbz#1895105
266
    skip_if_journald_unavailable
267

268
    _log_test_until journald
269
}
270

271
function _log_test_follow() {
272
    local driver=$1
273
    cname=$(random_string)
274
    contentA=$(random_string)
275
    contentB=$(random_string)
276
    contentC=$(random_string)
277
    local events_backend=$(_additional_events_backend $driver)
278

279
    if [[ -n "${events_backend}" ]]; then
280
        skip_if_remote "remote does not support --events-backend"
281
    fi
282

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
287
$contentB
288
$contentC" "logs -f on exited container works"
289

290
    run_podman ${events_backend} rm -t 0 -f $cname
291
}
292

293
@test "podman logs - --follow k8s-file" {
294
    _log_test_follow k8s-file
295
}
296

297
@test "podman logs - --follow journald" {
298
    # We can't use journald on RHEL as rootless: rhbz#1895105
299
    skip_if_journald_unavailable
300

301
    _log_test_follow journald
302
}
303

304
function _log_test_follow_since() {
305
    local driver=$1
306
    cname=$(random_string)
307
    content=$(random_string)
308
    local events_backend=$(_additional_events_backend $driver)
309

310
    if [[ -n "${events_backend}" ]]; then
311
        skip_if_remote "remote does not support --events-backend"
312
    fi
313

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"
319

320
    run_podman ${events_backend} rm -t 0 -f $cname
321

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"
325

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
328
    sleep 0.2
329

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"
334

335
    run_podman ${events_backend} rm -t 0 -f $cname
336
}
337

338
@test "podman logs - --since --follow k8s-file" {
339
    _log_test_follow_since k8s-file
340
}
341

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
346

347
    _log_test_follow_since journald
348
}
349

350
function _log_test_follow_until() {
351
    local driver=$1
352
    cname=$(random_string)
353
    content=$(random_string)
354
    local events_backend=$(_additional_events_backend $driver)
355

356
    if [[ -n "${events_backend}" ]]; then
357
        skip_if_remote "remote does not support --events-backend"
358
    fi
359

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"
362

363
    t0=$SECONDS
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
366
    t1=$SECONDS
367
    logs_seen="$output"
368

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!"
373

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"
377

378
    run_podman ${events_backend} rm -t 0 -f $cname
379
}
380

381
@test "podman logs - --until --follow k8s-file" {
382
    _log_test_follow_until k8s-file
383
}
384

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
389

390
    _log_test_follow_until journald
391
}
392

393
# https://github.com/containers/podman/issues/19545
394
@test "podman logs --tail, k8s-file with partial lines" {
395
    cname="tail_container"
396

397
    # "-t" gives us ^Ms (CRs) in the log
398
    run_podman run --name $cname --log-driver k8s-file -t $IMAGE echo hi
399

400
    # Hand-craft a log file with partial lines and carriage returns
401
    run_podman inspect --format '{{.HostConfig.LogConfig.Path}}' $cname
402
    logpath="$output"
403
    timestamp=$(head -n1 "$logpath" | awk '{print $1}')
404
    cr=$'\r'
405
    nl=$'\n'
406
    # Delete, don't overwrite, in case conmon still has the fd open
407
    rm -f $logpath
408
    cat > $logpath <<EOF
409
$timestamp stdout F podman1$cr
410
$timestamp stdout P podman2
411
$timestamp stdout F $cr
412
$timestamp stdout F podman3$cr
413
EOF
414

415
    # FIXME: remove after 2024-01-01 if no more flakes seen.
416
    cat -vET $logpath
417

418
    expect1="podman3${cr}"
419
    expect2="podman2${cr}${nl}podman3${cr}"
420
    expect3="podman1${cr}${nl}podman2${cr}${nl}podman3${cr}"
421

422
    # This always worked
423
    run_podman logs --tail 1 $cname
424
    assert "$output" = "$expect1" "--tail 1"
425

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"
429

430
    # Confirm that we won't overrun
431
    for i in 3 4 5; do
432
        run_podman logs --tail $i $cname
433
        assert "$output" = "$expect3" "--tail $i"
434
    done
435

436
    run_podman rm $cname
437
}
438

439
# vim: filetype=sh
440

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.