diff --git a/tests/sanity/Makefile b/tests/sanity/Makefile new file mode 100644 index 0000000..9ea4f00 --- /dev/null +++ b/tests/sanity/Makefile @@ -0,0 +1,81 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Makefile of general/kmod/sanity +# Description: kmod test +# +# 2016-07-31 +# Author: Chunyu Hu +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2016 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing +# to use, modify, copy, or redistribute it subject to the terms +# and conditions of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +TENV=_env +ifeq ($(PKG_TOP_DIR),) + export PKG_TOP_DIR := $(shell p=$$PWD; while :; do \ + [ -e $$p/env.mk -o -z "$$p" ] && { echo $$p; break; }; p=$${p%/*}; done) + export _TOP_DIR := $(shell p=$$PWD; while :; do \ + [ -d $$p/.git -o -z "$$p" ] && { echo $$p; break; }; p=$${p%/*}; done) + -include $(PKG_TOP_DIR)/env.mk +endif +include $(TENV) +ifeq ($(_TOP_DIR),) + _TOP_DIR=/mnt/tests/$(TOPLEVEL_NAMESPACE) +endif + +export TESTVERSION=1.0 + +BUILT_FILES= + +FILES=$(TENV) $(METADATA) _env runtest.sh Makefile PURPOSE lib.sh + +.PHONY: all install download clean + +run: $(FILES) build + ( set +o posix; . /usr/bin/rhts_environment.sh; \ + . /usr/share/beakerlib/beakerlib.sh; \ + . runtest.sh ) + +build: $(BUILT_FILES) + test -x runtest.sh || chmod a+x runtest.sh + +clean: + rm -fr *~ $(BUILT_FILES) + +include /usr/share/rhts/lib/rhts-make.include + +$(METADATA): Makefile + @echo "Owner: Chunyu Hu " > $(METADATA) + @echo "Name: $(TEST)" >> $(METADATA) + @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) + @echo "Path: $(TEST_DIR)" >> $(METADATA) + @echo "Description: kmod kernel module check from kernel modules tools">> $(METADATA) + @echo "Type: Regression" >> $(METADATA) + @echo "TestTime: 1h" >> $(METADATA) + @echo "RunFor: kernel" >> $(METADATA) + @echo "Requires: kernel" >> $(METADATA) + @echo "Requires: sysstat perf trace-cmd" >> $(METADATA) + @echo "Requires: $(PACKAGE_NAME) python rpm wget" >> $(METADATA) + @echo "Priority: Normal" >> $(METADATA) + @echo "License: GPLv2" >> $(METADATA) + @echo "Confidential: no" >> $(METADATA) + @echo "Destructive: no" >> $(METADATA) + @echo "RhtsRequires: kernel-kernel-general-include" >> $(METADATA) + rhts-lint $(METADATA) + diff --git a/tests/sanity/PURPOSE b/tests/sanity/PURPOSE new file mode 100644 index 0000000..5950e75 --- /dev/null +++ b/tests/sanity/PURPOSE @@ -0,0 +1,4 @@ +Defaults to testing currently running kernel modules tools on all architectures. + +The test runs on any architecture, check normal kernel modules and compressed kernel modules for sanity + diff --git a/tests/sanity/_env b/tests/sanity/_env new file mode 100644 index 0000000..9f69344 --- /dev/null +++ b/tests/sanity/_env @@ -0,0 +1,8 @@ +#This file was generated automatically,do not manually change it. +export TOPLEVEL_NAMESPACE=kernel +export PKG_NAMESPACE=kernel/general +export RELATIVE_PATH=kmod/sanity +export PACKAGE=general +export PACKAGE_NAME=general +export PKG_LIST= +export TEST=/kernel/general/kmod/sanity diff --git a/tests/sanity/lib.sh b/tests/sanity/lib.sh new file mode 100755 index 0000000..d9a6c33 --- /dev/null +++ b/tests/sanity/lib.sh @@ -0,0 +1,258 @@ +#!/bin/bash + +dir_extra=/usr/lib/modules/$(uname -r)/extra +dir_updates=/usr/lib/modules/$(uname -r)/updates +dir_weak_updates=/usr/lib/modules/$(uname -r)/weak-updates +kmods=(base kmod_test_force kmod_test) + +function kmod_log_warn() +{ + echo "WARN: $*" +} + + +function kmod_log_pass() +{ + echo "PASS: $*" +} + +function kmod_log_fail() +{ + echo "FAIL: $*" +} + +function kmod_log_info() +{ + echo "INFO: $*" +} + +function kmod_log_err() +{ + echo "ERR: $*" +} + +function kmod_verify_exist() +{ + local files=$* + local ret=0 + local msg=0 + local f= + for f in $files; do + if ! test -f $f; then + ret=$((ret + 1)) + continue + fi + done + return $ret +} + +function kmod_verify_loaded() +{ + local kmods=$* + local ret=$? + for kmod in $kmods; do + lsmod | grep -w ${kmod/.ko/} + if [ $? -ne 0 ]; then + ret=$((ret+1)) + continue + fi + done + return $ret +} + +# tainted should be shown +function kmod_verify_dmesg() +{ + local str="$1" + dmesg | grep -i "$str" + return $? +} + +function kmod_verify_tainted() +{ + local kmod=$1 + shift + local taint_expect=$* + local ret=0 + local checker=./parse_taint.sh + local tainted=$(cat /proc/sys/kernel/tainted) + kmod_log_info "Kernel taint value: $tainted" + local flag= + for flag in $taint_expect; do + $checker $tainted | grep -we $flag || ret=$((ret + 1)) + done + return $ret +} + +function kmod_verify_tainted_module() +{ + local kmod=$1 + shift + local taint_expect="$*" + local ret=0 + + if ! test -f /sys/module/$kmod/taint; then + kmod_log_info "Kmod taint value on module $kmod not supported" + kmod_log_info "$(ls /sys/module/$kmod/)" + return 0 + fi + + local kmod_tainted=$(cat /sys/module/$kmod/taint) + ret=$(( $ret + 1 )) + kmod_log_info "Kmod taint value: $kmod_tainted" + + local flag= + local grep_exec="grep" + for flag in $*; do + grep_exec+=" -e $flag" + done + + echo "$kmod_tainted" | $grep_exec + ret=$? + return $ret +} + +function kmod_check_result() +{ + local opt=$1 + shift 1 + local dir=$1 + shift 1 + local files=$* + case $opt in + compile) + for f in $files; do + if kmod_verify_exist $dir/$f; then + kmod_log_pass "File exist: $dir/$f" + else + kmod_log_fail "File does not exist: $dir/$f" + return 1 + fi + done + ;; + load) + for f in $files; do + if kmod_verify_loaded $f; then + kmod_log_fail $f not loaded + return 1 + else + kmod_log_pass $f loaded + fi + done + ;; + unload) + for f in $files; do + if ! kmod_verify_loaded $f; then + kmod_log_fail $f unloaded + return 1 + else + kmod_log_pass $f not loaded + fi + done + ;; + *) + ;; + esac + return 0 +} + +# Locate the compiled kmods into several dirs for different +# tests. +function kmod_locate_extra() +{ + local ret=0 + if ! test -d $dir_extra; then + kmod_log_warn "$dir_extra does not exist." + return 1 + fi + local f= + for f in $*; do + cp -f $f $dir_extra || ret=$((ret + 1)) + done + depmod || ret=$((ret+1)) + return $ret +} + +function kmod_locate_updates() +{ + local ret=0 + if ! test -d $dir_updates; then + kmod_log_warn "$dir_updates does not exist." + return 1 + fi + for f in $*; do + cp -f $f $dir_updates || ret=$((ret + 1)) + done + depmod || ret=$((ret+1)) + return $ret +} + +function kmod_locate_weak_updates() +{ + local ret=0 + if ! test -d $dir_weak_updates; then + kmod_log_warn "$dir_weak_updates does not exist." + return 1 + fi + for f in $*; do + cp -f $f $dir_weak_updates || ret=$((ret + 1)) + done + depmod || ret=$((ret+1)) + return $ret +} + +function kmod_cleanup_all() +{ + local ret=$? + for ko in ${kmod[*]}; do + test -f $dir_extra/${ko}.ko && rm -r $dir_extra/${ko}.ko + test -f $dir_weak_updates/${ko}.ko && rm -r $dir_weak_updates/${ko}.ko + test -f $dir_updates/${ko}.ko && rm -r $dir_extra/${ko}.ko + done +} + +# The kmods should be loaded now. +function kmod_check_all_loaded() +{ + local ret=$? + lsmod | grep base -w + ret=$(($ret + $?)) + lsmod | grep -w kmod_test_dependency + ret=$(($ret + $?)) + lsmod | grep -w kmod_test_force + ret=$(($ret + $?)) + return $ret +} + +function kmod_unload_all() +{ + local ret=0 + lsmod | grep -w kmod_test_force && rmmod kmod_test_force + lsmod | grep -w base && rmmod base + ! lsmod | grep -w base + ret=$(($ret | $?)) + ! lsmod | grep -w kmod_test_force + ret=$(($ret | $?)) + return $ret +} + + +function kmod_load_all() +{ + local kmod= + kmod_unload_all || return $? + for kmod in $*; do + modprobe $kmod || return $? + done +} + +function kmod_load_all_force() +{ + local kmod= + kmod_unload_all || return $? + for kmod in $*; do + modprobe -f $kmod || return $? + dmesg | tail -n 10 + done +} + diff --git a/tests/sanity/parse_taint.sh b/tests/sanity/parse_taint.sh new file mode 100755 index 0000000..72ddf24 --- /dev/null +++ b/tests/sanity/parse_taint.sh @@ -0,0 +1,70 @@ +# /bin/bash +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Copyright (c) 2015 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing +# to use, modify, copy, or redistribute it subject to the terms +# and conditions of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +# Author: Chunyu Hu +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +taint_mask=( + [0]="P (G=Gnu)TAINT_PROPRIETARY_MODULE" + [1]="F TAINT_FORCED_MODULE" + [2]="S TAINT_UNSAFE_SMP" + [3]="R TAINT_FORCED_RMMOD" + [4]="M TAINT_MACHINE_CHECK" + [5]="B TAINT_BAD_PAGE" + [6]="U TAINT_USER" + [7]="D TAINT_DIE" + [8]="A TAINT_OVERRIDDEN_ACPI_TABLE" + [9]="W TAINT_WARN" + [10]="C TAINT_CRAP" + [11]="I TAINT_FIRMWARE_WORKAROUND" + [12]="O TAINT_OOT_MODULE [RHEL7 ONLY]" + [13]="E TAINT_UNSIGNED_MODULE" + [14]="L TAINT_SOFTLOCKUP" + [15]="K TAINT_LIVEPATCH" + [16]="? TAINT_16" + [17]="? TAINT_17" + [18]="? TAINT_18" + [19]="? TAINT_19" + [20]="? TAINT_20" + [21]="? TAINT_21" + [22]="? TAINT_22" + [23]="? TAINT_23" + [24]="? TAINT_24" + [25]="? TAINT_25" + [26]="? TAINT_26" + [27]="? TAINT_BIT_BY_ZOMBIE" + [28]="H TAINT_HARDWARE_UNSUPPORTED" + [29]="T TAINT_TECH_PREVIEW" + [30]="? TAINT_RESERVED30" + [31]="? TAINT_RESERVED31" +) + +function parse_taint(){ + for mask in ${!taint_mask[*]};do + if (( ((1< +# Author: Chunyu Hu +# Update: Ziqian SUN +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2015 Red Hat, Inc. +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +# PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Include Beaker environment +. /usr/bin/rhts-environment.sh || exit 1 +. /usr/share/beakerlib/beakerlib.sh || exit 1 +. lib.sh + +PACKAGE="kmod" +if [ -z $TESTARGS ]; then +export TESTARGS=$(rpm -q --queryformat '%{version}-%{release}\n' -qf /boot/config-$(uname -r)) +fi +name=kernel +version=$(echo $TESTARGS | awk 'BEGIN {FS="-"} {print $1 }') +release=$(echo $TESTARGS | awk 'BEGIN {FS="-"} {print $2 }') +DEBUG=0 +result=FAIL +FAIL=0 +PASS=0 +arch=`uname -m` + +export TESTS=${TESTS:-kmod_load_insmod kmod_load_modprobe kmod_modinfo} + +# Functions +function kmod_load_insmod() +{ + local m + for m in ${existed_unloaded}; do + #local m_name=$(basename ${m//.ko}) won't work for compressed kmod + local m_name=$(basename ${m} | sed "s/.ko//;s/.xz//;s/.gz//") + rlRun "insmod $mod_path/$m" + rlRun "lsmod | grep ${m_name}" + rlRun "rmmod ${m_name}" + rlRun "lsmod | grep ${m_name}" 1-255 + done +} + +function kmod_load_modprobe() +{ + rlRun "modprobe tea" + rlRun "modprobe -r tea" +} + +function kmod_modinfo() +{ + for m in ${existed_unloaded}; do + local m_name=$(basename ${m} | sed "s/.ko//;s/.xz//;s/.gz//") + rlRun "modinfo -l $m_name" + done +} + +RunKmod() { + local tests + for tests in $@; do + rlPhaseStartTest $tests + case $tests in + load_unload_kernel_modules) + load_unload_kernl_modules_func + ;; + load_unload_compressed_kernel_modules) + load_unload_compressed_kernel_module_func + ;; + *) + $tests + ;; + esac + rlPhaseEnd + done +} + +rlJournalStart + rlPhaseStartSetup + mod_list="/kernel/crypto/tgr192.ko /kernel/net/wireless/lib80211.ko /kernel/net/wireless/ath/ath9k/ath9k.ko /kernel/crypto/tgr192.ko.xz /kernel/net/wireless/lib80211.ko.xz /kernel/net/wireless/ath/ath9k/ath9k.ko.xz" + if [[ -L /lib && -d /lib ]]; then + mod_path=/usr/lib/modules/`uname -r`/ + else + mod_path=/lib/modules/`uname -r`/ + fi + existed_unloaded="" + local m + for m in ${mod_list}; do + test -f $mod_path/$m && existed_unloaded+="$m " + done + [ -z "$existed_unloaded" ] && rlDie "There is no right module path to use : $mod_list" + rlPhaseEnd + + rlPhaseStartTest + RunKmod $TESTS + rlPhaseEnd + + rlPhaseStartTest "Modprobe with wrong parameter" + rlRun -l "modprobe $wparam BADPARAM=this_should_fail" 0-1 + rlRun -l "dmesg | grep -i 'Unknown parameter' | grep 'BADPARAM' | grep '$wparam'" + rlPhaseEnd + + rlPhaseStartCleanup + rlPhaseEnd + + rlJournalPrintText +rlJournalEnd + diff --git a/tests/tests.yml b/tests/tests.yml index e69de29..d362e9f 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -0,0 +1,13 @@ +- hosts: localhost + tags: + - classic + roles: + - role: standard-test-beakerlib + tests: + - sanity + required_packages: + - kernel + - perf + - sysstat + - trace-cmd +