dkms/run_test.sh

425 lines
16 KiB
Bash
Raw Normal View History

2022-10-09 17:17:07 +08:00
#!/bin/bash -e
# Test that dkms works properly
set -eu
# Change the to base directory
cd "$(dirname -- "$0")"
# To use a specific kernel version, use the environment variable KERNEL_VER
KERNEL_VER="${KERNEL_VER:-$(uname -r)}"
echo "Using kernel ${KERNEL_VER}"
# Override PATH to use the local dkms binary
PATH="$(pwd):$PATH"
export PATH
# Some helpers
dkms_status_grep_dkms_test() {
(dkms status | grep '^dkms_test/') || true
}
check_no_dkms_test() {
local found_moule
found_moule="$(dkms_status_grep_dkms_test)"
if [[ -n "$found_moule" ]] ; then
echo >&2 'Warning: module dkms_test is already in DKMS tree, removing...'
dkms remove dkms_test/1.0 >/dev/null
fi
if [[ -d /usr/src/dkms_test-1.0 ]] ; then
echo >&2 'Warning: directory /usr/src/dkms_test-1.0 already exists, removing'
rm -rf /usr/src/dkms_test-1.0
fi
}
run_with_expected_output() {
cat > test_cmd_expected_output.log
if "$@" > test_cmd_output.log 2>&1 ; then
# "depmod..." lines can have multiple points. Replace them, to be able to compare
sed 's/\([^.]\)\.\.\.\.*$/\1.../' -i test_cmd_output.log
# On CentOS, weak-modules is executed. Drop it from the output, to be more generic
sed '/^Adding any weak-modules$/d' -i test_cmd_output.log
sed '/^Removing any linked weak-modules$/d' -i test_cmd_output.log
# "depmod..." lines are missing when uninstalling modules on CentOS. Remove them to be more generic
if [[ $# -ge 2 && "$2" =~ uninstall|unbuild|remove ]] ; then
sed '/^depmod\.\.\.$/d' -i test_cmd_output.log
fi
# Signing related output. Drop it from the output, to be more generic
sed '/^Sign command:/d' -i test_cmd_output.log
sed '/^Signing key:/d' -i test_cmd_output.log
sed '/^Public certificate (MOK):/d' -i test_cmd_output.log
sed '/^Signing module \/var\/lib\/dkms\/dkms_test\/1.0\/build\/dkms_test.ko$/d' -i test_cmd_output.log
sed '/^Certificate or key are missing, generating them using update-secureboot-policy...$/d' -i test_cmd_output.log
sed '/^Certificate or key are missing, generating self signed certificate for MOK...$/d' -i test_cmd_output.log
sed "/^Binary .* not found, modules won't be signed$/d" -i test_cmd_output.log
# OpenSSL non-critical errors while signing. Remove them to be more generic
sed '/^At main.c:/d' -i test_cmd_output.log
sed '/^- SSL error:/d' -i test_cmd_output.log
if ! diff -U3 test_cmd_expected_output.log test_cmd_output.log ; then
echo >&2 "Error: unexpected output from: $*"
return 1
fi
rm test_cmd_expected_output.log test_cmd_output.log
else
echo "Error: command '$*' returned status $?"
cat test_cmd_output.log
rm test_cmd_expected_output.log test_cmd_output.log
return 1
fi
}
run_with_expected_error() {
local expected_error_code="$1"
local error_code
shift
cat > test_cmd_expected_output.log
if "$@" > test_cmd_output.log 2>&1 ; then
echo "Error: command '$*' was successful"
cat test_cmd_output.log
rm test_cmd_expected_output.log test_cmd_output.log
return 1
else
error_code=$?
fi
if [[ "${error_code}" != "${expected_error_code}" ]] ; then
echo "Error: command '$*' returned status ${error_code} instead of expected ${expected_error_code}"
cat test_cmd_output.log
rm test_cmd_expected_output.log test_cmd_output.log
return 1
fi
if ! diff -U3 test_cmd_expected_output.log test_cmd_output.log ; then
echo >&2 "Error: unexpected output from: $*"
return 1
fi
rm test_cmd_expected_output.log test_cmd_output.log
}
# Compute the expected destination module location
os_id="$(sed -n 's/^ID\s*=\s*\(.*\)$/\1/p' /etc/os-release | tr -d '"')"
mod_compression_ext=
case "${os_id}" in
centos | fedora | rhel | ovm | almalinux)
expected_dest_loc=extra
mod_compression_ext=.xz
;;
sles | suse | opensuse)
expected_dest_loc=updates
;;
arch | debian | ubuntu)
expected_dest_loc=updates/dkms
;;
alpine)
expected_dest_loc=kernel/extra
;;
*)
echo >&2 "Error: unknown Linux distribution ID ${os_id}"
exit 1
;;
esac
echo 'Checking that the environment is clean'
check_no_dkms_test
echo 'Adding the test module by version (expected error)'
run_with_expected_error 2 dkms add -m dkms_test -v 1.0 << EOF
Error! Could not find module source directory.
Directory: /usr/src/dkms_test-1.0 does not exist.
EOF
echo 'Adding the test module by directory'
run_with_expected_output dkms add test/dkms_test-1.0 << EOF
Creating symlink /var/lib/dkms/dkms_test/1.0/source -> /usr/src/dkms_test-1.0
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
dkms_test/1.0: added
EOF
if ! [[ -d /usr/src/dkms_test-1.0 ]] ; then
echo >&2 'Error: directory /usr/src/dkms_test-1.0 was not created'
return 1
fi
echo 'Adding the test module again (expected error)'
run_with_expected_error 3 dkms add test/dkms_test-1.0 << EOF
Error! DKMS tree already contains: dkms_test-1.0
You cannot add the same module/version combo more than once.
EOF
echo 'Adding the test module by version (expected error)'
run_with_expected_error 3 dkms add -m dkms_test -v 1.0 << EOF
Error! DKMS tree already contains: dkms_test-1.0
You cannot add the same module/version combo more than once.
EOF
echo 'Building the test module'
run_with_expected_output dkms build -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
Building module:
Cleaning build area...
make -j$(nproc) KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
Cleaning build area...
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
dkms_test/1.0, ${KERNEL_VER}, $(uname -m): built
EOF
echo 'Building the test module again'
run_with_expected_output dkms build -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
Module dkms_test/1.0 already built for kernel ${KERNEL_VER} ($(uname -m)), skip. You may override by specifying --force.
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
dkms_test/1.0, ${KERNEL_VER}, $(uname -m): built
EOF
echo 'Building the test module again by force'
run_with_expected_output dkms build -k "${KERNEL_VER}" -m dkms_test -v 1.0 --force << EOF
Building module:
Cleaning build area...
make -j$(nproc) KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
Cleaning build area...
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
dkms_test/1.0, ${KERNEL_VER}, $(uname -m): built
EOF
echo 'Installing the test module'
run_with_expected_output dkms install -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
dkms_test.ko${mod_compression_ext}:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
depmod...
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
dkms_test/1.0, ${KERNEL_VER}, $(uname -m): installed
EOF
echo 'Installing the test module again'
run_with_expected_output dkms install -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
Module dkms_test/1.0 already installed on kernel ${KERNEL_VER} ($(uname -m)), skip. You may override by specifying --force.
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
dkms_test/1.0, ${KERNEL_VER}, $(uname -m): installed
EOF
if ! [[ -f "/lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}" ]] ; then
echo >&2 "Error: module not found in /lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}"
exit 1
fi
echo 'Installing the test module again by force'
run_with_expected_output dkms install -k "${KERNEL_VER}" -m dkms_test -v 1.0 --force << EOF
Module dkms_test-1.0 for kernel ${KERNEL_VER} ($(uname -m)).
Before uninstall, this module version was ACTIVE on this kernel.
dkms_test.ko${mod_compression_ext}:
- Uninstallation
- Deleting from: /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
- Original module
- No original module was found for this module on this kernel.
- Use the dkms install command to reinstall any previous module version.
depmod...
dkms_test.ko${mod_compression_ext}:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
depmod...
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
dkms_test/1.0, ${KERNEL_VER}, $(uname -m): installed
EOF
echo 'Checking modinfo'
run_with_expected_output sh -c "modinfo /lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext} | head -n 4" << EOF
filename: /lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}
version: 1.0
description: A Simple dkms test module
license: GPL
EOF
echo 'Uninstalling the test module'
run_with_expected_output dkms uninstall -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
Module dkms_test-1.0 for kernel ${KERNEL_VER} ($(uname -m)).
Before uninstall, this module version was ACTIVE on this kernel.
dkms_test.ko${mod_compression_ext}:
- Uninstallation
- Deleting from: /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
- Original module
- No original module was found for this module on this kernel.
- Use the dkms install command to reinstall any previous module version.
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
dkms_test/1.0, ${KERNEL_VER}, $(uname -m): built
EOF
if [[ -e "/lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}" ]] ; then
echo >&2 "Error: module not removed in /lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}"
exit 1
fi
echo 'Uninstalling the test module again'
run_with_expected_output dkms uninstall -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
Module dkms_test 1.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
dkms_test/1.0, ${KERNEL_VER}, $(uname -m): built
EOF
echo 'Unbuilding the test module'
run_with_expected_output dkms unbuild -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
Module dkms_test 1.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
dkms_test/1.0: added
EOF
echo 'Unbuilding the test module again'
run_with_expected_output dkms unbuild -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
Module dkms_test 1.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
Module dkms_test 1.0 is not built for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
dkms_test/1.0: added
EOF
echo 'Removing the test module'
run_with_expected_output dkms remove -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
Module dkms_test 1.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
Module dkms_test 1.0 is not built for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
Deleting module dkms_test-1.0 completely from the DKMS tree.
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
EOF
if ! [[ -d /usr/src/dkms_test-1.0 ]] ; then
echo >&2 'Error: directory /usr/src/dkms_test-1.0 was removed'
return 1
fi
echo 'Adding the test module by version'
run_with_expected_output dkms add -m dkms_test -v 1.0 << EOF
Creating symlink /var/lib/dkms/dkms_test/1.0/source -> /usr/src/dkms_test-1.0
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
dkms_test/1.0: added
EOF
echo 'Removing the test module'
run_with_expected_output dkms remove --all -m dkms_test -v 1.0 << EOF
Deleting module dkms_test-1.0 completely from the DKMS tree.
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
EOF
echo 'Installing the test module by version (combining add, build, install)'
run_with_expected_output dkms install -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
Creating symlink /var/lib/dkms/dkms_test/1.0/source -> /usr/src/dkms_test-1.0
Building module:
Cleaning build area...
make -j$(nproc) KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
Cleaning build area...
dkms_test.ko${mod_compression_ext}:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
depmod...
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
dkms_test/1.0, ${KERNEL_VER}, $(uname -m): installed
EOF
if ! [[ -f "/lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}" ]] ; then
echo >&2 "Error: module not found in /lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}"
exit 1
fi
echo 'Checking modinfo'
run_with_expected_output sh -c "modinfo /lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext} | head -n 4" << EOF
filename: /lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}
version: 1.0
description: A Simple dkms test module
license: GPL
EOF
echo 'Removing the test module with --all'
run_with_expected_output dkms remove --all -m dkms_test -v 1.0 << EOF
Module dkms_test-1.0 for kernel ${KERNEL_VER} ($(uname -m)).
Before uninstall, this module version was ACTIVE on this kernel.
dkms_test.ko${mod_compression_ext}:
- Uninstallation
- Deleting from: /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
- Original module
- No original module was found for this module on this kernel.
- Use the dkms install command to reinstall any previous module version.
Deleting module dkms_test-1.0 completely from the DKMS tree.
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
EOF
if [[ -e "/lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}" ]] ; then
echo >&2 "Error: module not removed in /lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}"
exit 1
fi
echo 'Removing /usr/src/dkms_test-1.0'
rm -r /usr/src/dkms_test-1.0
echo 'Building the test module by config file (combining add, build)'
run_with_expected_output dkms build -k "${KERNEL_VER}" test/dkms_test-1.0/dkms.conf << EOF
Creating symlink /var/lib/dkms/dkms_test/1.0/source -> /usr/src/dkms_test-1.0
Building module:
Cleaning build area...
make -j$(nproc) KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
Cleaning build area...
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
dkms_test/1.0, ${KERNEL_VER}, $(uname -m): built
EOF
echo "Running dkms autoinstall"
run_with_expected_output dkms autoinstall -k "${KERNEL_VER}" << EOF
dkms_test.ko${mod_compression_ext}:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
depmod...
EOF
echo 'Removing the test module with --all'
run_with_expected_output dkms remove --all -m dkms_test -v 1.0 << EOF
Module dkms_test-1.0 for kernel ${KERNEL_VER} ($(uname -m)).
Before uninstall, this module version was ACTIVE on this kernel.
dkms_test.ko${mod_compression_ext}:
- Uninstallation
- Deleting from: /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
- Original module
- No original module was found for this module on this kernel.
- Use the dkms install command to reinstall any previous module version.
Deleting module dkms_test-1.0 completely from the DKMS tree.
EOF
run_with_expected_output dkms_status_grep_dkms_test << EOF
EOF
echo 'Removing /usr/src/dkms_test-1.0'
rm -r /usr/src/dkms_test-1.0
echo 'Checking that the environment is clean again'
check_no_dkms_test
echo 'All tests successful :)'