1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-21 13:34:21 +03:00

Compare commits

...

13 Commits

Author SHA1 Message Date
Luca Boccassi
398d5a368c mkosi: install util-linux-script in F42 too
(cherry picked from commit 3f86ce166d)
2024-12-20 14:54:07 +00:00
Yu Watanabe
53129f4fc8 github: drop workaround and use distro mold
Now, ubuntu-24.04 has mold-2.30.0+dfsg-1build1 .
See https://packages.ubuntu.com/noble/mold .

(cherry picked from commit f85213e8f6)
2024-12-20 14:02:24 +00:00
Daan De Meyer
6b7cd2dd59 TEST-58-REPART: Always run TEST-58-REPART in virtual machine
Required for various tests in TEST-58-REPART.

(cherry picked from commit d55d756c42)
2024-12-20 12:50:56 +00:00
Daan De Meyer
3258c268ad test: Set kernel loglevel to INFO when running tests unattended
This makes sure all kernel log messages are logged to the console.
This should be helpful during shutdown to detect possible issues with
journald when the logs can't be written to the journal itself anymore
but are written to kmsg.

(cherry picked from commit 8f51cf6981)
2024-12-20 12:50:56 +00:00
Daan De Meyer
e53881298b test: Implement TEST_PREFER_QEMU and use it in one of the mkosi jobs
We want to make sure the integration tests that don't require qemu
can run successfully both in an nspawn container and in a qemu VM.
So let's add one more knob TEST_PREFER_QEMU=1 to run jobs that normally
require nspawn in qemu instead.

Running these tests in qemu is also possible by not running as root but
that's very implicit so we add an explicit knob instead to make it explicit
that we want to run these in qemu instead of nspawn.

(cherry picked from commit e022e73e3f)
2024-12-20 12:50:56 +00:00
Daan De Meyer
7c5fc202a0 test: Fix typing errors in integration-test-wrapper.py
(cherry picked from commit ceca7c5005)
2024-12-20 12:12:19 +00:00
Daan De Meyer
a23279a55f test: Format integration-test-wrapper.py
(cherry picked from commit 4f969b20b0)
2024-12-20 12:12:19 +00:00
Daan De Meyer
e0b6838bc2 integration-test-wrapper: Remove unneeded format strings
(cherry picked from commit 6d2fd490cf)
2024-12-20 12:12:19 +00:00
Luca Boccassi
99fdc0ab68 test: fix TEST_SKIP for test cases with subtests
TEST-64-UDEV-STORAGE is invoked with the subtest appended, so TEST_SKIP=TEST-64-UDEV-STORAGE
does not work. Fix it by using TEST_SKIP as a partial match.

Follow-up for ddc91af4ea

(cherry picked from commit 8f4bbd096b)
2024-12-20 12:12:19 +00:00
Daan De Meyer
9d2e086ab4 test: Set show_status=error
The TEST-64-UDEV-STORAGE tests fail before we even start the test.
Let's set show_status=error to get more information when those failures
happen.

(cherry picked from commit 7560a5393a)
2024-12-20 12:12:19 +00:00
Zbigniew Jędrzejewski-Szmek
3a310b3ef1 mkosi/ci: use a bash array to pass options
This patch initially also changed the configuration, but that'll be done in a
different way, so all that remains is the syntax change.
An array is nicer because the array definition can have inline comments and
doesn't use continuation symbols which are easy to mess up in edits.

(cherry picked from commit f5292d63af)
2024-12-20 12:07:12 +00:00
Yu Watanabe
b2f4e022be test-time-util: fix truncation of usec to sec
Also
- use ASSERT_XYZ() macros,
- log tzname[] on failure.

