1#!/usr/bin/env bash
2# SPDX-License-Identifier: LGPL-2.1-or-later
3set -eux
4set -o pipefail
5
6# Limit the maximum journal size
7trap "journalctl --rotate --vacuum-size=16M" EXIT
8
9# Rotation/flush test, see https://github.com/systemd/systemd/issues/19895
10journalctl --relinquish-var
11for _ in {0..50}; do
12    dd if=/dev/urandom bs=1M count=1 | base64 | systemd-cat
13done
14journalctl --rotate
15journalctl --flush
16journalctl --sync
17
18# Reset the ratelimit buckets for the subsequent tests below.
19systemctl restart systemd-journald
20
21# Test stdout stream
22
23# Skip empty lines
24ID=$(journalctl --new-id128 | sed -n 2p)
25: >/expected
26printf $'\n\n\n' | systemd-cat -t "$ID" --level-prefix false
27journalctl --sync
28journalctl -b -o cat -t "$ID" >/output
29cmp /expected /output
30
31ID=$(journalctl --new-id128 | sed -n 2p)
32: >/expected
33printf $'<5>\n<6>\n<7>\n' | systemd-cat -t "$ID" --level-prefix true
34journalctl --sync
35journalctl -b -o cat -t "$ID" >/output
36cmp /expected /output
37
38# Remove trailing spaces
39ID=$(journalctl --new-id128 | sed -n 2p)
40printf "Trailing spaces\n">/expected
41printf $'<5>Trailing spaces \t \n' | systemd-cat -t "$ID" --level-prefix true
42journalctl --sync
43journalctl -b -o cat -t "$ID" >/output
44cmp /expected /output
45
46ID=$(journalctl --new-id128 | sed -n 2p)
47printf "Trailing spaces\n">/expected
48printf $'Trailing spaces \t \n' | systemd-cat -t "$ID" --level-prefix false
49journalctl --sync
50journalctl -b -o cat -t "$ID" >/output
51cmp /expected /output
52
53# Don't remove leading spaces
54ID=$(journalctl --new-id128 | sed -n 2p)
55printf $' \t Leading spaces\n'>/expected
56printf $'<5> \t Leading spaces\n' | systemd-cat -t "$ID" --level-prefix true
57journalctl --sync
58journalctl -b -o cat -t "$ID" >/output
59cmp /expected /output
60
61ID=$(journalctl --new-id128 | sed -n 2p)
62printf $' \t Leading spaces\n'>/expected
63printf $' \t Leading spaces\n' | systemd-cat -t "$ID" --level-prefix false
64journalctl --sync
65journalctl -b -o cat -t "$ID" >/output
66cmp /expected /output
67
68# --output-fields restricts output
69ID=$(journalctl --new-id128 | sed -n 2p)
70printf $'foo' | systemd-cat -t "$ID" --level-prefix false
71journalctl --sync
72journalctl -b -o export --output-fields=MESSAGE,FOO --output-fields=PRIORITY,MESSAGE -t "$ID" >/output
73[[ $(grep -c . /output) -eq 6 ]]
74grep -q '^__CURSOR=' /output
75grep -q '^MESSAGE=foo$' /output
76grep -q '^PRIORITY=6$' /output
77grep '^FOO=' /output && { echo 'unexpected success'; exit 1; }
78grep '^SYSLOG_FACILITY=' /output && { echo 'unexpected success'; exit 1; }
79
80# `-b all` negates earlier use of -b (-b and -m are otherwise exclusive)
81journalctl -b -1 -b all -m >/dev/null
82
83# -b always behaves like -b0
84journalctl -q -b-1 -b0 | head -1 >/expected
85journalctl -q -b-1 -b  | head -1 >/output
86cmp /expected /output
87# ... even when another option follows (both of these should fail due to -m)
88{ journalctl -ball -b0 -m 2>&1 || :; } | head -1 >/expected
89{ journalctl -ball -b  -m 2>&1 || :; } | head -1 >/output
90cmp /expected /output
91
92# https://github.com/systemd/systemd/issues/13708
93ID=$(systemd-id128 new)
94systemd-cat -t "$ID" bash -c 'echo parent; (echo child) & wait' &
95PID=$!
96wait %%
97journalctl --sync
98# We can drop this grep when https://github.com/systemd/systemd/issues/13937
99# has a fix.
100journalctl -b -o export -t "$ID" --output-fields=_PID | grep '^_PID=' >/output
101[[ $(grep -c . /output) -eq 2 ]]
102grep -q "^_PID=$PID" /output
103grep -vq "^_PID=$PID" /output
104
105# https://github.com/systemd/systemd/issues/15654
106ID=$(journalctl --new-id128 | sed -n 2p)
107printf "This will\nusually fail\nand be truncated\n">/expected
108systemd-cat -t "$ID" /bin/sh -c 'env echo -n "This will";echo;env echo -n "usually fail";echo;env echo -n "and be truncated";echo;'
109journalctl --sync
110journalctl -b -o cat -t "$ID" >/output
111cmp /expected /output
112[[ $(journalctl -b -o cat -t "$ID" --output-fields=_TRANSPORT | grep -Pc "^stdout$") -eq 3 ]]
113[[ $(journalctl -b -o cat -t "$ID" --output-fields=_LINE_BREAK | grep -Pc "^pid-change$") -eq 3 ]]
114[[ $(journalctl -b -o cat -t "$ID" --output-fields=_PID | sort -u | grep -c "^.*$") -eq 3 ]]
115[[ $(journalctl -b -o cat -t "$ID" --output-fields=MESSAGE | grep -Pc "^(This will|usually fail|and be truncated)$") -eq 3 ]]
116
117# test that LogLevelMax can also suppress logging about services, not only by services
118systemctl start silent-success
119journalctl --sync
120[[ -z "$(journalctl -b -q -u silent-success.service)" ]]
121
122# Add new tests before here, the journald restarts below
123# may make tests flappy.
124
125# Don't lose streams on restart
126systemctl start forever-print-hola
127sleep 3
128systemctl restart systemd-journald
129sleep 3
130systemctl stop forever-print-hola
131[[ ! -f "/i-lose-my-logs" ]]
132
133# https://github.com/systemd/systemd/issues/4408
134rm -f /i-lose-my-logs
135systemctl start forever-print-hola
136sleep 3
137systemctl kill --signal=SIGKILL systemd-journald
138sleep 3
139[[ ! -f "/i-lose-my-logs" ]]
140
141# https://github.com/systemd/systemd/issues/15528
142journalctl --follow --file=/var/log/journal/*/* | head -n1 || [[ $? -eq 1 ]]
143
144touch /testok
145