mirror of
https://github.com/systemd/systemd.git
synced 2025-01-03 05:18:09 +03:00
Compare commits
13 Commits
a01cc5a7cb
...
398d5a368c
Author | SHA1 | Date | |
---|---|---|---|
|
398d5a368c | ||
|
53129f4fc8 | ||
|
6b7cd2dd59 | ||
|
3258c268ad | ||
|
e53881298b | ||
|
7c5fc202a0 | ||
|
a23279a55f | ||
|
e0b6838bc2 | ||
|
99fdc0ab68 | ||
|
9d2e086ab4 | ||
|
3a310b3ef1 | ||
|
b2f4e022be | ||
|
f3cdfb1865 |
10
.github/workflows/build_test.sh
vendored
10
.github/workflows/build_test.sh
vendored
@ -47,7 +47,7 @@ PACKAGES=(
|
|||||||
libxkbcommon-dev
|
libxkbcommon-dev
|
||||||
libxtables-dev
|
libxtables-dev
|
||||||
libzstd-dev
|
libzstd-dev
|
||||||
# mold
|
mold
|
||||||
mount
|
mount
|
||||||
net-tools
|
net-tools
|
||||||
python3-evdev
|
python3-evdev
|
||||||
@ -70,14 +70,6 @@ LINKER="${LINKER:?}"
|
|||||||
CRYPTOLIB="${CRYPTOLIB:?}"
|
CRYPTOLIB="${CRYPTOLIB:?}"
|
||||||
RELEASE="$(lsb_release -cs)"
|
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
|
# Note: As we use postfixed clang/gcc binaries, we need to override $AR
|
||||||
# as well, otherwise meson falls back to ar from binutils which
|
# as well, otherwise meson falls back to ar from binutils which
|
||||||
# doesn't work with LTO
|
# doesn't work with LTO
|
||||||
|
42
.github/workflows/mkosi.yml
vendored
42
.github/workflows/mkosi.yml
vendored
@ -60,48 +60,56 @@ jobs:
|
|||||||
llvm: 0
|
llvm: 0
|
||||||
cflags: "-O2 -D_FORTIFY_SOURCE=3"
|
cflags: "-O2 -D_FORTIFY_SOURCE=3"
|
||||||
relabel: no
|
relabel: no
|
||||||
|
qemu: 1
|
||||||
- distro: debian
|
- distro: debian
|
||||||
release: testing
|
release: testing
|
||||||
sanitizers: ""
|
sanitizers: ""
|
||||||
llvm: 0
|
llvm: 0
|
||||||
cflags: "-Og"
|
cflags: "-Og"
|
||||||
relabel: no
|
relabel: no
|
||||||
|
qemu: 0
|
||||||
- distro: ubuntu
|
- distro: ubuntu
|
||||||
release: noble
|
release: noble
|
||||||
sanitizers: ""
|
sanitizers: ""
|
||||||
llvm: 0
|
llvm: 0
|
||||||
cflags: "-Og"
|
cflags: "-Og"
|
||||||
relabel: no
|
relabel: no
|
||||||
|
qemu: 0
|
||||||
- distro: fedora
|
- distro: fedora
|
||||||
release: "41"
|
release: "41"
|
||||||
sanitizers: ""
|
sanitizers: ""
|
||||||
llvm: 0
|
llvm: 0
|
||||||
cflags: "-Og"
|
cflags: "-Og"
|
||||||
relabel: yes
|
relabel: yes
|
||||||
|
qemu: 0
|
||||||
- distro: fedora
|
- distro: fedora
|
||||||
release: rawhide
|
release: rawhide
|
||||||
sanitizers: address,undefined
|
sanitizers: address,undefined
|
||||||
llvm: 1
|
llvm: 1
|
||||||
cflags: "-Og"
|
cflags: "-Og"
|
||||||
relabel: yes
|
relabel: yes
|
||||||
|
qemu: 0
|
||||||
- distro: opensuse
|
- distro: opensuse
|
||||||
release: tumbleweed
|
release: tumbleweed
|
||||||
sanitizers: ""
|
sanitizers: ""
|
||||||
llvm: 0
|
llvm: 0
|
||||||
cflags: "-Og"
|
cflags: "-Og"
|
||||||
relabel: no
|
relabel: no
|
||||||
|
qemu: 0
|
||||||
- distro: centos
|
- distro: centos
|
||||||
release: "9"
|
release: "9"
|
||||||
sanitizers: ""
|
sanitizers: ""
|
||||||
llvm: 0
|
llvm: 0
|
||||||
cflags: "-Og"
|
cflags: "-Og"
|
||||||
relabel: yes
|
relabel: yes
|
||||||
|
qemu: 0
|
||||||
- distro: centos
|
- distro: centos
|
||||||
release: "10"
|
release: "10"
|
||||||
sanitizers: ""
|
sanitizers: ""
|
||||||
llvm: 0
|
llvm: 0
|
||||||
cflags: "-Og"
|
cflags: "-Og"
|
||||||
relabel: yes
|
relabel: yes
|
||||||
|
qemu: 0
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
|
||||||
@ -132,6 +140,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
# XXX: drop after the HyperV bug that breaks secure boot KVM guests is solved
|
# 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
|
sed -i "s/'firmware'\s*:\s*'auto'/'firmware' : 'uefi'/g" test/*/meson.build
|
||||||
|
|
||||||
tee mkosi.local.conf <<EOF
|
tee mkosi.local.conf <<EOF
|
||||||
[Distribution]
|
[Distribution]
|
||||||
Distribution=${{ matrix.distro }}
|
Distribution=${{ matrix.distro }}
|
||||||
@ -186,27 +195,30 @@ jobs:
|
|||||||
|
|
||||||
- name: Configure meson
|
- name: Configure meson
|
||||||
run: |
|
run: |
|
||||||
meson setup build \
|
OPTIONS=(
|
||||||
--buildtype=debugoptimized \
|
--buildtype=debugoptimized
|
||||||
-Dintegration-tests=true \
|
-Dintegration-tests=true
|
||||||
-Dremote=enabled \
|
-Dremote=enabled
|
||||||
-Dopenssl=enabled \
|
-Dopenssl=enabled
|
||||||
-Dblkid=enabled \
|
-Dblkid=enabled
|
||||||
-Dtpm2=enabled \
|
-Dtpm2=enabled
|
||||||
-Dlibcryptsetup=enabled \
|
-Dlibcryptsetup=enabled
|
||||||
-Dlibcurl=enabled \
|
-Dlibcurl=enabled
|
||||||
-Drepart=enabled \
|
-Drepart=enabled
|
||||||
-Dfirstboot=true \
|
-Dfirstboot=true
|
||||||
-Dsysusers=true \
|
-Dsysusers=true
|
||||||
-Dtmpfiles=true \
|
-Dtmpfiles=true
|
||||||
-Dhwdb=true \
|
-Dhwdb=true
|
||||||
-Dvmspawn=enabled
|
-Dvmspawn=enabled
|
||||||
|
)
|
||||||
|
|
||||||
|
meson setup build "${OPTIONS[@]}"
|
||||||
|
|
||||||
- name: Build image
|
- name: Build image
|
||||||
run: sudo meson compile -C build mkosi
|
run: sudo meson compile -C build mkosi
|
||||||
|
|
||||||
- name: Run integration tests
|
- 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
|
- name: Archive failed test journals
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
[Match]
|
[Match]
|
||||||
Release=rawhide
|
Release=|rawhide
|
||||||
|
Release=|42
|
||||||
|
|
||||||
[Content]
|
[Content]
|
||||||
Packages=util-linux-script
|
Packages=util-linux-script
|
@ -393,32 +393,37 @@ TEST(format_timestamp) {
|
|||||||
static void test_format_timestamp_impl(usec_t x) {
|
static void test_format_timestamp_impl(usec_t x) {
|
||||||
bool success, override;
|
bool success, override;
|
||||||
const char *xx, *yy;
|
const char *xx, *yy;
|
||||||
usec_t y;
|
usec_t y, x_sec, y_sec;
|
||||||
|
|
||||||
xx = FORMAT_TIMESTAMP(x);
|
xx = FORMAT_TIMESTAMP(x);
|
||||||
assert_se(xx);
|
ASSERT_NOT_NULL(xx);
|
||||||
assert_se(parse_timestamp(xx, &y) >= 0);
|
ASSERT_OK(parse_timestamp(xx, &y));
|
||||||
yy = FORMAT_TIMESTAMP(y);
|
yy = FORMAT_TIMESTAMP(y);
|
||||||
assert_se(yy);
|
ASSERT_NOT_NULL(yy);
|
||||||
|
|
||||||
success = (x / USEC_PER_SEC == y / USEC_PER_SEC) && streq(xx, yy);
|
x_sec = x / USEC_PER_SEC;
|
||||||
/* Workaround for https://github.com/systemd/systemd/issues/28472 */
|
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 &&
|
override = !success &&
|
||||||
(STRPTR_IN_SET(tzname[0], "CAT", "EAT") ||
|
(STRPTR_IN_SET(tzname[0], "CAT", "EAT", "WET") ||
|
||||||
STRPTR_IN_SET(tzname[1], "CAT", "EAT")) &&
|
STRPTR_IN_SET(tzname[1], "CAT", "EAT", "WET")) &&
|
||||||
DIV_ROUND_UP(y - x, USEC_PER_SEC) == 3600; /* 1 hour, ignore fractional second */
|
(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,
|
log_full(success ? LOG_DEBUG : override ? LOG_WARNING : LOG_ERR,
|
||||||
"@" USEC_FMT " → %s → @" USEC_FMT " → %s%s",
|
"@" USEC_FMT " → %s → @" USEC_FMT " → %s%s",
|
||||||
x, xx, y, yy,
|
x, xx, y, yy,
|
||||||
override ? ", ignoring." : "");
|
override ? ", ignoring." : "");
|
||||||
if (!override) {
|
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);
|
ASSERT_STREQ(xx, yy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_format_timestamp_loop(void) {
|
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-1);
|
||||||
test_format_timestamp_impl(USEC_TIMESTAMP_FORMATTABLE_MAX_32BIT);
|
test_format_timestamp_impl(USEC_TIMESTAMP_FORMATTABLE_MAX_32BIT);
|
||||||
test_format_timestamp_impl(USEC_TIMESTAMP_FORMATTABLE_MAX-1);
|
test_format_timestamp_impl(USEC_TIMESTAMP_FORMATTABLE_MAX-1);
|
||||||
|
@ -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
|
`TEST_PREFER_NSPAWN=1`: Run all tests that do not require qemu under
|
||||||
systemd-nspawn.
|
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
|
`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)
|
trying to run the *vanilla* qemu and have both qemu and qemu-kvm installed)
|
||||||
|
|
||||||
|
@ -3,5 +3,6 @@
|
|||||||
integration_tests += [
|
integration_tests += [
|
||||||
integration_test_template + {
|
integration_test_template + {
|
||||||
'name' : fs.name(meson.current_source_dir()),
|
'name' : fs.name(meson.current_source_dir()),
|
||||||
|
'vm' : true,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
# 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 argparse
|
||||||
import json
|
import json
|
||||||
@ -13,7 +12,6 @@ import sys
|
|||||||
import textwrap
|
import textwrap
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
EMERGENCY_EXIT_DROPIN = """\
|
EMERGENCY_EXIT_DROPIN = """\
|
||||||
[Unit]
|
[Unit]
|
||||||
Wants=emergency-exit.service
|
Wants=emergency-exit.service
|
||||||
@ -34,7 +32,7 @@ ExecStart=false
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main() -> None:
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
parser.add_argument('--mkosi', required=True)
|
parser.add_argument('--mkosi', required=True)
|
||||||
parser.add_argument('--meson-source-dir', required=True, type=Path)
|
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('--slow', action=argparse.BooleanOptionalAction)
|
||||||
parser.add_argument('--vm', action=argparse.BooleanOptionalAction)
|
parser.add_argument('--vm', action=argparse.BooleanOptionalAction)
|
||||||
parser.add_argument('--exit-code', required=True, type=int)
|
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()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if not bool(int(os.getenv("SYSTEMD_INTEGRATION_TESTS", "0"))):
|
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)
|
print(
|
||||||
|
f'SYSTEMD_INTEGRATION_TESTS=1 not found in environment, skipping {args.name}',
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
exit(77)
|
exit(77)
|
||||||
|
|
||||||
if args.slow and not bool(int(os.getenv("SYSTEMD_SLOW_TESTS", "0"))):
|
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)
|
print(
|
||||||
|
f'SYSTEMD_SLOW_TESTS=1 not found in environment, skipping {args.name}',
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
exit(77)
|
exit(77)
|
||||||
|
|
||||||
if args.vm and bool(int(os.getenv("TEST_NO_QEMU", "0"))):
|
if args.vm and bool(int(os.getenv('TEST_NO_QEMU', '0'))):
|
||||||
print(f"TEST_NO_QEMU=1, skipping {args.name}", file=sys.stderr)
|
print(f'TEST_NO_QEMU=1, skipping {args.name}', file=sys.stderr)
|
||||||
exit(77)
|
exit(77)
|
||||||
|
|
||||||
if args.name in os.getenv("TEST_SKIP", "").split():
|
for s in os.getenv('TEST_SKIP', '').split():
|
||||||
print(f"Skipping {args.name} due to TEST_SKIP", file=sys.stderr)
|
if s in args.name:
|
||||||
exit(77)
|
print(f'Skipping {args.name} due to TEST_SKIP', file=sys.stderr)
|
||||||
|
exit(77)
|
||||||
|
|
||||||
keep_journal = os.getenv("TEST_SAVE_JOURNAL", "fail")
|
keep_journal = os.getenv('TEST_SAVE_JOURNAL', 'fail')
|
||||||
shell = bool(int(os.getenv("TEST_SHELL", "0")))
|
shell = bool(int(os.getenv('TEST_SHELL', '0')))
|
||||||
|
|
||||||
if shell and not sys.stderr.isatty():
|
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)
|
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(
|
dropin = textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
@ -83,14 +91,14 @@ def main():
|
|||||||
|
|
||||||
if not shell:
|
if not shell:
|
||||||
dropin += textwrap.dedent(
|
dropin += textwrap.dedent(
|
||||||
f"""
|
"""
|
||||||
[Unit]
|
[Unit]
|
||||||
SuccessAction=exit
|
SuccessAction=exit
|
||||||
SuccessActionExitStatus=123
|
SuccessActionExitStatus=123
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
if os.getenv("TEST_MATCH_SUBTEST"):
|
if os.getenv('TEST_MATCH_SUBTEST'):
|
||||||
dropin += textwrap.dedent(
|
dropin += textwrap.dedent(
|
||||||
f"""
|
f"""
|
||||||
[Service]
|
[Service]
|
||||||
@ -98,7 +106,7 @@ def main():
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
if os.getenv("TEST_MATCH_TESTCASE"):
|
if os.getenv('TEST_MATCH_TESTCASE'):
|
||||||
dropin += textwrap.dedent(
|
dropin += textwrap.dedent(
|
||||||
f"""
|
f"""
|
||||||
[Service]
|
[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)
|
journal_file.unlink(missing_ok=True)
|
||||||
elif not shell:
|
elif not shell:
|
||||||
dropin += textwrap.dedent(
|
dropin += textwrap.dedent(
|
||||||
@ -135,54 +143,61 @@ def main():
|
|||||||
*(['--forward-journal', journal_file] if journal_file else []),
|
*(['--forward-journal', journal_file] if journal_file else []),
|
||||||
*(
|
*(
|
||||||
[
|
[
|
||||||
'--credential',
|
'--credential', f'systemd.extra-unit.emergency-exit.service={shlex.quote(EMERGENCY_EXIT_SERVICE)}', # noqa: E501
|
||||||
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.unit-dropin.emergency.target={shlex.quote(EMERGENCY_EXIT_DROPIN)}",
|
|
||||||
]
|
]
|
||||||
if not sys.stderr.isatty()
|
if not sys.stderr.isatty()
|
||||||
else []
|
else []
|
||||||
),
|
),
|
||||||
'--credential',
|
'--credential', f'systemd.unit-dropin.{args.unit}={shlex.quote(dropin)}',
|
||||||
f"systemd.unit-dropin.{args.unit}={shlex.quote(dropin)}",
|
|
||||||
'--runtime-network=none',
|
'--runtime-network=none',
|
||||||
'--runtime-scratch=no',
|
'--runtime-scratch=no',
|
||||||
*args.mkosi_args,
|
*args.mkosi_args,
|
||||||
'--qemu-firmware', args.firmware,
|
'--qemu-firmware',
|
||||||
*(['--qemu-kvm', 'no'] if int(os.getenv("TEST_NO_KVM", "0")) else []),
|
args.firmware,
|
||||||
|
*(['--qemu-kvm', 'no'] if int(os.getenv('TEST_NO_KVM', '0')) else []),
|
||||||
'--kernel-command-line-extra',
|
'--kernel-command-line-extra',
|
||||||
' '.join([
|
' '.join(
|
||||||
'systemd.hostname=H',
|
[
|
||||||
f"SYSTEMD_UNIT_PATH=/usr/lib/systemd/tests/testdata/{args.name}.units:/usr/lib/systemd/tests/testdata/units:",
|
'systemd.hostname=H',
|
||||||
*([f"systemd.unit={args.unit}"] if not shell else []),
|
f'SYSTEMD_UNIT_PATH=/usr/lib/systemd/tests/testdata/{args.name}.units:/usr/lib/systemd/tests/testdata/units:',
|
||||||
'systemd.mask=systemd-networkd-wait-online.service',
|
*([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.mask=serial-getty@.service',
|
||||||
"systemd.crash_shell=0",
|
'systemd.show_status=error',
|
||||||
"systemd.crash_action=poweroff",
|
'systemd.crash_shell=0',
|
||||||
]
|
'systemd.crash_action=poweroff',
|
||||||
if not sys.stderr.isatty()
|
'loglevel=6',
|
||||||
else []
|
]
|
||||||
),
|
if not sys.stderr.isatty()
|
||||||
]),
|
else []
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
'--credential', f"journal.storage={'persistent' if sys.stderr.isatty() else args.storage}",
|
'--credential', f"journal.storage={'persistent' if sys.stderr.isatty() else args.storage}",
|
||||||
*(['--runtime-build-sources=no'] if not sys.stderr.isatty() else []),
|
*(['--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)
|
result = subprocess.run(cmd)
|
||||||
|
|
||||||
# On Debian/Ubuntu we get a lot of random QEMU crashes. Retry once, and then skip if it fails again.
|
# 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:
|
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)
|
result = subprocess.run(cmd)
|
||||||
if args.vm and result.returncode == 247 and args.exit_code != 247:
|
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)
|
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)
|
journal_file.unlink(missing_ok=True)
|
||||||
|
|
||||||
if shell or result.returncode in (args.exit_code, 77):
|
if shell or result.returncode in (args.exit_code, 77):
|
||||||
@ -191,31 +206,33 @@ def main():
|
|||||||
if journal_file:
|
if journal_file:
|
||||||
ops = []
|
ops = []
|
||||||
|
|
||||||
if os.getenv("GITHUB_ACTIONS"):
|
if os.getenv('GITHUB_ACTIONS'):
|
||||||
id = os.environ["GITHUB_RUN_ID"]
|
id = os.environ['GITHUB_RUN_ID']
|
||||||
iteration = os.environ["GITHUB_RUN_ATTEMPT"]
|
iteration = os.environ['GITHUB_RUN_ATTEMPT']
|
||||||
j = json.loads(
|
j = json.loads(
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
[
|
[
|
||||||
args.mkosi,
|
args.mkosi,
|
||||||
"--directory", os.fspath(args.meson_source_dir),
|
'--directory', os.fspath(args.meson_source_dir),
|
||||||
"--json",
|
'--json',
|
||||||
"summary",
|
'summary',
|
||||||
],
|
],
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
text=True,
|
text=True,
|
||||||
).stdout
|
).stdout
|
||||||
)
|
) # fmt: skip
|
||||||
distribution = j["Images"][-1]["Distribution"]
|
distribution = j['Images'][-1]['Distribution']
|
||||||
release = j["Images"][-1]["Release"]
|
release = j['Images'][-1]['Release']
|
||||||
artifact = f"ci-mkosi-{id}-{iteration}-{distribution}-{release}-failed-test-journals"
|
artifact = f'ci-mkosi-{id}-{iteration}-{distribution}-{release}-failed-test-journals'
|
||||||
ops += [f"gh run download {id} --name {artifact} -D ci/{artifact}"]
|
ops += [f'gh run download {id} --name {artifact} -D ci/{artifact}']
|
||||||
journal_file = Path(f"ci/{artifact}/test/journal/{name}.journal")
|
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"
|
print(
|
||||||
f"{(' && '.join(ops))}\n", file=sys.stderr)
|
"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.
|
# 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)
|
exit(result.returncode or 1)
|
||||||
|
Loading…
Reference in New Issue
Block a user