From 4b8edc68f9f4111ccb5ba40c048431874ce8afab Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 24 Feb 2025 22:24:52 +0100 Subject: [PATCH 1/5] mkosi: Update to latest --- .github/workflows/coverage.yml | 2 +- .github/workflows/mkosi.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 81ba85fe27..6c505c6074 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -25,7 +25,7 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: systemd/mkosi@13eb5b68bd5fb234dd0da3b242d80954faf91b95 + - uses: systemd/mkosi@87c540a5cf9fe24bb79fa946b9617d10e7f02b7e # 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 diff --git a/.github/workflows/mkosi.yml b/.github/workflows/mkosi.yml index 6ed7a48efa..69bbb6f6b8 100644 --- a/.github/workflows/mkosi.yml +++ b/.github/workflows/mkosi.yml @@ -120,7 +120,7 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: systemd/mkosi@13eb5b68bd5fb234dd0da3b242d80954faf91b95 + - uses: systemd/mkosi@87c540a5cf9fe24bb79fa946b9617d10e7f02b7e # 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 From 2db2cb3034e71600d25ab1c181f692265d3833fe Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 24 Feb 2025 17:12:22 +0100 Subject: [PATCH 2/5] TEST-53-ISSUE-16347: Implement rtc via custom argument Let's get rid of the configure script for this use case by just implementing the necessary logic in integration-test-wrapper.py. We need to get rid of our usage of configure scripts to allow enabling the History= setting. --- test/TEST-53-ISSUE-16347/meson.build | 4 +--- test/TEST-53-ISSUE-16347/mkosi.configure | 6 ------ test/integration-test-wrapper.py | 13 +++++++++++++ test/meson.build | 5 +++++ 4 files changed, 19 insertions(+), 9 deletions(-) delete mode 100755 test/TEST-53-ISSUE-16347/mkosi.configure diff --git a/test/TEST-53-ISSUE-16347/meson.build b/test/TEST-53-ISSUE-16347/meson.build index 4c764a21c3..cb9e6a6d4e 100644 --- a/test/TEST-53-ISSUE-16347/meson.build +++ b/test/TEST-53-ISSUE-16347/meson.build @@ -3,9 +3,7 @@ integration_tests += [ integration_test_template + { 'name' : fs.name(meson.current_source_dir()), - 'mkosi-args' : integration_test_template['mkosi-args'] + [ - '--configure-script', meson.current_source_dir() / 'mkosi.configure', - ], + 'rtc' : true, 'vm' : true, }, ] diff --git a/test/TEST-53-ISSUE-16347/mkosi.configure b/test/TEST-53-ISSUE-16347/mkosi.configure deleted file mode 100755 index d754fe46e2..0000000000 --- a/test/TEST-53-ISSUE-16347/mkosi.configure +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: LGPL-2.1-or-later -set -e - -RTC="$(date -u +%Y-%m-%dT%H:%M:%S -d "+3 days")" -jq ".QemuArgs += [\"-rtc\", \"base=$RTC\"]" diff --git a/test/integration-test-wrapper.py b/test/integration-test-wrapper.py index 746c0f98d9..7dac8998c8 100755 --- a/test/integration-test-wrapper.py +++ b/test/integration-test-wrapper.py @@ -6,6 +6,7 @@ import argparse import base64 import dataclasses +import datetime import json import os import re @@ -363,6 +364,7 @@ def main() -> None: parser.add_argument('--exit-code', required=True, type=int) parser.add_argument('--coredump-exclude-regex', required=True) parser.add_argument('--sanitizer-exclude-regex', required=True) + parser.add_argument('--rtc', action=argparse.BooleanOptionalAction) parser.add_argument('mkosi_args', nargs='*') args = parser.parse_args() @@ -466,6 +468,16 @@ def main() -> None: """ ) + if args.rtc: + if sys.version_info >= (3, 12): + now = datetime.datetime.now(datetime.UTC) + else: + now = datetime.datetime.utcnow() + + rtc = datetime.datetime.strftime(now, r'%Y-%m-%dT%H:%M:%S') + else: + rtc = None + cmd = [ args.mkosi, '--directory', os.fspath(args.meson_source_dir), @@ -485,6 +497,7 @@ def main() -> None: '--credential', f'systemd.unit-dropin.{args.unit}={shlex.quote(dropin)}', '--runtime-network=none', '--runtime-scratch=no', + *([f'--qemu-args=-rtc base={rtc}'] if rtc else []), *args.mkosi_args, '--firmware', args.firmware, *(['--kvm', 'no'] if int(os.getenv('TEST_NO_KVM', '0')) else []), diff --git a/test/meson.build b/test/meson.build index f2fb5f79ce..39dbc80b66 100644 --- a/test/meson.build +++ b/test/meson.build @@ -299,6 +299,7 @@ integration_test_template = { 'vm' : false, 'coredump-exclude-regex' : '', 'sanitizer-exclude-regex' : '', + 'rtc' : false, } testdata_subdirs = [ 'auxv', @@ -417,6 +418,10 @@ foreach integration_test : integration_tests integration_test_args += ['--vm'] endif + if integration_test['rtc'] + integration_test_args += ['--rtc'] + endif + if not mkosi.found() continue endif From ba29de84cf3967ac3b06707348493d5ddc65c7d8 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 24 Feb 2025 17:14:01 +0100 Subject: [PATCH 3/5] TEST-64-UDEV-STORAGE: Stop using mkosi configure scripts Now that we have mkosi sandbox, meson runs with the mkosi tools tree mounted (if one is used at all), so we can implement all the qemu feature checks in meson itself, removing the need for mkosi configure scripts. --- .../btrfs_basic.configure | 26 -- test/TEST-64-UDEV-STORAGE/iscsi_lvm.configure | 26 -- .../long_sysfs_path.configure | 31 --- test/TEST-64-UDEV-STORAGE/lvm_basic.configure | 25 -- .../mdadm_basic.configure | 25 -- test/TEST-64-UDEV-STORAGE/mdadm_lvm.configure | 25 -- test/TEST-64-UDEV-STORAGE/meson.build | 260 ++++++++++++++++-- .../multipath_basic_failover.configure | 31 --- .../TEST-64-UDEV-STORAGE/nvme_basic.configure | 40 --- .../nvme_subsystem.configure | 40 --- .../simultaneous_events.configure | 21 -- .../virtio_scsi_basic.configure | 28 -- ...csi_identically_named_partitions.configure | 34 --- 13 files changed, 241 insertions(+), 371 deletions(-) delete mode 100755 test/TEST-64-UDEV-STORAGE/btrfs_basic.configure delete mode 100755 test/TEST-64-UDEV-STORAGE/iscsi_lvm.configure delete mode 100755 test/TEST-64-UDEV-STORAGE/long_sysfs_path.configure delete mode 100755 test/TEST-64-UDEV-STORAGE/lvm_basic.configure delete mode 100755 test/TEST-64-UDEV-STORAGE/mdadm_basic.configure delete mode 100755 test/TEST-64-UDEV-STORAGE/mdadm_lvm.configure delete mode 100755 test/TEST-64-UDEV-STORAGE/multipath_basic_failover.configure delete mode 100755 test/TEST-64-UDEV-STORAGE/nvme_basic.configure delete mode 100755 test/TEST-64-UDEV-STORAGE/nvme_subsystem.configure delete mode 100755 test/TEST-64-UDEV-STORAGE/simultaneous_events.configure delete mode 100755 test/TEST-64-UDEV-STORAGE/virtio_scsi_basic.configure delete mode 100755 test/TEST-64-UDEV-STORAGE/virtio_scsi_identically_named_partitions.configure diff --git a/test/TEST-64-UDEV-STORAGE/btrfs_basic.configure b/test/TEST-64-UDEV-STORAGE/btrfs_basic.configure deleted file mode 100755 index 85ec983fc3..0000000000 --- a/test/TEST-64-UDEV-STORAGE/btrfs_basic.configure +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: LGPL-2.1-or-later - -import json -import sys - - -config = json.load(sys.stdin) - -config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0"] - -for i in range(4): - id = f"drivebtrfsbasic{i}" - config["Drives"] += [ - { - "Id": id, - "Size": "350M" if i == 0 else "128M", - "Options": "cache=unsafe", - } - ] - config["QemuArgs"] += [ - "-device", - f"scsi-hd,drive={id},vendor=systemd,product=foobar,serial=deadbeefbtrfs{i}", - ] - -json.dump(config, sys.stdout) diff --git a/test/TEST-64-UDEV-STORAGE/iscsi_lvm.configure b/test/TEST-64-UDEV-STORAGE/iscsi_lvm.configure deleted file mode 100755 index 1d7a0c5b9a..0000000000 --- a/test/TEST-64-UDEV-STORAGE/iscsi_lvm.configure +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: LGPL-2.1-or-later - -import json -import sys - - -config = json.load(sys.stdin) - -config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0"] - -for i in range(4): - id = f"driveiscsibasic{i}" - config["Drives"] += [ - { - "Id": id, - "Size": "150M" if i == 0 else "70M", - "Options": "cache=unsafe", - } - ] - config["QemuArgs"] += [ - "-device", - f"scsi-hd,drive={id},vendor=systemd,product=foobar,serial=deadbeefiscsi{i}", - ] - -json.dump(config, sys.stdout) diff --git a/test/TEST-64-UDEV-STORAGE/long_sysfs_path.configure b/test/TEST-64-UDEV-STORAGE/long_sysfs_path.configure deleted file mode 100755 index a920171add..0000000000 --- a/test/TEST-64-UDEV-STORAGE/long_sysfs_path.configure +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: LGPL-2.1-or-later - -import json -import sys - - -config = json.load(sys.stdin) - -config["Drives"] += [ - { - "Id": "drive0", - "Size": "64M", - "Options": "cache=unsafe", - } -] -config["QemuArgs"] += ["-device", "pci-bridge,id=pci_bridge0,chassis_nr=64"] - -# Create 25 additional PCI bridges, each one connected to the previous one -# (basically a really long extension cable), and attach a virtio drive to -# the last one. This should force udev into attempting to create a device -# unit with a _really_ long name. -for bridge in range(1, 26): - config["QemuArgs"] += [ - "-device", - f"pci-bridge,id=pci_bridge{bridge},bus=pci_bridge{bridge - 1},chassis_nr={64 + bridge},addr=1", - ] - -config["QemuArgs"] += ["-device", f"virtio-blk-pci,drive=drive0,bus=pci_bridge25,addr=1,serial=long-sysfs-path"] - -json.dump(config, sys.stdout) diff --git a/test/TEST-64-UDEV-STORAGE/lvm_basic.configure b/test/TEST-64-UDEV-STORAGE/lvm_basic.configure deleted file mode 100755 index c4074becb4..0000000000 --- a/test/TEST-64-UDEV-STORAGE/lvm_basic.configure +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: LGPL-2.1-or-later - -import json -import sys - - -config = json.load(sys.stdin) - -config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0"] - -for i in range(4): - id = f"drivelvmbasic{i}" - config["Drives"] += [ - { - "Id": id, - "Size": "32M", - "Options": "cache=unsafe", - } - ] - config["QemuArgs"] += [ - "-device", f"scsi-hd,drive={id},vendor=systemd,product=foobar,serial=deadbeeflvm{i}", - ] - -json.dump(config, sys.stdout) diff --git a/test/TEST-64-UDEV-STORAGE/mdadm_basic.configure b/test/TEST-64-UDEV-STORAGE/mdadm_basic.configure deleted file mode 100755 index d722e081e2..0000000000 --- a/test/TEST-64-UDEV-STORAGE/mdadm_basic.configure +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: LGPL-2.1-or-later - -import json -import sys - - -config = json.load(sys.stdin) - -config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0"] - -for i in range(5): - id = f"drivemdadmbasic{i}" - config["Drives"] += [ - { - "Id": id, - "Size": "64M", - "Options": "cache=unsafe", - } - ] - config["QemuArgs"] += [ - "-device", f"scsi-hd,drive={id},vendor=systemd,product=foobar,serial=deadbeefmdadm{i}", - ] - -json.dump(config, sys.stdout) diff --git a/test/TEST-64-UDEV-STORAGE/mdadm_lvm.configure b/test/TEST-64-UDEV-STORAGE/mdadm_lvm.configure deleted file mode 100755 index d669895925..0000000000 --- a/test/TEST-64-UDEV-STORAGE/mdadm_lvm.configure +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: LGPL-2.1-or-later - -import json -import sys - - -config = json.load(sys.stdin) - -config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0"] - -for i in range(5): - id = f"drivemdadmlvm{i}" - config["Drives"] += [ - { - "Id": id, - "Size": "64M", - "Options": "cache=unsafe", - } - ] - config["QemuArgs"] += [ - "-device", f"scsi-hd,drive={id},vendor=systemd,product=foobar,serial=deadbeefmdadmlvm{i}", - ] - -json.dump(config, sys.stdout) diff --git a/test/TEST-64-UDEV-STORAGE/meson.build b/test/TEST-64-UDEV-STORAGE/meson.build index a91c23ae17..f1045e89b4 100644 --- a/test/TEST-64-UDEV-STORAGE/meson.build +++ b/test/TEST-64-UDEV-STORAGE/meson.build @@ -11,31 +11,253 @@ unit = configure_file( }, ) -foreach testcase : [ - 'btrfs_basic', - 'iscsi_lvm', - 'long_sysfs_path', - 'lvm_basic', - 'mdadm_basic', - 'mdadm_lvm', - 'multipath_basic_failover', - 'nvme_basic', - 'nvme_subsystem', - 'simultaneous_events', - 'virtio_scsi_basic', - 'virtio_scsi_identically_named_partitions', -] +udev_storage_tests = [] + +cmdline = [] +qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0'] + +foreach i : range(4) + id = f'drivebtrfsbasic@i@' + size = i == 0 ? '350M' : '128M' + cmdline += [f'--drive=@id@:@size@::cache=unsafe'] + qemu_args += ['-device', f'scsi-hd,drive=@id@,vendor=systemd,product=foobar,serial=deadbeefbtrfs@i@'] +endforeach + +udev_storage_tests += { + 'name' : 'btrfs_basic', + 'cmdline' : cmdline, + 'qemu-args' : qemu_args, +} + +cmdline = [] +qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0'] + +foreach i : range(4) + id = f'driveiscsibasic@i@' + size = i == 0 ? '150M' : '70M' + cmdline += [f'--drive=@id@:@size@::cache=unsafe'] + qemu_args += ['-device', f'scsi-hd,drive=@id@,vendor=systemd,product=foobar,serial=deadbeefiscsi@i@'] +endforeach + +udev_storage_tests += { + 'name' : 'iscsi_lvm', + 'cmdline' : cmdline, + 'qemu-args' : qemu_args, +} + +cmdline = ['--drive=drive0:64M::cache=unsafe'] +qemu_args = ['-device', 'pci-bridge,id=pci_bridge0,chassis_nr=64'] + +# Create 25 additional PCI bridges, each one connected to the previous one +# (basically a really long extension cable), and attach a virtio drive to +# the last one. This should force udev into attempting to create a device +# unit with a _really_ long name. +foreach bridge : range(1, 26) + bus = bridge - 1 + chassis = 64 + bridge + qemu_args += ['-device', f'pci-bridge,id=pci_bridge@bridge@,bus=pci_bridge@bus@,chassis_nr=@chassis@,addr=1'] +endforeach + +qemu_args += ['-device', 'virtio-blk-pci,drive=drive0,bus=pci_bridge25,addr=1,serial=long-sysfs-path'] + +udev_storage_tests += { + 'name' : 'long_sysfs_path', + 'cmdline' : cmdline, + 'qemu-args' : qemu_args, +} + +cmdline = [] +qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0'] + +foreach i : range(4) + id = f'drivelvmbasic@i@' + cmdline += [f'--drive=@id@:32M::cache=unsafe'] + qemu_args += ['-device', f'scsi-hd,drive=@id@,vendor=systemd,product=foobar,serial=deadbeeflvm@i@'] +endforeach + +udev_storage_tests += { + 'name' : 'lvm_basic', + 'cmdline' : cmdline, + 'qemu-args' : qemu_args, +} + +cmdline = [] +qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0'] + +foreach i : range(5) + id = f'drivemdadmbasic@i@' + cmdline += [f'--drive=@id@:64M::cache=unsafe'] + qemu_args += ['-device', f'scsi-hd,drive=@id@,vendor=systemd,product=foobar,serial=deadbeefmdadm@i@'] +endforeach + +udev_storage_tests += { + 'name' : 'mdadm_basic', + 'cmdline' : cmdline, + 'qemu-args' : qemu_args, +} + +cmdline = [] +qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0'] + +foreach i : range(5) + id = f'drivemdadmlvm@i@' + cmdline += [f'--drive=@id@:64M::cache=unsafe'] + qemu_args += ['-device', f'scsi-hd,drive=@id@,vendor=systemd,product=foobar,serial=deadbeefmdadmlvm@i@'] +endforeach + +udev_storage_tests += { + 'name' : 'mdadm_lvm', + 'cmdline' : cmdline, + 'qemu-args' : qemu_args, +} + +cmdline = [] +qemu_args = [] + +# Add 16 multipath devices, each backed by 4 paths +foreach ndisk : range(16) + ndiskfmt = ndisk >= 10 ? f'00@ndisk@' : f'000@ndisk@' + wwn = f'0xDEADDEADBEEF@ndiskfmt@' + size = ndisk == 0 ? '16M' : '1M' + + foreach nback : range(4) + id = f'drive@ndisk@x@nback@' + cmdline += [f'--drive=@id@:@size@::cache=unsafe:@ndisk@'] + qemu_args += ['-device', f'scsi-hd,drive=@id@,serial=MPIO@ndisk@,wwn=@wwn@'] + endforeach +endforeach + +udev_storage_tests += { + 'name' : 'multipath_basic_failover', + 'cmdline' : cmdline, + 'qemu-args' : qemu_args, +} + +cmdline = [] +qemu_args = [] + +foreach i : range(10) + id = f'drivesimultaneousevents@i@' + cmdline += [f'--drive=@id@:128M::cache=unsafe'] + qemu_args += ['-device', f'scsi-hd,drive=@id@,serial=deadbeeftest@i@'] +endforeach + +udev_storage_tests += { + 'name' : 'simultaneous_events', + 'cmdline' : cmdline, + 'qemu-args' : qemu_args, +} + +cmdline = [] +qemu_args = [] + +foreach i : range(4) + qemu_args += ['-device', f'virtio-scsi-pci,id=scsi@i@'] +endforeach + +foreach i : range(128) + id = f'drive@i@' + cmdline += [f'--drive=@id@:1M::cache=unsafe'] + div = i / 32 + mod = i % 32 + qemu_args += ['-device', f'scsi-hd,drive=@id@,bus=scsi@div@.0,channel=0,scsi-id=@mod@,lun=0'] +endforeach + +udev_storage_tests += { + 'name' : 'virtio_scsi_basic', + 'cmdline' : cmdline, + 'qemu-args' : qemu_args, +} + +qemu = find_program('qemu-system-@0@'.format(host_machine.cpu_family()), 'qemu-kvm', dirs : ['/usr/libexec'], native : true, required : false) +if qemu.found() + devices = run_command(qemu, '-device', 'help', check : true).stdout().strip() + if devices.contains('name "nvme"') + cmdline = [] + qemu_args = [] + + foreach i : range(20) + cmdline += [f'--drive=nvme@i@:1M::cache=unsafe'] + endforeach + + foreach i : range(5) + qemu_args += ['-device', f'nvme,drive=nvme@i@,serial=deadbeef@i@,max_ioqpairs=8'] + endforeach + + foreach i : range(5, 10) + qemu_args += ['-device', f'"nvme,drive=nvme@i@,serial= deadbeef @i@ ,max_ioqpairs=8"'] + endforeach + + foreach i : range(10, 15) + qemu_args += ['-device', f'"nvme,drive=nvme@i@,serial= dead/beef/@i@ ,max_ioqpairs=8"'] + endforeach + + foreach i : range(15, 20) + qemu_args += ['-device', f'"nvme,drive=nvme@i@,serial=dead/../../beef/@i@,max_ioqpairs=8"'] + endforeach + + udev_storage_tests += { + 'name' : 'nvme_basic', + 'cmdline' : cmdline, + 'qemu-args' : qemu_args, + } + + cmdline = [] + + foreach id : ['nvme0', 'nvme1'] + cmdline += [f'--drive=@id@:1M::cache=unsafe'] + endforeach + + qemu_args = [ + # Create an NVM Subsystem Device + '-device', 'nvme-subsys,id=nvme-subsys-64,nqn=subsys64', + # Attach two NVM controllers to it + '-device', 'nvme,subsys=nvme-subsys-64,serial=deadbeef', + '-device', 'nvme,subsys=nvme-subsys-64,serial=deadbeef', + # And create two shared namespaces attached to both controllers + '-device', 'nvme-ns,drive=nvme0,nsid=16,shared=on', + '-device', 'nvme-ns,drive=nvme1,nsid=17,shared=on', + ] + + udev_storage_tests += { + 'name' : 'nvme_subsystem', + 'cmdline' : cmdline, + 'qemu-args' : qemu_args, + } + endif + + if devices.contains('name "virtio-scsi-pci"') + cmdline = [] + qemu_args = ['-device', 'virtio-scsi-pci,id=scsi0,num_queues=4'] + + foreach i : range(16) + id = f'drive@i@' + cmdline += [f'--drive=@id@:40M::cache=unsafe'] + qemu_args += ['-device', f'scsi-hd,drive=@id@,bus=scsi0.0,channel=0,scsi-id=0,lun=@i@'] + endforeach + + udev_storage_tests += { + 'name' : 'virtio_scsi_identically_named_partitions', + 'cmdline' : cmdline, + 'qemu-args' : qemu_args, + } + endif +endif + + +foreach testcase : udev_storage_tests + qemu_args = ' '.join(testcase['qemu-args']) + cmdline = testcase['cmdline'] + [f'--qemu-args=@qemu_args@'] + integration_tests += [ integration_test_template + { - 'name' : '@0@-@1@'.format(name, testcase), + 'name' : '@0@-@1@'.format(name, testcase['name']), # Make sure the service is still named TEST-64-UDEV-STORAGE.service. 'unit' : unit, 'cmdline' : integration_test_template['cmdline'] + [ - 'systemd.setenv=TEST_FUNCTION_NAME=testcase_@0@'.format(testcase) - ], - 'mkosi-args' : integration_test_template['mkosi-args'] + [ - '--configure-script', files('@0@.configure'.format(testcase)), + 'systemd.setenv=TEST_FUNCTION_NAME=testcase_@0@'.format(testcase['name']) ], + 'mkosi-args' : integration_test_template['mkosi-args'] + cmdline, 'priority' : 10, 'vm' : true, # Suppress ASan error diff --git a/test/TEST-64-UDEV-STORAGE/multipath_basic_failover.configure b/test/TEST-64-UDEV-STORAGE/multipath_basic_failover.configure deleted file mode 100755 index a59927c3b7..0000000000 --- a/test/TEST-64-UDEV-STORAGE/multipath_basic_failover.configure +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: LGPL-2.1-or-later - -import json -import sys - - -config = json.load(sys.stdin) - -# Add 16 multipath devices, each backed by 4 paths -# We don't use --qemu-drive for this since they have to share the file. -for ndisk in range(16): - wwn = f"0xDEADDEADBEEF{ndisk:04d}" - if ndisk == 0: - size = "16M" - else: - size = "1M" - - for nback in range(4): - id = f"drive{ndisk}x{nback}" - config["Drives"] += [ - { - "Id": id, - "Size": size, - "Options": "cache=unsafe", - "FileId": str(ndisk), - } - ] - config["QemuArgs"] += ["-device", f"scsi-hd,drive={id},serial=MPIO{ndisk},wwn={wwn}"] - -json.dump(config, sys.stdout) diff --git a/test/TEST-64-UDEV-STORAGE/nvme_basic.configure b/test/TEST-64-UDEV-STORAGE/nvme_basic.configure deleted file mode 100755 index ed8304d804..0000000000 --- a/test/TEST-64-UDEV-STORAGE/nvme_basic.configure +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: LGPL-2.1-or-later - -import json -import os -import shutil -import subprocess -import sys - - -config = json.load(sys.stdin) - -qemu = shutil.which("/usr/libexec/qemu-kvm") or f"qemu-system-{os.environ['QEMU_ARCHITECTURE']}" -result = subprocess.run([qemu, "-device", "help"], check=True, text=True, stdout=subprocess.PIPE) -if 'name "nvme"' not in result.stdout: - print("nvme device driver is not available, skipping test...", file=sys.stderr) - exit(77) - -def add_drive(i: int, serial: str) -> None: - global config - id = f"nvme{i}" - config["Drives"] += [ - { - "Id": id, - "Size": "1M", - "Options": "cache=unsafe", - } - ] - config["QemuArgs"] += ["-device", f"nvme,drive={id},serial={serial},max_ioqpairs=8"] - -for i in range(5): - add_drive(i, serial=f"deadbeef{i}") -for i in range(5, 10): - add_drive(i, serial=f" deadbeef {i} ") -for i in range(10, 15): - add_drive(i, serial=f" dead/beef/{i} ") -for i in range(15, 20): - add_drive(i, serial=f"dead/../../beef/{i}") - -json.dump(config, sys.stdout) diff --git a/test/TEST-64-UDEV-STORAGE/nvme_subsystem.configure b/test/TEST-64-UDEV-STORAGE/nvme_subsystem.configure deleted file mode 100755 index ed8b39ac5f..0000000000 --- a/test/TEST-64-UDEV-STORAGE/nvme_subsystem.configure +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: LGPL-2.1-or-later - -import json -import os -import shutil -import subprocess -import sys - - -config = json.load(sys.stdin) - -qemu = shutil.which("/usr/libexec/qemu-kvm") or f"qemu-system-{os.environ['QEMU_ARCHITECTURE']}" -result = subprocess.run([qemu, "-device", "help"], check=True, text=True, stdout=subprocess.PIPE) -if 'name "nvme"' not in result.stdout: - print("nvme device driver is not available, skipping test...", file=sys.stderr) - exit(77) - -for id in ("nvme0", "nvme1"): - config["Drives"] += [ - { - "Id": id, - "Size": "1M", - "Options": "cache=unsafe", - } - - ] - -config["QemuArgs"] += [ - # Create an NVM Subsystem Device - "-device", "nvme-subsys,id=nvme-subsys-64,nqn=subsys64", - # Attach two NVM controllers to it - "-device", "nvme,subsys=nvme-subsys-64,serial=deadbeef", - "-device", "nvme,subsys=nvme-subsys-64,serial=deadbeef", - # And create two shared namespaces attached to both controllers - "-device", "nvme-ns,drive=nvme0,nsid=16,shared=on", - "-device", "nvme-ns,drive=nvme1,nsid=17,shared=on", -] - -json.dump(config, sys.stdout) diff --git a/test/TEST-64-UDEV-STORAGE/simultaneous_events.configure b/test/TEST-64-UDEV-STORAGE/simultaneous_events.configure deleted file mode 100755 index 668f3e2aa0..0000000000 --- a/test/TEST-64-UDEV-STORAGE/simultaneous_events.configure +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: LGPL-2.1-or-later - -import json -import sys - - -config = json.load(sys.stdin) - -for i in range(10): - id = f"drivesimultaneousevents{i}" - config["Drives"] += [ - { - "Id": id, - "Size": "128M", - "Options": "cache=unsafe", - } - ] - config["QemuArgs"] += ["-device", f"scsi-hd,drive={id},serial=deadbeeftest{i}"] - -json.dump(config, sys.stdout) diff --git a/test/TEST-64-UDEV-STORAGE/virtio_scsi_basic.configure b/test/TEST-64-UDEV-STORAGE/virtio_scsi_basic.configure deleted file mode 100755 index 91e1fe14e5..0000000000 --- a/test/TEST-64-UDEV-STORAGE/virtio_scsi_basic.configure +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: LGPL-2.1-or-later - -import json -import sys - - -config = json.load(sys.stdin) - -for i in range(4): - config["QemuArgs"] += ['-device', f"virtio-scsi-pci,id=scsi{i}"] - -for i in range(128): - id = f"drive{i}" - config["Drives"] += [ - { - "Id": id, - "Size": "1M", - "Options": "cache=unsafe", - } - ] - config["QemuArgs"] += [ - '-device', - f"scsi-hd,drive={id},bus=scsi{i // 32}.0,channel=0," - f"scsi-id={i % 32},lun=0", - ] - -json.dump(config, sys.stdout) diff --git a/test/TEST-64-UDEV-STORAGE/virtio_scsi_identically_named_partitions.configure b/test/TEST-64-UDEV-STORAGE/virtio_scsi_identically_named_partitions.configure deleted file mode 100755 index 5ffade5800..0000000000 --- a/test/TEST-64-UDEV-STORAGE/virtio_scsi_identically_named_partitions.configure +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: LGPL-2.1-or-later - -import json -import os -import shutil -import subprocess -import sys - - -config = json.load(sys.stdin) - -qemu = shutil.which("/usr/libexec/qemu-kvm") or f"qemu-system-{os.environ['QEMU_ARCHITECTURE']}" -result = subprocess.run([qemu, "-device", "help"], check=True, text=True, stdout=subprocess.PIPE) -if 'name "virtio-scsi-pci"' not in result.stdout: - print("virtio-scsi-pci device driver is not available, skipping test...", file=sys.stderr) - exit(77) - -num_disk = 16 - -config["QemuArgs"] += ["-device", "virtio-scsi-pci,id=scsi0,num_queues=4"] - -for i in range(0, num_disk): - id = f"drive{i}" - config["Drives"] += [ - { - "Id": id, - "Size": "40M", - "Options": "cache=unsafe" - } - ] - config["QemuArgs"] += ["-device", f"scsi-hd,drive={id},bus=scsi0.0,channel=0,scsi-id=0,lun={i}"] - -json.dump(config, sys.stdout) From 890e1ad3183458aa0337e4e6a1a9afa26d706e36 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 25 Feb 2025 10:59:20 +0100 Subject: [PATCH 4/5] test: Do not add integration tests if want_tests == 'false' --- test/meson.build | 364 ++++++++++++++++++++++++----------------------- 1 file changed, 183 insertions(+), 181 deletions(-) diff --git a/test/meson.build b/test/meson.build index 39dbc80b66..59e9cd36fd 100644 --- a/test/meson.build +++ b/test/meson.build @@ -277,196 +277,198 @@ endif ############################################################ -integration_test_wrapper = find_program('integration-test-wrapper.py') -integration_tests = [] -integration_test_template = { - 'mkosi-args' : [], - 'timeout' : 1800, - 'storage' : 'volatile', - 'priority' : 0, - 'firmware' : 'linux', - 'enabled' : true, - 'configuration' : { - 'memory-accounting' : 'no', - 'command' : testdata_dir / 'units/%N.sh', - 'wants' : 'multi-user.target user@4711.service', - 'after' : 'user@4711.service', - }, - 'cmdline' : [], - 'credentials' : [], - 'qemu-args' : [], - 'exit-code' : 123, - 'vm' : false, - 'coredump-exclude-regex' : '', - 'sanitizer-exclude-regex' : '', - 'rtc' : false, -} -testdata_subdirs = [ - 'auxv', - 'journal-data', - 'knot-data', - 'test-journals', - 'units', - 'test-execute', - 'test-fstab-generator', - 'test-path', - 'test-path-util', - 'test-umount', - 'test-network', - 'test-network-generator-conversion', -] - -foreach dirname : [ - 'TEST-01-BASIC', - 'TEST-02-UNITTESTS', - 'TEST-03-JOBS', - 'TEST-04-JOURNAL', - 'TEST-05-RLIMITS', - 'TEST-06-SELINUX', - 'TEST-07-PID1', - 'TEST-08-INITRD', - 'TEST-09-REBOOT', - 'TEST-13-NSPAWN', - 'TEST-15-DROPIN', - 'TEST-16-EXTEND-TIMEOUT', - 'TEST-17-UDEV', - 'TEST-18-FAILUREACTION', - 'TEST-19-CGROUP', - 'TEST-21-DFUZZER', - 'TEST-22-TMPFILES', - 'TEST-23-UNIT-FILE', - 'TEST-24-CRYPTSETUP', - 'TEST-25-IMPORT', - 'TEST-26-SYSTEMCTL', - 'TEST-29-PORTABLE', - 'TEST-30-ONCLOCKCHANGE', - 'TEST-31-DEVICE-ENUMERATION', - 'TEST-32-OOMPOLICY', - 'TEST-34-DYNAMICUSERMIGRATE', - 'TEST-35-LOGIN', - 'TEST-36-NUMAPOLICY', - 'TEST-38-FREEZER', - 'TEST-43-PRIVATEUSER-UNPRIV', - 'TEST-44-LOG-NAMESPACE', - 'TEST-45-TIMEDATE', - 'TEST-46-HOMED', - 'TEST-50-DISSECT', - 'TEST-52-HONORFIRSTSHUTDOWN', - 'TEST-53-ISSUE-16347', - 'TEST-54-CREDS', - 'TEST-55-OOMD', - 'TEST-58-REPART', - 'TEST-59-RELOADING-RESTART', - 'TEST-60-MOUNT-RATELIMIT', - 'TEST-62-RESTRICT-IFACES', - 'TEST-63-PATH', - 'TEST-64-UDEV-STORAGE', - 'TEST-65-ANALYZE', - 'TEST-66-DEVICE-ISOLATION', - 'TEST-67-INTEGRITY', - 'TEST-68-PROPAGATE-EXIT-STATUS', - 'TEST-69-SHUTDOWN', - 'TEST-70-TPM2', - 'TEST-71-HOSTNAME', - 'TEST-72-SYSUPDATE', - 'TEST-73-LOCALE', - 'TEST-74-AUX-UTILS', - 'TEST-75-RESOLVED', - 'TEST-76-SYSCTL', - 'TEST-78-SIGQUEUE', - 'TEST-79-MEMPRESS', - 'TEST-80-NOTIFYACCESS', - 'TEST-81-GENERATORS', - 'TEST-82-SOFTREBOOT', - 'TEST-83-BTRFS', - 'TEST-84-STORAGETM', - 'TEST-85-NETWORK', - 'TEST-86-MULTI-PROFILE-UKI', - 'TEST-87-AUX-UTILS-VM', -] - subdir(dirname) -endforeach - -foreach integration_test : integration_tests - integration_test_args = [ - '--meson-source-dir', meson.project_source_root(), - '--meson-build-dir', meson.project_build_root(), - '--name', integration_test['name'], - '--storage', integration_test['storage'], - '--firmware', integration_test['firmware'], - '--exit-code', integration_test['exit-code'].to_string(), - '--coredump-exclude-regex', integration_test['coredump-exclude-regex'], - '--sanitizer-exclude-regex', integration_test['sanitizer-exclude-regex'], +if want_tests != 'false' + integration_test_wrapper = find_program('integration-test-wrapper.py') + integration_tests = [] + integration_test_template = { + 'mkosi-args' : [], + 'timeout' : 1800, + 'storage' : 'volatile', + 'priority' : 0, + 'firmware' : 'linux', + 'enabled' : true, + 'configuration' : { + 'memory-accounting' : 'no', + 'command' : testdata_dir / 'units/%N.sh', + 'wants' : 'multi-user.target user@4711.service', + 'after' : 'user@4711.service', + }, + 'cmdline' : [], + 'credentials' : [], + 'qemu-args' : [], + 'exit-code' : 123, + 'vm' : false, + 'coredump-exclude-regex' : '', + 'sanitizer-exclude-regex' : '', + 'rtc' : false, + } + testdata_subdirs = [ + 'auxv', + 'journal-data', + 'knot-data', + 'test-journals', + 'units', + 'test-execute', + 'test-fstab-generator', + 'test-path', + 'test-path-util', + 'test-umount', + 'test-network', + 'test-network-generator-conversion', ] - if 'unit' in integration_test - integration_test_unit = integration_test['unit'] - else - integration_test_unit = configure_file( - input : 'test.service.in', - output : '@0@.service'.format(integration_test['name']), - configuration : integration_test['configuration'], - ) - endif - - integration_test_args += ['--unit', fs.name(integration_test_unit)] - if install_tests - install_data(integration_test_unit, install_dir : testdata_dir / 'units') - endif - - if integration_test['vm'] - integration_test_args += ['--vm'] - endif - - if integration_test['rtc'] - integration_test_args += ['--rtc'] - endif - - if not mkosi.found() - continue - endif - - integration_test_args += ['--mkosi', mkosi.full_path(), '--'] - - if integration_test['cmdline'].length() > 0 - integration_test_args += [ - '--kernel-command-line-extra=@0@'.format(' '.join(integration_test['cmdline'])) - ] - endif - - foreach credential : integration_test['credentials'] - integration_test_args += ['--credential', credential] + foreach dirname : [ + 'TEST-01-BASIC', + 'TEST-02-UNITTESTS', + 'TEST-03-JOBS', + 'TEST-04-JOURNAL', + 'TEST-05-RLIMITS', + 'TEST-06-SELINUX', + 'TEST-07-PID1', + 'TEST-08-INITRD', + 'TEST-09-REBOOT', + 'TEST-13-NSPAWN', + 'TEST-15-DROPIN', + 'TEST-16-EXTEND-TIMEOUT', + 'TEST-17-UDEV', + 'TEST-18-FAILUREACTION', + 'TEST-19-CGROUP', + 'TEST-21-DFUZZER', + 'TEST-22-TMPFILES', + 'TEST-23-UNIT-FILE', + 'TEST-24-CRYPTSETUP', + 'TEST-25-IMPORT', + 'TEST-26-SYSTEMCTL', + 'TEST-29-PORTABLE', + 'TEST-30-ONCLOCKCHANGE', + 'TEST-31-DEVICE-ENUMERATION', + 'TEST-32-OOMPOLICY', + 'TEST-34-DYNAMICUSERMIGRATE', + 'TEST-35-LOGIN', + 'TEST-36-NUMAPOLICY', + 'TEST-38-FREEZER', + 'TEST-43-PRIVATEUSER-UNPRIV', + 'TEST-44-LOG-NAMESPACE', + 'TEST-45-TIMEDATE', + 'TEST-46-HOMED', + 'TEST-50-DISSECT', + 'TEST-52-HONORFIRSTSHUTDOWN', + 'TEST-53-ISSUE-16347', + 'TEST-54-CREDS', + 'TEST-55-OOMD', + 'TEST-58-REPART', + 'TEST-59-RELOADING-RESTART', + 'TEST-60-MOUNT-RATELIMIT', + 'TEST-62-RESTRICT-IFACES', + 'TEST-63-PATH', + 'TEST-64-UDEV-STORAGE', + 'TEST-65-ANALYZE', + 'TEST-66-DEVICE-ISOLATION', + 'TEST-67-INTEGRITY', + 'TEST-68-PROPAGATE-EXIT-STATUS', + 'TEST-69-SHUTDOWN', + 'TEST-70-TPM2', + 'TEST-71-HOSTNAME', + 'TEST-72-SYSUPDATE', + 'TEST-73-LOCALE', + 'TEST-74-AUX-UTILS', + 'TEST-75-RESOLVED', + 'TEST-76-SYSCTL', + 'TEST-78-SIGQUEUE', + 'TEST-79-MEMPRESS', + 'TEST-80-NOTIFYACCESS', + 'TEST-81-GENERATORS', + 'TEST-82-SOFTREBOOT', + 'TEST-83-BTRFS', + 'TEST-84-STORAGETM', + 'TEST-85-NETWORK', + 'TEST-86-MULTI-PROFILE-UKI', + 'TEST-87-AUX-UTILS-VM', + ] + subdir(dirname) endforeach - if integration_test['qemu-args'].length() > 0 - integration_test_args += ['--qemu-args=@0@'.format(' '.join(integration_test['qemu-args']))] - endif + foreach integration_test : integration_tests + integration_test_args = [ + '--meson-source-dir', meson.project_source_root(), + '--meson-build-dir', meson.project_build_root(), + '--name', integration_test['name'], + '--storage', integration_test['storage'], + '--firmware', integration_test['firmware'], + '--exit-code', integration_test['exit-code'].to_string(), + '--coredump-exclude-regex', integration_test['coredump-exclude-regex'], + '--sanitizer-exclude-regex', integration_test['sanitizer-exclude-regex'], + ] - integration_test_args += integration_test['mkosi-args'] + if 'unit' in integration_test + integration_test_unit = integration_test['unit'] + else + integration_test_unit = configure_file( + input : 'test.service.in', + output : '@0@.service'.format(integration_test['name']), + configuration : integration_test['configuration'], + ) + endif - integration_test_env = {} + integration_test_args += ['--unit', fs.name(integration_test_unit)] + if install_tests + install_data(integration_test_unit, install_dir : testdata_dir / 'units') + endif - if want_integration_tests - integration_test_env += {'SYSTEMD_INTEGRATION_TESTS': '1'} - endif + if integration_test['vm'] + integration_test_args += ['--vm'] + endif - if not integration_test['enabled'] - continue - endif + if integration_test['rtc'] + integration_test_args += ['--rtc'] + 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'], - suite : 'integration-tests', - ) -endforeach + if not mkosi.found() + continue + endif + + integration_test_args += ['--mkosi', mkosi.full_path(), '--'] + + if integration_test['cmdline'].length() > 0 + integration_test_args += [ + '--kernel-command-line-extra=@0@'.format(' '.join(integration_test['cmdline'])) + ] + endif + + foreach credential : integration_test['credentials'] + integration_test_args += ['--credential', credential] + endforeach + + if integration_test['qemu-args'].length() > 0 + integration_test_args += ['--qemu-args=@0@'.format(' '.join(integration_test['qemu-args']))] + endif + + integration_test_args += integration_test['mkosi-args'] + + integration_test_env = {} + + if want_integration_tests + integration_test_env += {'SYSTEMD_INTEGRATION_TESTS': '1'} + endif + + if not integration_test['enabled'] + continue + 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'], + suite : 'integration-tests', + ) + endforeach +endif if install_tests foreach subdir : testdata_subdirs From 75cf5b0d3a6045e72dacd90f90ae14fa6d817be1 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 24 Feb 2025 10:56:26 +0100 Subject: [PATCH 5/5] mkosi: Enable History= option This option makes mkosi "remember" all the CLI options specified on the command line when building an image. This means they don't need to be specified again when booting the image afterwards or doing any other operation on the image with "mkosi xxx". As an example of how this is useful, currently, when running "mkosi -d opensuse -f" to build an opensuse image and then running "mkosi sandbox -- meson test -C build TEST-86-MULTI-UKI-PROFILE", running the test will try to add virtiofs mounts of the fedora~rawhide build directory on my machine instead of the opensuse one. With the History= option enabled, it will use the opensuse tumbleweed directory as expected. We stop setting --extra-search-path and --output-dir in the integration test wrapper as these are settings that are "remembered" by enabling the History= option. --- mkosi.conf | 1 + test/integration-test-wrapper.py | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/mkosi.conf b/mkosi.conf index 1ae273a5da..a9d096815a 100644 --- a/mkosi.conf +++ b/mkosi.conf @@ -30,6 +30,7 @@ RepartDirectories=mkosi.repart OutputDirectory=build/mkosi.output [Build] +History=yes ToolsTree=default BuildDirectory=build/mkosi.builddir CacheDirectory=build/mkosi.cache diff --git a/test/integration-test-wrapper.py b/test/integration-test-wrapper.py index 7dac8998c8..a87b49bd8b 100755 --- a/test/integration-test-wrapper.py +++ b/test/integration-test-wrapper.py @@ -481,8 +481,6 @@ def main() -> None: cmd = [ args.mkosi, '--directory', os.fspath(args.meson_source_dir), - '--output-dir', os.fspath(args.meson_build_dir / 'mkosi.output'), - '--extra-search-path', os.fspath(args.meson_build_dir), '--machine', name, '--ephemeral=yes', *(['--forward-journal', journal_file] if journal_file else []),