Compare commits

..

1 Commits

Author SHA1 Message Date
Matteo Croce 39fb6e8cfe add test for upgrade
Add a basic test to check that systemd works after an upgrade
2025-04-17 14:21:55 +02:00
12 changed files with 51 additions and 52 deletions

View File

@ -25,7 +25,7 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: systemd/mkosi@dbb4020beee2cdf250f93a425794f1cf8b0fe693
- uses: systemd/mkosi@7e4ec15aee6b98300b2ee14265bc647a716a9f8a
# Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space
# immediately, we remove the files in the background. However, we first move them to a different location
@ -90,6 +90,7 @@ jobs:
sudo mkosi sandbox -- \
meson setup \
--buildtype=debugoptimized \
-Dintegration-tests=true \
build
- name: Build image
@ -119,8 +120,7 @@ jobs:
meson test \
-C build \
--no-rebuild \
--setup=integration \
--suite=integration-tests \
--suite integration-tests \
--print-errorlogs \
--no-stdsplit \
--num-processes "$(($(nproc) - 1))" \

View File

@ -120,7 +120,7 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: systemd/mkosi@dbb4020beee2cdf250f93a425794f1cf8b0fe693
- uses: systemd/mkosi@7e4ec15aee6b98300b2ee14265bc647a716a9f8a
# Freeing up disk space with rm -rf can take multiple minutes. Since we don't need the extra free space
# immediately, we remove the files in the background. However, we first move them to a different location
@ -197,6 +197,7 @@ jobs:
sudo mkosi sandbox -- \
meson setup \
--buildtype=debugoptimized \
-Dintegration-tests=true \
-Dbpf-framework=disabled \
build
@ -232,8 +233,7 @@ jobs:
meson test \
-C build \
--no-rebuild \
--setup=integration \
--suite=integration-tests \
--suite integration-tests \
--print-errorlogs \
--no-stdsplit \
--num-processes "$(($(nproc) - 1))" \

View File

@ -13,12 +13,6 @@ project('systemd', 'c',
meson_version : '>= 0.62.0',
)
add_test_setup(
'default',
exclude_suites : ['integration-tests'],
is_default : true,
)
project_major_version = meson.project_version().split('.')[0].split('~')[0]
if meson.project_version().contains('.')
project_minor_version = meson.project_version().split('.')[-1].split('~')[0]
@ -345,6 +339,7 @@ meson_build_sh = find_program('tools/meson-build.sh')
want_tests = get_option('tests')
want_slow_tests = want_tests != 'false' and get_option('slow-tests')
want_fuzz_tests = want_tests != 'false' and get_option('fuzz-tests')
want_integration_tests = want_tests != 'false' and get_option('integration-tests')
install_tests = want_tests != 'false' and get_option('install-tests')
if add_languages('cpp', native : false, required : fuzzer_build)
@ -2666,6 +2661,10 @@ endif
#####################################################################
mkosi = find_program('mkosi', required : false)
if want_integration_tests and not mkosi.found()
error('Could not find mkosi which is required to run the integration tests')
endif
mkosi_depends = public_programs
foreach executable : ['systemd-journal-remote', 'systemd-sbsign', 'systemd-keyutil']

View File