(cherry picked from commit 3f1d499964)
(cherry picked from commit 11d7050017)
2024-12-20 12:02:45 +00:00
Zbigniew Jędrzejewski-Szmek
f3cdfb1865 test-time-util: do more suppression of time zone checks
The issue is directly triggered by tzdata-2024b, where the setting of timezone
started to fail and the tests stopped passing. But those timestamps in 1/1/1970
appear to have some problems already before:

  $ sudo date -s 'Thu 1970-01-01 13:00:01 WET'
  Thu Jan  1 03:00:01 PM EET 1970
  $ sudo date -s 'Thu 1970-01-01 12:00:01 WET'
  date: cannot set date: Invalid argument
  Thu Jan  1 02:00:01 PM EET 1970
  $ rpm -q tzdata
  tzdata-2024a-9.fc41.noarch

The same issue appears with other timezones. So move the first timestamp one
day forward to avoid the issue.

After the previous problem is solved, we also get the problem already seen
previously where the roundtrip returns a time that is off by one hour:

@86401000000 → Fri 1970-01-02 00:00:01 WET → @82801000000 → Thu 1970-01-01 23:00:01 WET
Assertion 'x / USEC_PER_SEC == y / USEC_PER_SEC' failed at src/test/test-time-util.c:415, function test_format_timestamp_impl(). Aborting.

Extend the override to suppress this.

(cherry picked from commit 3cf362f6f5)
2024-12-20 12:02:37 +00:00
7 changed files with 132 additions and 102 deletions

View File

