summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrantisek Sumsal <frantisek@sumsal.cz>2021-07-30 16:56:10 +0200
committerYu Watanabe <watanabe.yu+github@gmail.com>2021-09-08 04:31:24 +0900
commitf2204ac27d8c707269e889f0ead0f833b9477ea7 (patch)
tree88f32c8ca4a4a3e8a9bf2be264f3495aadcf5da7
parent771a36439e955906290afc16a6fb3b10401892cf (diff)
downloadsystemd-f2204ac27d8c707269e889f0ead0f833b9477ea7.tar.gz
test: udev storage tests
l---------test/TEST-64-UDEV-STORAGE/Makefile1
-rwxr-xr-xtest/TEST-64-UDEV-STORAGE/test.sh198
-rw-r--r--test/units/testsuite-64.service7
-rwxr-xr-xtest/units/testsuite-64.sh41
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