@ -509,7 +509,7 @@ option('install-tests', type : 'boolean', value : false,
description : 'install test executables')
option('log-message-verification', type : 'feature', deprecated : { 'true' : 'enabled', 'false' : 'disabled' },
description : 'do fake printf() calls to verify format strings')
option('integration-tests', type : 'boolean', value : false, deprecated : true,
option('integration-tests', type : 'boolean', value : false,
description : 'run the integration tests')
option('ok-color', type : 'combo',

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
[Config]
MinimumVersion=commit:dbb4020beee2cdf250f93a425794f1cf8b0fe693
MinimumVersion=commit:7e4ec15aee6b98300b2ee14265bc647a716a9f8a
Dependencies=
exitrd
initrd
@ -78,7 +78,8 @@ KernelCommandLine=
oops=panic
panic=-1
softlockup_panic=1
panic_on_warn=1
# Disabled due to BTRFS issue, waiting for the fix to become available
panic_on_warn=0
psi=1
mitigations=off

View File

@ -17,13 +17,8 @@ else
exit 1
fi
curver=$(dnf repoquery "$disable" mkosi --latest-limit=1 --queryformat='%{evr}' systemd)
pkgs=$(dnf repoquery 'systemd*' |grep -F "$curver" |grep -v -e -debuginfo -e -debugsource)
pkgdir=/usr/host-pkgs
distrover=$(dnf repoquery "$disable" mkosi --latest-limit=1 --queryformat='%{evr}' systemd)
develver=$(rpm -q --queryformat='%{evr}' systemd)
# Filter only noarch and arch packages otherwise on CentOS 9 we could end having i686 packages too
distropkgs=$(dnf repoquery 'systemd*' |grep -F "$distrover" |grep -e noarch -e "$DISTRIBUTION_ARCHITECTURE" |grep -v -e -debuginfo -e -debugsource)
develpkgs=$(dnf repoquery 'systemd*' |grep -F "$develver" |grep -e noarch -e "$DISTRIBUTION_ARCHITECTURE" |grep -v -e -debuginfo -e -debugsource)
dnf download --arch noarch --arch "$DISTRIBUTION_ARCHITECTURE" --destdir "$BUILDROOT$pkgdir/distro" $distropkgs
dnf download --arch noarch --arch "$DISTRIBUTION_ARCHITECTURE" --destdir "$BUILDROOT$pkgdir/devel" $develpkgs
dnf download --arch noarch --arch "$DISTRIBUTION_ARCHITECTURE" --destdir "$BUILDROOT$pkgdir" $pkgs

View File

@ -161,10 +161,6 @@ static int socket_recv_message(int fd, void *buf, size_t buf_size, uint32_t *ret
assert(fd >= 0);
assert(peek || (buf && buf_size > 0));
/* Note: this might return successfully, but with a zero size under some transient conditions, such
* as the reception of a non-kernel message. In such a case the passed buffer might or might not be
* modified. Caller must treat a zero return as "no message, but also not an error". */
n = recvmsg_safe(fd, &msg, peek ? (MSG_PEEK|MSG_TRUNC) : 0);
if (ERRNO_IS_NEG_TRANSIENT(n))
goto transient;
@ -183,9 +179,8 @@ static int socket_recv_message(int fd, void *buf, size_t buf_size, uint32_t *ret
if (peek) {
/* Drop the message. Note that we ignore ECHRNG/EXFULL errors here, which
* recvmsg_safe() returns in case the payload or cdata is truncated. Given we just
* want to drop the message we also don't care if its payload or cdata was
* truncated. */
* recvmsg_safe() returns in case the payload or cdata is truncated. Here it's quite
* likely it is truncated, because we pass a zero-sized buffer. */
n = recvmsg_safe(fd, &msg, 0);
if (n < 0 && !IN_SET(n, -ECHRNG, -EXFULL))
return (int) n;

View File

@ -38,14 +38,14 @@ directory (`OutputDirectory=`) to point to the other directory using `mkosi/mkos
After the image has been built, the integration tests can be run with:
```shell
$ mkosi -f sandbox -- meson test -C build --setup=integration --suite integration-tests --num-processes "$(($(nproc) / 4))"
$ env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox -- meson test -C build --suite integration-tests --num-processes "$(($(nproc) / 4))"
```
As usual, specific tests can be run in meson by appending the name of the test
which is usually the name of the directory e.g.
```shell
$ mkosi -f sandbox -- meson test -C build --setup=integration -v TEST-01-BASIC
$ env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox -- meson test -C build -v TEST-01-BASIC
```
See `mkosi -f sandbox -- meson introspect build --tests` for a list of tests.
@ -55,7 +55,7 @@ To interactively debug a failing integration test, the `--interactive` option
newer:
```shell
$ mkosi -f sandbox -- meson test -C build --setup=integration -i TEST-01-BASIC
$ env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox -- meson test -C build -i TEST-01-BASIC
```
Due to limitations in meson, the integration tests do not yet depend on the
@ -64,7 +64,7 @@ running the integration tests. To rebuild the image and rerun a test, the
following command can be used:
```shell
$ mkosi -f sandbox -- meson compile -C build mkosi && mkosi -f sandbox -- meson test -C build --setup=integration -v TEST-01-BASIC
$ mkosi -f sandbox -- meson compile -C build mkosi && env SYSTEMD_INTEGRATION_TESTS=1 mkosi -f sandbox -- meson test -C build -v TEST-01-BASIC
```
The integration tests use the same mkosi configuration that's used when you run
@ -78,7 +78,7 @@ To iterate on an integration test, let's first get a shell in the integration te
the following:
```shell
$ mkosi -f sandbox -- meson compile -C build mkosi && mkosi -f sandbox -- meson test -C build --setup=shell -i TEST-01-BASIC
$ mkosi -f sandbox -- meson compile -C build mkosi && env SYSTEMD_INTEGRATION_TESTS=1 TEST_SHELL=1 mkosi -f sandbox -- meson test -C build -i TEST-01-BASIC
```
This will get us a shell in the integration test environment after booting the machine without running the
@ -107,7 +107,7 @@ re-running the test will first install the new packages we just built, make a ne
the test again. You can keep running the loop of `mkosi -R`, `systemctl soft-reboot` and
`systemctl start ...` until the changes to the integration test are working.
If you're debugging a failing integration test (running `meson test --interactive`),
If you're debugging a failing integration test (running `meson test --interactive` without `TEST_SHELL`),
there's no need to run `systemctl start ...`, running `systemctl soft-reboot` on its own is sufficient to
rerun the test.
@ -120,6 +120,10 @@ rerun the test.
`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)
`TEST_SHELL=1`: Configure the machine to be more *user-friendly* for
interactive debugging (e.g. by setting a usable default terminal, suppressing
the shutdown after the test, etc.).
`TEST_MATCH_SUBTEST=subtest`: If the test makes use of `run_subtests` use this
variable to provide a POSIX extended regex to run only subtests matching the
expression.

View File

@ -361,7 +361,7 @@ def statfs(path: Path) -> str:
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--mkosi', default=None)
parser.add_argument('--mkosi', required=True)
parser.add_argument('--meson-source-dir', required=True, type=Path)
parser.add_argument('--meson-build-dir', required=True, type=Path)
parser.add_argument('--name', required=True)
@ -379,12 +379,6 @@ def main() -> None:
parser.add_argument('mkosi_args', nargs='*')
args = parser.parse_args()
if not args.mkosi:
args.mkosi = shutil.which('mkosi')
if not args.mkosi:
print('Could not find mkosi which is required to run the integration tests', file=sys.stderr)
sys.exit(1)
# The meson source directory can either be the top-level repository directory or the
# test/integration-tests/standalone subdirectory in the repository directory. The mkosi configuration
# will always be a parent directory of one of these directories and at most 4 levels upwards, so don't
@ -401,6 +395,13 @@ def main() -> None:
)
exit(1)
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}',

View File

@ -1,9 +1,5 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# We'd give these more descriptive names but only alphanumeric characters are allowed.
add_test_setup('integration')
add_test_setup('shell', env : {'TEST_SHELL' : '1'})
integration_test_wrapper = find_program('integration-test-wrapper.py')
integration_tests = []
integration_test_template = {
@ -134,11 +130,11 @@ foreach integration_test : integration_tests
integration_test_args += ['--skip']
endif
if mkosi.found()
integration_test_args += ['--mkosi', mkosi.full_path()]
if not mkosi.found()
continue
endif
integration_test_args += ['--']
integration_test_args += ['--mkosi', mkosi.full_path(), '--']
if integration_test['cmdline'].length() > 0
integration_test_args += [
@ -156,12 +152,19 @@ foreach integration_test : integration_tests
integration_test_args += integration_test['mkosi-args']
integration_test_env = {}
if want_integration_tests
integration_test_env += {'SYSTEMD_INTEGRATION_TESTS': '1'}
endif
# We don't explicitly depend on the "mkosi" target because that means the image is rebuilt on every
# "ninja -C build". Instead, the mkosi target has to be rebuilt manually before running the
# integration tests with mkosi.
test(
integration_test['name'],
integration_test_wrapper,
env : integration_test_env,
args : integration_test_args,
timeout : integration_test['timeout'],
priority : integration_test['priority'],

View File

@ -16,6 +16,7 @@ project('systemd-testsuite',
fs = import('fs')
mkosi = find_program('mkosi', required : true)
want_integration_tests = true
# meson refuses .. in subdir() so we use a symlink to trick it into accepting it anyway.
subdir('integration-tests')

View File

@ -26,7 +26,7 @@ else
exit 1
fi
dnf downgrade -y --allowerasing "$disable" '*' "$pkgdir"/distro/*.rpm
dnf downgrade -y --allowerasing "$disable" '*' "$pkgdir"/*.rpm
newminor=$(systemctl --version |awk '/^systemd/{print$2}')
@ -44,7 +44,7 @@ systemctl --failed |grep -Fqx '0 loaded units listed.'
loginctl list-sessions
# Finally test the upgrade
dnf -y upgrade "$disable" '*' "$pkgdir"/devel/*.rpm
dnf -y upgrade $disable '*' "$PACKAGEDIR"/*.rpm
# TODO: sanity checks