diff options
author | Frantisek Sumsal <frantisek@sumsal.cz> | 2021-07-30 16:56:10 +0200 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2021-09-08 04:31:24 +0900 |
commit | f2204ac27d8c707269e889f0ead0f833b9477ea7 (patch) | |
tree | 88f32c8ca4a4a3e8a9bf2be264f3495aadcf5da7 | |
parent | 771a36439e955906290afc16a6fb3b10401892cf (diff) | |
download | systemd-f2204ac27d8c707269e889f0ead0f833b9477ea7.tar.gz |
test: udev storage tests
l--------- | test/TEST-64-UDEV-STORAGE/Makefile | 1 | ||||
-rwxr-xr-x | test/TEST-64-UDEV-STORAGE/test.sh | 198 | ||||
-rw-r--r-- | test/units/testsuite-64.service | 7 | ||||
-rwxr-xr-x | test/units/testsuite-64.sh | 41 |
4 files changed, 247 insertions, 0 deletions
diff --git a/test/TEST-64-UDEV-STORAGE/Makefile b/test/TEST-64-UDEV-STORAGE/Makefile new file mode 120000 index 0000000000..e9f93b1104 --- /dev/null +++ b/test/TEST-64-UDEV-STORAGE/Makefile @@ -0,0 +1 @@ +../TEST-01-BASIC/Makefile
\ No newline at end of file diff --git a/test/TEST-64-UDEV-STORAGE/test.sh b/test/TEST-64-UDEV-STORAGE/test.sh new file mode 100755 index 0000000000..62e0041af8 --- /dev/null +++ b/test/TEST-64-UDEV-STORAGE/test.sh @@ -0,0 +1,198 @@ +#!/usr/bin/env bash +# vi: ts=4 sw=4 tw=0 et: +set -e + +TEST_DESCRIPTION="systemd-udev storage tests" +IMAGE_NAME="default" +TEST_NO_NSPAWN=1 +QEMU_TIMEOUT="${QEMU_TIMEOUT:-600}" + +# shellcheck source=test/test-functions +. "${TEST_BASE_DIR:?}/test-functions" + +USER_QEMU_OPTIONS="${QEMU_OPTIONS:-}" +USER_KERNEL_APPEND="${KERNEL_APPEND:-}" + +if ! get_bool "$QEMU_KVM"; then + echo "This test requires KVM, skipping..." + exit 0 +fi + +test_append_files() { + ( + instmods "=block" + instmods "=md" + instmods "=scsi" + instmods "=nvme" + install_dmevent + generate_module_dependencies + inst_binary lsblk + inst_binary wc + + for i in {0..127}; do + dd if=/dev/zero of="${TESTDIR:?}/disk$i.img" bs=1M count=1 + done + ) +} + +test_run_one() { + local test_id="${1:?}" + + if run_qemu "$test_id"; then + check_result_qemu || { echo "QEMU test failed"; return 1; } + fi + + return 0 +} + +test_run() { + local test_id="${1:?}" + local passed=() + local failed=() + local skipped=() + local ec state + + mount_initdir + + if get_bool "${TEST_NO_QEMU:=}" || ! find_qemu_bin; then + dwarn "can't run QEMU, skipping" + return 0 + fi + + # Execute each currently defined function starting with "testcase_" + for testcase in "${TESTCASES[@]}"; do + echo "------ $testcase: BEGIN ------" + { "$testcase" "$test_id"; ec=$?; } || : + case $ec in + 0) + passed+=("$testcase") + state="PASS" + ;; + 77) + skipped+=("$testcase") + state="SKIP" + ;; + *) + failed+=("$testcase") + state="FAIL" + esac + echo "------ $testcase: END ($state) ------" + done + + echo "Passed tests: ${#passed[@]}" + printf " * %s\n" "${passed[@]}" + echo "Skipped tests: ${#skipped[@]}" + printf " * %s\n" "${skipped[@]}" + echo "Failed tests: ${#failed[@]}" + printf " * %s\n" "${failed[@]}" + + [[ ${#failed[@]} -eq 0 ]] || return 1 + + return 0 +} + +testcase_megasas2_basic() { + if ! "${QEMU_BIN:?}" -device help | grep 'name "megasas-gen2"'; then + echo "megasas-gen2 device driver is not available, skipping test..." + return 77 + fi + + local qemu_opts=( + "-device megasas-gen2,id=scsi0" + "-device megasas-gen2,id=scsi1" + "-device megasas-gen2,id=scsi2" + "-device megasas-gen2,id=scsi3" + ) + + for i in {0..127}; do + # Add 128 drives, 32 per bus + qemu_opts+=( + "-device scsi-hd,drive=drive$i,bus=scsi$((i / 32)).0,channel=0,scsi-id=$((i % 32)),lun=0" + "-drive format=raw,cache=unsafe,file=${TESTDIR:?}/disk$i.img,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:?}" +} + +testcase_nvme_basic() { + if ! "${QEMU_BIN:?}" -device help | grep 'name "nvme"'; then + echo "nvme device driver is not available, skipping test..." + return 77 + fi + + for i in {0..27}; do + qemu_opts+=( + "-device nvme,drive=nvme$i,serial=deadbeef$i,num_queues=8" + "-drive format=raw,cache=unsafe,file=${TESTDIR:?}/disk$i.img,if=none,id=nvme$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:?}" +} + +# Test for issue https://github.com/systemd/systemd/issues/20212 +testcase_virtio_scsi_identically_named_partitions() { + if ! "${QEMU_BIN:?}" -device help | grep 'name "virtio-scsi-pci"'; then + echo "virtio-scsi-pci device driver is not available, skipping test..." + return 77 + fi + + # Create 16 disks, with 8 partitions per disk (all identically named) + # and attach them to a virtio-scsi controller + local qemu_opts=("-device virtio-scsi-pci,id=scsi0,num_queues=4") + local diskpath="${TESTDIR:?}/namedpart0.img" + local lodev + + # Save some time (and storage life) during local testing + if [[ ! -e "$diskpath" ]]; then + dd if=/dev/zero of="$diskpath" bs=1M count=18 + lodev="$(losetup --show -f -P "$diskpath")" + sfdisk "${lodev:?}" <<EOF +label: gpt + +name="Hello world", size=2M +name="Hello world", size=2M +name="Hello world", size=2M +name="Hello world", size=2M +name="Hello world", size=2M +name="Hello world", size=2M +name="Hello world", size=2M +name="Hello world", size=2M +EOF + losetup -d "$lodev" + fi + + for i in {0..15}; do + diskpath="${TESTDIR:?}/namedpart$i.img" + if [[ $i -gt 0 ]]; then + cp -uv "${TESTDIR:?}/namedpart0.img" "$diskpath" + fi + + qemu_opts+=( + "-device scsi-hd,drive=drive$i,bus=scsi0.0,channel=0,scsi-id=0,lun=$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:-}" + # Limit the number of VCPUs and set a timeout to make sure we trigger the issue + QEMU_OPTIONS="${qemu_opts[*]} ${USER_QEMU_OPTIONS:-}" + QEMU_SMP=1 QEMU_TIMEOUT=60 test_run_one "${1:?}" +} + +# 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 + read -ra TESTCASES <<< "$TESTCASES" +else + # This must run after all functions were defined, otherwise `declare -F` won't + # see them + mapfile -t TESTCASES < <(declare -F | awk '$3 ~ /^testcase_/ {print $3;}') +fi + +do_test "$@" diff --git a/test/units/testsuite-64.service b/test/units/testsuite-64.service new file mode 100644 index 0000000000..4c8f701e73 --- /dev/null +++ b/test/units/testsuite-64.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-64-UDEV + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/units/testsuite-64.sh b/test/units/testsuite-64.sh new file mode 100755 index 0000000000..4505306607 --- /dev/null +++ b/test/units/testsuite-64.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# vi: ts=4 sw=4 tw=0 et: + +set -eux +set -o pipefail + +testcase_megasas2_basic() { + lsblk -S + [[ "$(lsblk --scsi --noheadings | wc -l)" -ge 128 ]] +} + +testcase_nvme_basic() { + lsblk --noheadings | grep "^nvme" + [[ "$(lsblk --noheadings | grep -c "^nvme")" -ge 28 ]] +} + +testcase_virtio_scsi_identically_named_partitions() { + lsblk --noheadings -a -o NAME,PARTLABEL + [[ "$(lsblk --noheadings -a -o NAME,PARTLABEL | grep -c "Hello world")" -eq $((16 * 8)) ]] +} + +: >/failed + +udevadm settle + +lsblk -a + +# TEST_FUNCTION_NAME is passed on the kernel command line via systemd.setenv= +# in the respective test.sh file +if ! command -v "${TEST_FUNCTION_NAME:?}"; then + echo >&2 "Missing verification handler for test case '$TEST_FUNCTION_NAME'" + exit 1 +fi + +echo "TEST_FUNCTION_NAME=$TEST_FUNCTION_NAME" +"$TEST_FUNCTION_NAME" + +systemctl status systemd-udevd + +touch /testok +rm /failed |