diff options
Diffstat (limited to 'test')
-rwxr-xr-x | test/TEST-02-UNITTESTS/test.sh | 4 | ||||
-rwxr-xr-x | test/TEST-64-UDEV-STORAGE/test.sh | 55 | ||||
-rw-r--r-- | test/fuzz/fuzz-unit-file/directives.service | 2 | ||||
-rwxr-xr-x | test/networkd-test.py | 2 | ||||
-rw-r--r-- | test/test-functions | 27 | ||||
-rw-r--r-- | test/test-network/conf/25-ip6tnl-tunnel-external.netdev (renamed from test/test-network/conf/25-ip6tnl-external.netdev) | 0 | ||||
-rwxr-xr-x | test/test-network/systemd-networkd-tests.py | 2 | ||||
-rwxr-xr-x | test/udev-test.pl | 4 | ||||
-rwxr-xr-x | test/units/testsuite-50.sh | 2 | ||||
-rwxr-xr-x | test/units/testsuite-58.sh | 20 | ||||
-rwxr-xr-x | test/units/testsuite-60.sh | 19 | ||||
-rwxr-xr-x | test/units/testsuite-64.sh | 152 |
12 files changed, 269 insertions, 20 deletions
diff --git a/test/TEST-02-UNITTESTS/test.sh b/test/TEST-02-UNITTESTS/test.sh index 571abe41c3..80cb82a50d 100755 --- a/test/TEST-02-UNITTESTS/test.sh +++ b/test/TEST-02-UNITTESTS/test.sh @@ -4,6 +4,10 @@ set -e TEST_DESCRIPTION="Run unit tests under containers" RUN_IN_UNPRIVILEGED_CONTAINER=yes +# Some tests make collecting coverage impossible (like test-mount-util, which +# remounts the whole / as read-only), so let's ignore the gcov errors in such +# case +IGNORE_MISSING_COVERAGE=yes # embed some newlines in the kernel command line to stress our test suite KERNEL_APPEND=" diff --git a/test/TEST-64-UDEV-STORAGE/test.sh b/test/TEST-64-UDEV-STORAGE/test.sh index 04632952d0..d2660d3951 100755 --- a/test/TEST-64-UDEV-STORAGE/test.sh +++ b/test/TEST-64-UDEV-STORAGE/test.sh @@ -42,6 +42,9 @@ _host_has_feature() {( lvm) command -v lvm || return $? ;; + mdadm) + command -v mdadm || return $? + ;; multipath) command -v multipath && command -v multipathd || return $? ;; @@ -64,6 +67,7 @@ test_append_files() {( [btrfs]=install_btrfs [iscsi]=install_iscsi [lvm]=install_lvm + [mdadm]=install_mdadm [multipath]=install_multipath ) @@ -444,6 +448,57 @@ EOF rm -f "${testdisk:?}" } +testcase_mdadm_basic() { + if ! _host_has_feature "mdadm"; then + echo "Missing mdadm tools/modules, skipping the test..." + return 77 + fi + + local qemu_opts=("-device ahci,id=ahci0") + local diskpath i size + + for i in {0..4}; do + diskpath="${TESTDIR:?}/mdadmbasic${i}.img" + + dd if=/dev/zero of="$diskpath" bs=1M count=64 + qemu_opts+=( + "-device ide-hd,bus=ahci0.$i,drive=drive$i,model=foobar,serial=deadbeefmdadm$i" + "-drive format=raw,cache=unsafe,file=$diskpath,if=none,id=drive$i" + ) + done + + KERNEL_APPEND="systemd.setenv=TEST_FUNCTION_NAME=${FUNCNAME[0]} ${USER_KERNEL_APPEND:-}" + QEMU_OPTIONS="${qemu_opts[*]} ${USER_QEMU_OPTIONS:-}" + test_run_one "${1:?}" || return $? + + rm -f "${TESTDIR:?}"/mdadmbasic*.img +} + +testcase_mdadm_lvm() { + if ! _host_has_feature "mdadm" || ! _host_has_feature "lvm"; then + echo "Missing mdadm tools/modules or LVM tools, skipping the test..." + return 77 + fi + + local qemu_opts=("-device ahci,id=ahci0") + local diskpath i size + + for i in {0..4}; do + diskpath="${TESTDIR:?}/mdadmlvm${i}.img" + + dd if=/dev/zero of="$diskpath" bs=1M count=64 + qemu_opts+=( + "-device ide-hd,bus=ahci0.$i,drive=drive$i,model=foobar,serial=deadbeefmdadmlvm$i" + "-drive format=raw,cache=unsafe,file=$diskpath,if=none,id=drive$i" + ) + done + + KERNEL_APPEND="systemd.setenv=TEST_FUNCTION_NAME=${FUNCNAME[0]} ${USER_KERNEL_APPEND:-}" + QEMU_OPTIONS="${qemu_opts[*]} ${USER_QEMU_OPTIONS:-}" + test_run_one "${1:?}" || return $? + + rm -f "${TESTDIR:?}"/mdadmlvm*.img +} # Allow overriding which tests should be run from the "outside", useful for manual # testing (make -C test/... TESTCASES="testcase1 testcase2") if [[ -v "TESTCASES" && -n "$TESTCASES" ]]; then diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service index 6be65062d3..3c33d947fe 100644 --- a/test/fuzz/fuzz-unit-file/directives.service +++ b/test/fuzz/fuzz-unit-file/directives.service @@ -4,6 +4,7 @@ After= AllowIsolate= AssertACPower= AssertArchitecture= +AssertCPUFeature= AssertCPUPressure= AssertCPUs= AssertCapability= @@ -40,6 +41,7 @@ BindsTo= CollectMode= ConditionACPower= ConditionArchitecture= +ConditionCPUFeature= ConditionCPUPressure= ConditionCPUs= ConditionFirmware= diff --git a/test/networkd-test.py b/test/networkd-test.py index 7faa12ef79..1001cd7cc8 100755 --- a/test/networkd-test.py +++ b/test/networkd-test.py @@ -91,7 +91,7 @@ def setUpModule(): def tearDownModule(): global tmpmounts for d in tmpmounts: - subprocess.check_call(["umount", d]) + subprocess.check_call(["umount", "--lazy", d]) for u in stopped_units: subprocess.call(["systemctl", "stop", u]) for u in running_units: diff --git a/test/test-functions b/test/test-functions index e1d6ed646f..7155e99c0e 100644 --- a/test/test-functions +++ b/test/test-functions @@ -1055,6 +1055,29 @@ install_iscsi() { fi } +install_mdadm() { + local unit + local mdadm_units=( + system/mdadm-grow-continue@.service + system/mdadm-last-resort@.service + system/mdadm-last-resort@.timer + system/mdmon@.service + system/mdmonitor-oneshot.service + system/mdmonitor-oneshot.timer + system/mdmonitor.service + system-shutdown/mdadm.shutdown + ) + + image_install mdadm mdmon + inst_rules 01-md-raid-creating.rules 63-md-raid-arrays.rules 64-md-raid-assembly.rules 69-md-clustered-confirm-device.rules + # Fedora/CentOS/RHEL ships this rule file + [[ -f /lib/udev/rules.d/65-md-incremental.rules ]] && inst_rules 65-md-incremental.rules + + for unit in "${mdadm_units[@]}"; do + image_install "${ROOTLIBDIR:?}/$unit" + done +} + install_compiled_systemd() { dinfo "Install compiled systemd" @@ -1406,8 +1429,8 @@ check_coverage_reports() { # usually due to the sandbox being too restrictive (e.g. ProtectSystem=yes, # ProtectHome=yes) or the $BUILD_DIR being inaccessible to non-root users - see # `setfacl` stuff in install_compiled_systemd(). - - if "${JOURNALCTL:?}" -q --no-pager -D "${root:?}/var/log/journal" --grep "profiling:.+?gcda:[Cc]annot open"; then + if ! get_bool "${IGNORE_MISSING_COVERAGE:=}" && \ + "${JOURNALCTL:?}" -q --no-pager -D "${root:?}/var/log/journal" --grep "profiling:.+?gcda:[Cc]annot open"; then derror "Detected possibly missing coverage, check the journal" return 1 fi diff --git a/test/test-network/conf/25-ip6tnl-external.netdev b/test/test-network/conf/25-ip6tnl-tunnel-external.netdev index 68926cdd1e..68926cdd1e 100644 --- a/test/test-network/conf/25-ip6tnl-external.netdev +++ b/test/test-network/conf/25-ip6tnl-tunnel-external.netdev diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 0a8349fd5b..d626e4b641 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -1711,7 +1711,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities): '25-ip6tnl-tunnel-remote-any.netdev', '25-tunnel-remote-any.network', '25-veth.netdev', '25-ip6tnl-slaac.network', '25-ipv6-prefix.network', '25-ip6tnl-tunnel-local-slaac.netdev', '25-ip6tnl-tunnel-local-slaac.network', - '25-ip6tnl-external.netdev', '26-netdev-link-local-addressing-yes.network') + '25-ip6tnl-tunnel-external.netdev', '26-netdev-link-local-addressing-yes.network') start_networkd() self.wait_online(['ip6tnl99:routable', 'ip6tnl98:routable', 'ip6tnl97:routable', 'ip6tnl-slaac:degraded', 'ip6tnl-external:degraded', diff --git a/test/udev-test.pl b/test/udev-test.pl index 3aeac65578..802bc1f3de 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -33,6 +33,10 @@ BEGIN { } } +# Relax sd-device's sysfs verification, since we want to provide a fake sysfs +# here that actually is a tmpfs. +$ENV{"SYSTEMD_DEVICE_VERIFY_SYSFS"}="0"; + my $udev_bin = "./test-udev"; my $valgrind = 0; my $gdb = 0; diff --git a/test/units/testsuite-50.sh b/test/units/testsuite-50.sh index 6aabbd139c..2f1844ccf7 100755 --- a/test/units/testsuite-50.sh +++ b/test/units/testsuite-50.sh @@ -285,7 +285,7 @@ Type=notify RemainAfterExit=yes MountAPIVFS=yes PrivateTmp=yes -ExecStart=/bin/sh -c 'systemd-notify --ready; while ! grep -q -F MARKER /tmp/img/usr/lib/os-release; do sleep 0.1; done; mount | grep -F "/tmp/img" | grep -q -F "nosuid"' +ExecStart=/bin/sh -c 'systemd-notify --ready; while ! grep -q -F MARKER /tmp/img/usr/lib/os-release; do sleep 0.1; done; mount | grep -F "/dev/mapper/${roothash}-verity" | grep -q -F "nosuid"' EOF systemctl start testservice-50d.service diff --git a/test/units/testsuite-58.sh b/test/units/testsuite-58.sh index 21f762d399..8dadcc0a95 100755 --- a/test/units/testsuite-58.sh +++ b/test/units/testsuite-58.sh @@ -173,20 +173,22 @@ rm -r /tmp/testsuite-58.3-defs/ # testcase for #21817 mkdir -p /tmp/testsuite-58-issue-21817-defs/ truncate -s 100m /var/tmp/testsuite-58-issue-21817.img -LOOP=$(losetup -P --show -f /var/tmp/testsuite-58-issue-21817.img) -udevadm wait --timeout 60 --initialized=yes --settle "${LOOP:?}" -printf 'size=50M,type=%s\n,\n' "${root_guid}" | sfdisk -X gpt "$LOOP" +sfdisk /var/tmp/testsuite-58-issue-21817.img <<EOF +label: gpt + +size=50M, type=${root_guid} +, +EOF cat >/tmp/testsuite-58-issue-21817-defs/test.conf <<EOF [Partition] Type=root EOF -systemd-repart --pretty=yes --definitions /tmp/testsuite-58-issue-21817-defs/ "$LOOP" -sfdisk --dump "$LOOP" | tee /tmp/testsuite-58-issue-21817.dump -losetup -d "$LOOP" +systemd-repart --pretty=yes --definitions /tmp/testsuite-58-issue-21817-defs/ --dry-run=no /var/tmp/testsuite-58-issue-21817.img +sfdisk --dump /var/tmp/testsuite-58-issue-21817.img | tee /tmp/testsuite-58-issue-21817.dump -grep -qiF "p1 : start= 2048, size= 102400, type=${root_guid}," /tmp/testsuite-58-issue-21817.dump +grep -qiF "/var/tmp/testsuite-58-issue-21817.img1 : start= 2048, size= 102400, type=${root_guid}," /tmp/testsuite-58-issue-21817.dump # Accept both unpadded (pre-v2.38 util-linux) and padded (v2.38+ util-linux) sizes -grep -qE "p2 : start= 104448, size= (100319| 98304)," /tmp/testsuite-58-issue-21817.dump +grep -qE "/var/tmp/testsuite-58-issue-21817.img2 : start= 104448, size= (100319| 98304)," /tmp/testsuite-58-issue-21817.dump rm /var/tmp/testsuite-58-issue-21817.img /tmp/testsuite-58-issue-21817.dump rm -r /tmp/testsuite-58-issue-21817-defs/ @@ -216,7 +218,7 @@ EOF truncate -s 100m "/tmp/testsuite-58-sector-$1.img" LOOP=$(losetup -b "$1" -P --show -f "/tmp/testsuite-58-sector-$1.img" ) - udevadm wait --timeout 60 --initialized=yes --settle "${LOOP:?}" + udevadm wait --timeout 60 --settle "${LOOP:?}" systemd-repart --pretty=yes --definitions=/tmp/testsuite-58-sector/ --seed=750b6cd5c4ae4012a15e7be3c29e6a47 --empty=require --dry-run=no "$LOOP" rm -rf /tmp/testsuite-58-sector sfdisk --verify "$LOOP" diff --git a/test/units/testsuite-60.sh b/test/units/testsuite-60.sh index eb174f00ed..239d7b0d4c 100755 --- a/test/units/testsuite-60.sh +++ b/test/units/testsuite-60.sh @@ -8,6 +8,25 @@ systemd-analyze log-target journal NUM_DIRS=20 +# make sure we can handle mounts at very long paths such that mount unit name must be hashed to fall within our unit name limit +LONGPATH="$(printf "/$(printf "x%0.s" {1..255})%0.s" {1..7})" +LONGMNT="$(systemd-escape --suffix=mount --path "$LONGPATH")" +TS="$(date '+%H:%M:%S')" + +mkdir -p "$LONGPATH" +mount -t tmpfs tmpfs "$LONGPATH" +systemctl daemon-reload + +# check that unit is active(mounted) +systemctl --no-pager show -p SubState --value "$LONGPATH" | grep -q mounted + +# check that relevant part of journal doesn't contain any errors related to unit +[ "$(journalctl -b --since="$TS" --priority=err | grep -c "$LONGMNT")" = "0" ] + +# check that we can successfully stop the mount unit +systemctl stop "$LONGPATH" +rm -rf "$LONGPATH" + # mount/unmount enough times to trigger the /proc/self/mountinfo parsing rate limiting for ((i = 0; i < NUM_DIRS; i++)); do diff --git a/test/units/testsuite-64.sh b/test/units/testsuite-64.sh index 44f362ec6f..cc016a774c 100755 --- a/test/units/testsuite-64.sh +++ b/test/units/testsuite-64.sh @@ -168,7 +168,7 @@ $(printf 'name="test%d", size=2M\n' {1..50}) EOF # Initial partition table - sfdisk -q -X gpt "$blockdev" <"$partscript" + udevadm lock --device="$blockdev" sfdisk -q -X gpt "$blockdev" <"$partscript" # Delete the partitions, immediately recreate them, wait for udev to settle # down, and then check if we have any dangling symlinks in /dev/disk/. Rinse @@ -177,8 +177,8 @@ EOF # On unpatched udev versions the delete-recreate cycle may trigger a race # leading to dead symlinks in /dev/disk/ for i in {1..100}; do - sfdisk -q --delete "$blockdev" - sfdisk -q -X gpt "$blockdev" <"$partscript" + udevadm lock --device="$blockdev" sfdisk -q --delete "$blockdev" + udevadm lock --device="$blockdev" sfdisk -q -X gpt "$blockdev" <"$partscript" if ((i % 10 == 0)); then udevadm wait --settle --timeout=30 "$blockdev" @@ -281,7 +281,7 @@ testcase_btrfs_basic() { echo "Multiple devices: using partitions, data: single, metadata: raid1" uuid="deadbeef-dead-dead-beef-000000000001" label="btrfs_mpart" - sfdisk --wipe=always "${devices[0]}" <<EOF + udevadm lock --device="${devices[0]}" sfdisk --wipe=always "${devices[0]}" <<EOF label: gpt name="diskpart1", size=85M @@ -515,6 +515,7 @@ testcase_long_sysfs_path() { echo "UUID=deadbeef-dead-dead-beef-222222222222 $mpoint ext4 defaults 0 0" >>/etc/fstab systemctl daemon-reload mount "$mpoint" + systemctl status "$mpoint" test -e "$mpoint/test" umount "$mpoint" @@ -525,15 +526,154 @@ testcase_long_sysfs_path() { udevadm settle logfile="$(mktemp)" - journalctl -b -q --no-pager -o short-monotonic -p info --grep "Device path.*vda.?' too long to fit into unit name" + [[ "$(journalctl -b -q --no-pager -o short-monotonic -p info --grep "Device path.*vda.?' too long to fit into unit name" | wc -l)" -eq 0 ]] # Make sure we don't unnecessarily spam the log - journalctl -b -q --no-pager -o short-monotonic -p info --grep "/sys/devices/.+/vda[0-9]?" _PID=1 + UNIT=systemd-udevd.service | tee "$logfile" + { journalctl -b -q --no-pager -o short-monotonic -p info --grep "/sys/devices/.+/vda[0-9]?" _PID=1 + UNIT=systemd-udevd.service || :;} | tee "$logfile" [[ "$(wc -l <"$logfile")" -lt 10 ]] : >/etc/fstab rm -fr "${logfile:?}" "${mpoint:?}" } +testcase_mdadm_basic() { + local part_name raid_name raid_dev uuid + local expected_symlinks=() + local devices=( + /dev/disk/by-id/ata-foobar_deadbeefmdadm{0..4} + ) + + ls -l "${devices[@]}" + + echo "Mirror raid (RAID 1)" + raid_name="mdmirror" + raid_dev="/dev/md/$raid_name" + part_name="${raid_name}_part" + uuid="aaaaaaaa:bbbbbbbb:cccccccc:00000001" + expected_symlinks=( + "$raid_dev" + "/dev/disk/by-id/md-name-H:$raid_name" + "/dev/disk/by-id/md-uuid-$uuid" + "/dev/disk/by-label/$part_name" # ext4 partition + ) + # Create a simple RAID 1 with an ext4 filesystem + echo y | mdadm --create "$raid_dev" --name "$raid_name" --uuid "$uuid" /dev/disk/by-id/ata-foobar_deadbeefmdadm{0..1} -v -f --level=1 --raid-devices=2 + udevadm wait --settle --timeout=30 "$raid_dev" + mkfs.ext4 -L "$part_name" "$raid_dev" + udevadm wait --settle --timeout=30 "${expected_symlinks[@]}" + # Disassemble the array + mdadm -v --stop "$raid_dev" + udevadm settle + helper_check_device_symlinks + # Reassemble it and check if all required symlinks exist + mdadm --assemble "$raid_dev" --name "$raid_name" -v + udevadm wait --settle --timeout=30 "${expected_symlinks[@]}" + helper_check_device_symlinks + # Cleanup + mdadm -v --stop "$raid_dev" + udevadm settle + + echo "Parity raid (RAID 5)" + raid_name="mdparity" + raid_dev="/dev/md/$raid_name" + part_name="${raid_name}_part" + uuid="aaaaaaaa:bbbbbbbb:cccccccc:00000101" + expected_symlinks=( + "$raid_dev" + "/dev/disk/by-id/md-name-H:$raid_name" + "/dev/disk/by-id/md-uuid-$uuid" + "/dev/disk/by-label/$part_name" # ext4 partition + ) + # Create a simple RAID 5 with an ext4 filesystem + echo y | mdadm --create "$raid_dev" --name "$raid_name" --uuid "$uuid" /dev/disk/by-id/ata-foobar_deadbeefmdadm{0..2} -v -f --level=5 --raid-devices=3 + udevadm wait --settle --timeout=30 "$raid_dev" + mkfs.ext4 -L "$part_name" "$raid_dev" + udevadm wait --settle --timeout=30 "${expected_symlinks[@]}" + # Disassemble the array + mdadm -v --stop "$raid_dev" + udevadm settle + helper_check_device_symlinks + # Reassemble it and check if all required symlinks exist + mdadm --assemble "$raid_dev" --name "$raid_name" -v + udevadm wait --settle --timeout=30 "${expected_symlinks[@]}" + helper_check_device_symlinks + # Cleanup + mdadm -v --stop "$raid_dev" + udevadm settle + + echo "Mirror + parity raid (RAID 10)" + raid_name="mdmirpar" + raid_dev="/dev/md/$raid_name" + part_name="${raid_name}_part" + uuid="aaaaaaaa:bbbbbbbb:cccccccc:00001010" + expected_symlinks=( + "$raid_dev" + "/dev/disk/by-id/md-name-H:$raid_name" + "/dev/disk/by-id/md-uuid-$uuid" + "/dev/disk/by-label/$part_name" # ext4 partition + ) + # Create a simple RAID 10 with an ext4 filesystem + echo y | mdadm --create "$raid_dev" --name "$raid_name" --uuid "$uuid" /dev/disk/by-id/ata-foobar_deadbeefmdadm{0..3} -v -f --level=10 --raid-devices=4 + udevadm wait --settle --timeout=30 "$raid_dev" + mkfs.ext4 -L "$part_name" "$raid_dev" + udevadm wait --settle --timeout=30 "${expected_symlinks[@]}" + # Disassemble the array + mdadm -v --stop "$raid_dev" + udevadm settle + helper_check_device_symlinks + # Reassemble it and check if all required symlinks exist + mdadm --assemble "$raid_dev" --name "$raid_name" -v + udevadm wait --settle --timeout=30 "${expected_symlinks[@]}" + helper_check_device_symlinks +} + +testcase_mdadm_lvm() { + local part_name raid_name raid_dev uuid vgroup + local expected_symlinks=() + local devices=( + /dev/disk/by-id/ata-foobar_deadbeefmdadmlvm{0..4} + ) + + ls -l "${devices[@]}" + + raid_name="mdlvm" + raid_dev="/dev/md/$raid_name" + part_name="${raid_name}_part" + vgroup="${raid_name}_vg" + uuid="aaaaaaaa:bbbbbbbb:ffffffff:00001010" + expected_symlinks=( + "$raid_dev" + "/dev/$vgroup/mypart1" # LVM partition + "/dev/$vgroup/mypart2" # LVM partition + "/dev/disk/by-id/md-name-H:$raid_name" + "/dev/disk/by-id/md-uuid-$uuid" + "/dev/disk/by-label/$part_name" # ext4 partition + ) + # Create a RAID 10 with LVM + ext4 + echo y | mdadm --create "$raid_dev" --name "$raid_name" --uuid "$uuid" /dev/disk/by-id/ata-foobar_deadbeefmdadmlvm{0..3} -v -f --level=10 --raid-devices=4 + udevadm wait --settle --timeout=30 "$raid_dev" + # Create an LVM on the MD + lvm pvcreate -y "$raid_dev" + lvm pvs + lvm vgcreate "$vgroup" -y "$raid_dev" + lvm vgs + lvm vgchange -ay "$vgroup" + lvm lvcreate -y -L 4M "$vgroup" -n mypart1 + lvm lvcreate -y -L 8M "$vgroup" -n mypart2 + lvm lvs + udevadm wait --settle --timeout=30 "/dev/$vgroup/mypart1" "/dev/$vgroup/mypart2" + mkfs.ext4 -L "$part_name" "/dev/$vgroup/mypart2" + udevadm wait --settle --timeout=30 "${expected_symlinks[@]}" + # Disassemble the array + lvm vgchange -an "$vgroup" + mdadm -v --stop "$raid_dev" + udevadm settle + helper_check_device_symlinks + # Reassemble it and check if all required symlinks exist + mdadm --assemble "$raid_dev" --name "$raid_name" -v + udevadm wait --settle --timeout=30 "${expected_symlinks[@]}" + helper_check_device_symlinks +} + : >/failed udevadm settle |