@ -47,7 +47,7 @@ PACKAGES=(
libxkbcommon-dev
libxtables-dev
libzstd-dev
# mold
mold
mount
net-tools
python3-evdev
@ -70,14 +70,6 @@ LINKER="${LINKER:?}"
CRYPTOLIB="${CRYPTOLIB:?}"
RELEASE="$(lsb_release -cs)"
# mold-2.2.0+ fixes some bugs breaking bootloader builds.
# TODO: Switch to distro mold with ubuntu-24.04
if [[ "$LINKER" == mold ]]; then
wget https://github.com/rui314/mold/releases/download/v2.2.0/mold-2.2.0-x86_64-linux.tar.gz
echo "d66e0230c562c2ba0e0b789cc5034e0fa2369cc843d0154920de4269cd94afeb mold-2.2.0-x86_64-linux.tar.gz" | sha256sum -c
sudo tar -xz -C /usr --strip-components=1 -f mold-2.2.0-x86_64-linux.tar.gz
fi
# Note: As we use postfixed clang/gcc binaries, we need to override $AR
# as well, otherwise meson falls back to ar from binutils which
# doesn't work with LTO

View File

@ -60,48 +60,56 @@ jobs:
llvm: 0
cflags: "-O2 -D_FORTIFY_SOURCE=3"
relabel: no
qemu: 1
- distro: debian
release: testing
sanitizers: ""
llvm: 0
cflags: "-Og"
relabel: no
qemu: 0
- distro: ubuntu
release: noble
sanitizers: ""
llvm: 0
cflags: "-Og"
relabel: no
qemu: 0
- distro: fedora
release: "41"
sanitizers: ""
llvm: 0
cflags: "-Og"
relabel: yes
qemu: 0
- distro: fedora
release: rawhide
sanitizers: address,undefined
llvm: 1
cflags: "-Og"
relabel: yes
qemu: 0
- distro: opensuse
release: tumbleweed
sanitizers: ""
llvm: 0
cflags: "-Og"
relabel: no
qemu: 0
- distro: centos
release: "9"
sanitizers: ""
llvm: 0
cflags: "-Og"
relabel: yes
qemu: 0
- distro: centos
release: "10"
sanitizers: ""
llvm: 0
cflags: "-Og"
relabel: yes
qemu: 0
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
@ -132,6 +140,7 @@ jobs:
run: |
# XXX: drop after the HyperV bug that breaks secure boot KVM guests is solved
sed -i "s/'firmware'\s*:\s*'auto'/'firmware' : 'uefi'/g" test/*/meson.build
tee mkosi.local.conf <<EOF
[Distribution]
Distribution=${{ matrix.distro }}
@ -186,27 +195,30 @@ jobs:
- name: Configure meson
run: |
meson setup build \
--buildtype=debugoptimized \
-Dintegration-tests=true \
-Dremote=enabled \
-Dopenssl=enabled \
-Dblkid=enabled \
-Dtpm2=enabled \
-Dlibcryptsetup=enabled \
-Dlibcurl=enabled \
-Drepart=enabled \
-Dfirstboot=true \
-Dsysusers=true \
-Dtmpfiles=true \
-Dhwdb=true \
OPTIONS=(
--buildtype=debugoptimized
-Dintegration-tests=true
-Dremote=enabled
-Dopenssl=enabled
-Dblkid=enabled
-Dtpm2=enabled
-Dlibcryptsetup=enabled
-Dlibcurl=enabled
-Drepart=enabled
-Dfirstboot=true
-Dsysusers=true
-Dtmpfiles=true
-Dhwdb=true
-Dvmspawn=enabled
)
meson setup build "${OPTIONS[@]}"
- name: Build image
run: sudo meson compile -C build mkosi
- name: Run integration tests
run: sudo --preserve-env meson test -C build --no-rebuild --suite integration-tests --print-errorlogs --no-stdsplit --num-processes "$(($(nproc) - 1))"
run: sudo --preserve-env env TEST_PREFER_QEMU=${{ matrix.qemu }} meson test -C build --no-rebuild --suite integration-tests --print-errorlogs --no-stdsplit --num-processes "$(($(nproc) - 1))"
- name: Archive failed test journals
uses: actions/upload-artifact@v4

View File

@ -1,7 +1,8 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Match]
Release=rawhide
Release=|rawhide
Release=|42
[Content]
Packages=util-linux-script

View File

@ -393,32 +393,37 @@ TEST(format_timestamp) {
static void test_format_timestamp_impl(usec_t x) {
bool success, override;
const char *xx, *yy;
usec_t y;
usec_t y, x_sec, y_sec;
xx = FORMAT_TIMESTAMP(x);
assert_se(xx);
assert_se(parse_timestamp(xx, &y) >= 0);
ASSERT_NOT_NULL(xx);
ASSERT_OK(parse_timestamp(xx, &y));
yy = FORMAT_TIMESTAMP(y);
assert_se(yy);
ASSERT_NOT_NULL(yy);
success = (x / USEC_PER_SEC == y / USEC_PER_SEC) && streq(xx, yy);
/* Workaround for https://github.com/systemd/systemd/issues/28472 */
x_sec = x / USEC_PER_SEC;
y_sec = y / USEC_PER_SEC;
success = (x_sec == y_sec) && streq(xx, yy);
/* Workaround for https://github.com/systemd/systemd/issues/28472
* and https://github.com/systemd/systemd/pull/35471. */
override = !success &&
(STRPTR_IN_SET(tzname[0], "CAT", "EAT") ||
STRPTR_IN_SET(tzname[1], "CAT", "EAT")) &&
DIV_ROUND_UP(y - x, USEC_PER_SEC) == 3600; /* 1 hour, ignore fractional second */
(STRPTR_IN_SET(tzname[0], "CAT", "EAT", "WET") ||
STRPTR_IN_SET(tzname[1], "CAT", "EAT", "WET")) &&
(x_sec > y_sec ? x_sec - y_sec : y_sec - x_sec) == 3600; /* 1 hour, ignore fractional second */
log_full(success ? LOG_DEBUG : override ? LOG_WARNING : LOG_ERR,
"@" USEC_FMT " → %s → @" USEC_FMT " → %s%s",
x, xx, y, yy,
override ? ", ignoring." : "");
if (!override) {
assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC);
if (!success)
log_warning("tzname[0]=\"%s\", tzname[1]=\"%s\"", tzname[0], tzname[1]);
ASSERT_EQ(x_sec, y_sec);
ASSERT_STREQ(xx, yy);
}
}
static void test_format_timestamp_loop(void) {
test_format_timestamp_impl(USEC_PER_SEC);
test_format_timestamp_impl(USEC_PER_DAY + USEC_PER_SEC);
test_format_timestamp_impl(USEC_TIMESTAMP_FORMATTABLE_MAX_32BIT-1);
test_format_timestamp_impl(USEC_TIMESTAMP_FORMATTABLE_MAX_32BIT);
test_format_timestamp_impl(USEC_TIMESTAMP_FORMATTABLE_MAX-1);

View File

@ -199,6 +199,8 @@ $ sudo NO_BUILD=1 test/run-integration-tests
`TEST_PREFER_NSPAWN=1`: Run all tests that do not require qemu under
systemd-nspawn.
`TEST_PREFER_QEMU=1`: Run all tests under qemu.
`TEST_NO_KVM=1`: Disable qemu KVM auto-detection (may be necessary when you're
trying to run the *vanilla* qemu and have both qemu and qemu-kvm installed)

View File

@ -3,5 +3,6 @@
integration_tests += [
integration_test_template + {
'name' : fs.name(meson.current_source_dir()),
'vm' : true,
},
]

View File

@ -1,8 +1,7 @@
#!/usr/bin/python3
# SPDX-License-Identifier: LGPL-2.1-or-later
'''Test wrapper command for driving integration tests.
'''
"""Test wrapper command for driving integration tests."""
import argparse
import json
@ -13,7 +12,6 @@ import sys
import textwrap
from pathlib import Path
EMERGENCY_EXIT_DROPIN = """\
[Unit]
Wants=emergency-exit.service
@ -34,7 +32,7 @@ ExecStart=false
"""
def main():
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--mkosi', required=True)
parser.add_argument('--meson-source-dir', required=True, type=Path)
@ -46,33 +44,43 @@ def main():
parser.add_argument('--slow', action=argparse.BooleanOptionalAction)
parser.add_argument('--vm', action=argparse.BooleanOptionalAction)
parser.add_argument('--exit-code', required=True, type=int)
parser.add_argument('mkosi_args', nargs="*")
parser.add_argument('mkosi_args', nargs='*')
args = parser.parse_args()
if not bool(int(os.getenv("SYSTEMD_INTEGRATION_TESTS", "0"))):
print(f"SYSTEMD_INTEGRATION_TESTS=1 not found in environment, skipping {args.name}", file=sys.stderr)
if not bool(int(os.getenv('SYSTEMD_INTEGRATION_TESTS', '0'))):
print(
f'SYSTEMD_INTEGRATION_TESTS=1 not found in environment, skipping {args.name}',
file=sys.stderr,
)
exit(77)
if args.slow and not bool(int(os.getenv("SYSTEMD_SLOW_TESTS", "0"))):
print(f"SYSTEMD_SLOW_TESTS=1 not found in environment, skipping {args.name}", file=sys.stderr)
if args.slow and not bool(int(os.getenv('SYSTEMD_SLOW_TESTS', '0'))):
print(
f'SYSTEMD_SLOW_TESTS=1 not found in environment, skipping {args.name}',
file=sys.stderr,
)
exit(77)
if args.vm and bool(int(os.getenv("TEST_NO_QEMU", "0"))):
print(f"TEST_NO_QEMU=1, skipping {args.name}", file=sys.stderr)
if args.vm and bool(int(os.getenv('TEST_NO_QEMU', '0'))):
print(f'TEST_NO_QEMU=1, skipping {args.name}', file=sys.stderr)
exit(77)
if args.name in os.getenv("TEST_SKIP", "").split():
print(f"Skipping {args.name} due to TEST_SKIP", file=sys.stderr)
exit(77)
for s in os.getenv('TEST_SKIP', '').split():
if s in args.name:
print(f'Skipping {args.name} due to TEST_SKIP', file=sys.stderr)
exit(77)
keep_journal = os.getenv("TEST_SAVE_JOURNAL", "fail")
shell = bool(int(os.getenv("TEST_SHELL", "0")))
keep_journal = os.getenv('TEST_SAVE_JOURNAL', 'fail')
shell = bool(int(os.getenv('TEST_SHELL', '0')))
if shell and not sys.stderr.isatty():
print(f"--interactive must be passed to meson test to use TEST_SHELL=1", file=sys.stderr)
print(
'--interactive must be passed to meson test to use TEST_SHELL=1',
file=sys.stderr,
)
exit(1)
name = args.name + (f"-{i}" if (i := os.getenv("MESON_TEST_ITERATION")) else "")
name = args.name + (f'-{i}' if (i := os.getenv('MESON_TEST_ITERATION')) else '')
dropin = textwrap.dedent(
"""\
@ -83,14 +91,14 @@ def main():
if not shell:
dropin += textwrap.dedent(
f"""
"""
[Unit]
SuccessAction=exit
SuccessActionExitStatus=123
"""
)
if os.getenv("TEST_MATCH_SUBTEST"):
if os.getenv('TEST_MATCH_SUBTEST'):
dropin += textwrap.dedent(
f"""
[Service]
@ -98,7 +106,7 @@ def main():
"""
)
if os.getenv("TEST_MATCH_TESTCASE"):
if os.getenv('TEST_MATCH_TESTCASE'):
dropin += textwrap.dedent(
f"""
[Service]
@ -115,7 +123,7 @@ def main():
"""
)
journal_file = (args.meson_build_dir / (f"test/journal/{name}.journal")).absolute()
journal_file = (args.meson_build_dir / (f'test/journal/{name}.journal')).absolute()
journal_file.unlink(missing_ok=True)
elif not shell:
dropin += textwrap.dedent(
@ -135,54 +143,61 @@ def main():
*(['--forward-journal', journal_file] if journal_file else []),
*(
[
'--credential',
f"systemd.extra-unit.emergency-exit.service={shlex.quote(EMERGENCY_EXIT_SERVICE)}",
'--credential',
f"systemd.unit-dropin.emergency.target={shlex.quote(EMERGENCY_EXIT_DROPIN)}",
'--credential', f'systemd.extra-unit.emergency-exit.service={shlex.quote(EMERGENCY_EXIT_SERVICE)}', # noqa: E501
'--credential', f'systemd.unit-dropin.emergency.target={shlex.quote(EMERGENCY_EXIT_DROPIN)}',
]
if not sys.stderr.isatty()
else []
),
'--credential',
f"systemd.unit-dropin.{args.unit}={shlex.quote(dropin)}",
'--credential', f'systemd.unit-dropin.{args.unit}={shlex.quote(dropin)}',
'--runtime-network=none',
'--runtime-scratch=no',
*args.mkosi_args,
'--qemu-firmware', args.firmware,
*(['--qemu-kvm', 'no'] if int(os.getenv("TEST_NO_KVM", "0")) else []),
'--qemu-firmware',
args.firmware,
*(['--qemu-kvm', 'no'] if int(os.getenv('TEST_NO_KVM', '0')) else []),
'--kernel-command-line-extra',
' '.join([
'systemd.hostname=H',
f"SYSTEMD_UNIT_PATH=/usr/lib/systemd/tests/testdata/{args.name}.units:/usr/lib/systemd/tests/testdata/units:",
*([f"systemd.unit={args.unit}"] if not shell else []),
'systemd.mask=systemd-networkd-wait-online.service',
*(
[
"systemd.mask=serial-getty@.service",
"systemd.show_status=no",
"systemd.crash_shell=0",
"systemd.crash_action=poweroff",
]
if not sys.stderr.isatty()
else []
),
]),
' '.join(
[
'systemd.hostname=H',
f'SYSTEMD_UNIT_PATH=/usr/lib/systemd/tests/testdata/{args.name}.units:/usr/lib/systemd/tests/testdata/units:',
*([f'systemd.unit={args.unit}'] if not shell else []),
'systemd.mask=systemd-networkd-wait-online.service',
*(
[
'systemd.mask=serial-getty@.service',
'systemd.show_status=error',
'systemd.crash_shell=0',
'systemd.crash_action=poweroff',
'loglevel=6',
]
if not sys.stderr.isatty()
else []
),
]
),
'--credential', f"journal.storage={'persistent' if sys.stderr.isatty() else args.storage}",
*(['--runtime-build-sources=no'] if not sys.stderr.isatty() else []),
'qemu' if args.vm or os.getuid() != 0 else 'boot',
]
'qemu' if args.vm or os.getuid() != 0 or os.getenv('TEST_PREFER_QEMU', '0') == '1' else 'boot',
] # fmt: skip
result = subprocess.run(cmd)
# On Debian/Ubuntu we get a lot of random QEMU crashes. Retry once, and then skip if it fails again.
if args.vm and result.returncode == 247 and args.exit_code != 247:
journal_file.unlink(missing_ok=True)
if journal_file:
journal_file.unlink(missing_ok=True)
result = subprocess.run(cmd)
if args.vm and result.returncode == 247 and args.exit_code != 247:
print(f"Test {args.name} failed due to QEMU crash (error 247), ignoring", file=sys.stderr)
print(
f'Test {args.name} failed due to QEMU crash (error 247), ignoring',
file=sys.stderr,
)
exit(77)
if journal_file and (keep_journal == "0" or (result.returncode in (args.exit_code, 77) and keep_journal == "fail")):
if journal_file and (
keep_journal == '0' or (result.returncode in (args.exit_code, 77) and keep_journal == 'fail')
):
journal_file.unlink(missing_ok=True)
if shell or result.returncode in (args.exit_code, 77):
@ -191,31 +206,33 @@ def main():
if journal_file:
ops = []
if os.getenv("GITHUB_ACTIONS"):
id = os.environ["GITHUB_RUN_ID"]
iteration = os.environ["GITHUB_RUN_ATTEMPT"]
if os.getenv('GITHUB_ACTIONS'):
id = os.environ['GITHUB_RUN_ID']
iteration = os.environ['GITHUB_RUN_ATTEMPT']
j = json.loads(
subprocess.run(
[
args.mkosi,
"--directory", os.fspath(args.meson_source_dir),
"--json",
"summary",
'--directory', os.fspath(args.meson_source_dir),
'--json',
'summary',
],
stdout=subprocess.PIPE,
text=True,
).stdout
)
distribution = j["Images"][-1]["Distribution"]
release = j["Images"][-1]["Release"]
artifact = f"ci-mkosi-{id}-{iteration}-{distribution}-{release}-failed-test-journals"
ops += [f"gh run download {id} --name {artifact} -D ci/{artifact}"]
journal_file = Path(f"ci/{artifact}/test/journal/{name}.journal")
) # fmt: skip
distribution = j['Images'][-1]['Distribution']
release = j['Images'][-1]['Release']
artifact = f'ci-mkosi-{id}-{iteration}-{distribution}-{release}-failed-test-journals'
ops += [f'gh run download {id} --name {artifact} -D ci/{artifact}']
journal_file = Path(f'ci/{artifact}/test/journal/{name}.journal')
ops += [f"journalctl --file {journal_file} --no-hostname -o short-monotonic -u {args.unit} -p info"]
ops += [f'journalctl --file {journal_file} --no-hostname -o short-monotonic -u {args.unit} -p info']
print("Test failed, relevant logs can be viewed with: \n\n"
f"{(' && '.join(ops))}\n", file=sys.stderr)
print(
"Test failed, relevant logs can be viewed with: \n\n" f"{(' && '.join(ops))}\n",
file=sys.stderr,
)
# 0 also means we failed so translate that to a non-zero exit code to mark the test as failed.
exit(result.returncode or 1)