]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - test/test-functions
tmpfiles: remove spurious curly braces in create_item()
[thirdparty/systemd.git] / test / test-functions
index 567a000b8dd5de328425d6466dd85b2bb496fbbe..963a32b5b54f1b4e534a172ef1d594e09e3baa66 100644 (file)
@@ -4,23 +4,30 @@
 PATH=/sbin:/bin:/usr/sbin:/usr/bin
 export PATH
 
-LOOKS_LIKE_DEBIAN=$(source /etc/os-release && [[ "$ID" = "debian" || "$ID_LIKE" = "debian" ]] && echo yes)
+LOOKS_LIKE_DEBIAN=$(source /etc/os-release && [[ "$ID" = "debian" || "$ID_LIKE" = "debian" ]] && echo yes || true)
+LOOKS_LIKE_ARCH=$(source /etc/os-release && [[ "$ID" = "arch" ]] && echo yes || true)
+LOOKS_LIKE_SUSE=$(source /etc/os-release && [[ "$ID_LIKE" = "suse" ]] && echo yes || true)
 KERNEL_VER=${KERNEL_VER-$(uname -r)}
 KERNEL_MODS="/lib/modules/$KERNEL_VER/"
 QEMU_TIMEOUT="${QEMU_TIMEOUT:-infinity}"
 NSPAWN_TIMEOUT="${NSPAWN_TIMEOUT:-infinity}"
 TIMED_OUT=  # will be 1 after run_* if *_TIMEOUT is set and test timed out
-FSTYPE="${FSTYPE:-ext3}"
-UNIFIED_CGROUP_HIERARCHY="${UNIFIED_CGROUP_HIERARCHY:-no}"
+[[ "$LOOKS_LIKE_SUSE" ]] && FSTYPE="${FSTYPE:-btrfs}" || FSTYPE="${FSTYPE:-ext4}"
+UNIFIED_CGROUP_HIERARCHY="${UNIFIED_CGROUP_HIERARCHY:-default}"
+EFI_MOUNT="$(bootctl -p 2>/dev/null || echo /boot)"
 
 if ! ROOTLIBDIR=$(pkg-config --variable=systemdutildir systemd); then
     echo "WARNING! Cannot determine rootlibdir from pkg-config, assuming /usr/lib/systemd" >&2
     ROOTLIBDIR=/usr/lib/systemd
 fi
 
-BASICTOOLS="sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm"
+BASICTOOLS="test sh bash setsid loadkeys setfont login sulogin gzip sleep echo mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln"
 DEBUGTOOLS="df free ls stty cat ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort hostname find"
 
+STATEDIR="${BUILD_DIR:-.}/test/$(basename $(dirname $(realpath $0)))"
+STATEFILE="$STATEDIR/.testdir"
+TESTLOG="$STATEDIR/test.log"
+
 function find_qemu_bin() {
     # SUSE and Red Hat call the binary qemu-kvm
     # Debian and Gentoo call it kvm
@@ -39,6 +46,9 @@ function find_qemu_bin() {
         # i386 version of QEMU
         [ "$QEMU_BIN" ] || QEMU_BIN=$(which -a qemu 2>/dev/null | grep '^/' -m1)
         ;;
+    ppc64*)
+        [ "$QEMU_BIN" ] || QEMU_BIN=$(which -a qemu-system-$ARCH 2>/dev/null | grep '^/' -m1)
+        ;;
     esac
 
     if [ ! -e "$QEMU_BIN" ]; then
@@ -52,29 +62,66 @@ function find_qemu_bin() {
 run_qemu() {
     if [ -f /etc/machine-id ]; then
         read MACHINE_ID < /etc/machine-id
-        [ -z "$INITRD" ] && [ -e "/boot/$MACHINE_ID/$KERNEL_VER/initrd" ] \
-            && INITRD="/boot/$MACHINE_ID/$KERNEL_VER/initrd"
-        [ -z "$KERNEL_BIN" ] && [ -e "/boot/$MACHINE_ID/$KERNEL_VER/linux" ] \
-            && KERNEL_BIN="/boot/$MACHINE_ID/$KERNEL_VER/linux"
+        [ -z "$INITRD" ] && [ -e "$EFI_MOUNT/$MACHINE_ID/$KERNEL_VER/initrd" ] \
+            && INITRD="$EFI_MOUNT/$MACHINE_ID/$KERNEL_VER/initrd"
+        [ -z "$KERNEL_BIN" ] && [ -e "$EFI_MOUNT/$MACHINE_ID/$KERNEL_VER/linux" ] \
+            && KERNEL_BIN="$EFI_MOUNT/$MACHINE_ID/$KERNEL_VER/linux"
+    fi
+
+    if [[ ! "$KERNEL_BIN" ]]; then
+        if [[ "$LOOKS_LIKE_ARCH" ]]; then
+            KERNEL_BIN=/boot/vmlinuz-linux
+        else
+            KERNEL_BIN=/boot/vmlinuz-$KERNEL_VER
+        fi
     fi
 
     default_fedora_initrd=/boot/initramfs-${KERNEL_VER}.img
     default_debian_initrd=/boot/initrd.img-${KERNEL_VER}
-    [ "$KERNEL_BIN" ] || KERNEL_BIN=/boot/vmlinuz-$KERNEL_VER
-    [ "$INITRD" ]     || { [ -e "$default_fedora_initrd" ] && INITRD=$default_fedora_initrd; }
-    [ "$INITRD" ]     || { [ "$LOOKS_LIKE_DEBIAN" ] && [ -e "$default_debian_initrd" ] && INITRD=$default_debian_initrd; }
+    default_arch_initrd=/boot/initramfs-linux.img
+    default_suse_initrd=/boot/initrd-${KERNEL_VER}
+    if [[ ! "$INITRD" ]]; then
+        if [[ -e "$default_fedora_initrd" ]]; then
+            INITRD="$default_fedora_initrd"
+        elif [[ "$LOOKS_LIKE_DEBIAN" && -e "$default_debian_initrd" ]]; then
+            INITRD="$default_debian_initrd"
+        elif [[ "$LOOKS_LIKE_ARCH" && -e "$default_arch_initrd" ]]; then
+            INITRD="$default_arch_initrd"
+        elif [[ "$LOOKS_LIKE_SUSE" && -e "$default_suse_initrd" ]]; then
+            INITRD="$default_suse_initrd"
+        fi
+    fi
+
     [ "$QEMU_SMP" ]   || QEMU_SMP=1
 
     find_qemu_bin || return 1
 
-    KERNEL_APPEND="root=/dev/sda1 \
+    local _cgroup_args
+    if [[ "$UNIFIED_CGROUP_HIERARCHY" = "yes" ]]; then
+        _cgroup_args="systemd.unified_cgroup_hierarchy=yes"
+    elif [[ "$UNIFIED_CGROUP_HIERARCHY" = "no" ]]; then
+        _cgroup_args="systemd.unified_cgroup_hierarchy=no systemd.legacy_systemd_cgroup_controller=yes"
+    elif [[ "$UNIFIED_CGROUP_HIERARCHY" = "hybrid" ]]; then
+        _cgroup_args="systemd.unified_cgroup_hierarchy=no systemd.legacy_systemd_cgroup_controller=no"
+    elif [[ "$UNIFIED_CGROUP_HIERARCHY" != "default" ]]; then
+        dfatal "Unknown UNIFIED_CGROUP_HIERARCHY. Got $UNIFIED_CGROUP_HIERARCHY, expected [yes|no|hybrid|default]"
+        exit 1
+    fi
+
+if [[ "$LOOKS_LIKE_SUSE" ]]; then
+    PARAMS+="rd.hostonly=0"
+else
+    PARAMS+="ro"
+fi
+
+KERNEL_APPEND="$PARAMS \
+root=/dev/sda1 \
 raid=noautodetect \
 loglevel=2 \
 init=$ROOTLIBDIR/systemd \
-ro \
 console=ttyS0 \
 selinux=0 \
-systemd.unified_cgroup_hierarchy=$UNIFIED_CGROUP_HIERARCHY \
+$_cgroup_args \
 $KERNEL_APPEND \
 "
 
@@ -113,12 +160,22 @@ $KERNEL_APPEND \
 run_nspawn() {
     [[ -d /run/systemd/system ]] || return 1
 
-    local _nspawn_cmd="../../systemd-nspawn --register=no --kill-signal=SIGKILL --directory=$TESTDIR/nspawn-root $ROOTLIBDIR/systemd $KERNEL_APPEND"
+    local _nspawn_cmd="$BUILD_DIR/systemd-nspawn --register=no --kill-signal=SIGKILL --directory=$TESTDIR/nspawn-root $ROOTLIBDIR/systemd $KERNEL_APPEND"
     if [[ "$NSPAWN_TIMEOUT" != "infinity" ]]; then
         _nspawn_cmd="timeout --foreground $NSPAWN_TIMEOUT $_nspawn_cmd"
     fi
 
-    _nspawn_cmd="env UNIFIED_CGROUP_HIERARCHY=$UNIFIED_CGROUP_HIERARCHY $_nspawn_cmd"
+    if [[ "$UNIFIED_CGROUP_HIERARCHY" = "hybrid" ]]; then
+        dwarn "nspawn doesn't support UNIFIED_CGROUP_HIERARCHY=hybrid, skipping"
+        exit
+    elif [[ "$UNIFIED_CGROUP_HIERARCHY" = "yes" || "$UNIFIED_CGROUP_HIERARCHY" = "no" ]]; then
+        _nspawn_cmd="env UNIFIED_CGROUP_HIERARCHY=$UNIFIED_CGROUP_HIERARCHY $_nspawn_cmd"
+    elif [[ "$UNIFIED_CGROUP_HIERARCHY" = "default" ]]; then
+        _nspawn_cmd="env --unset=UNIFIED_CGROUP_HIERARCHY $_nspawn_cmd"
+    else
+        dfatal "Unknown UNIFIED_CGROUP_HIERARCHY. Got $UNIFIED_CGROUP_HIERARCHY, expected [yes|no|hybrid|default]"
+        exit 1
+    fi
 
     (set -x; $_nspawn_cmd)
     rc=$?
@@ -225,6 +282,7 @@ create_valgrind_wrapper() {
     cat >$_valgrind_wrapper <<EOF
 #!/bin/bash
 
+mount -t proc proc /proc
 exec valgrind --leak-check=full --log-file=/valgrind.out $ROOTLIBDIR/systemd "\$@"
 EOF
     chmod 0755 $_valgrind_wrapper
@@ -255,8 +313,9 @@ install_dmevent() {
     inst_libdir_file "libdevmapper-event.so*"
     if [[ "$LOOKS_LIKE_DEBIAN" ]]; then
         # dmsetup installs 55-dm and 60-persistent-storage-dm on Debian/Ubuntu
-        # see https://anonscm.debian.org/cgit/pkg-lvm/lvm2.git/tree/debian/patches/0007-udev.patch
-        inst_rules 55-dm.rules 60-persistent-storage-dm.rules
+        # and since buster/bionic 95-dm-notify.rules
+        # see https://gitlab.com/debian-lvm/lvm2/blob/master/debian/patches/udev.patch
+        inst_rules 55-dm.rules 60-persistent-storage-dm.rules 95-dm-notify.rules
     else
         inst_rules 10-dm.rules 13-dm-disk.rules 95-dm-notify.rules
     fi
@@ -264,13 +323,20 @@ install_dmevent() {
 
 install_systemd() {
     # install compiled files
-    (cd $TEST_BASE_DIR/..; set -x; make DESTDIR=$initdir install)
+    local _ninja_bin=$(type -P ninja || type -P ninja-build)
+    if [[ -z "$_ninja_bin" ]]; then
+        dfatal "ninja was not found"
+        exit 1
+    fi
+    (set -x; DESTDIR=$initdir "$_ninja_bin" -C $BUILD_DIR install)
     # remove unneeded documentation
     rm -fr $initdir/usr/share/{man,doc}
     # we strip binaries since debug symbols increase binaries size a lot
     # and it could fill the available space
     strip_binaries
 
+   [[ "$LOOKS_LIKE_SUSE" ]] && setup_suse
+
     # enable debug logging in PID1
     echo LogLevel=debug >> $initdir/etc/systemd/system.conf
 }
@@ -299,6 +365,8 @@ create_empty_image() {
 ,
 EOF
 
+    udevadm settle
+
     local _label="-L systemd"
     # mkfs.reiserfs doesn't know -L. so, use --label instead
     [[ "$FSTYPE" == "reiserfs" ]] && _label="--label systemd"
@@ -320,6 +388,22 @@ check_result_nspawn() {
     return $ret
 }
 
+# can be overridden in specific test
+check_result_qemu() {
+    ret=1
+    mkdir -p $TESTDIR/root
+    mount ${LOOPDEV}p1 $TESTDIR/root
+    [[ -e $TESTDIR/root/testok ]] && ret=0
+    [[ -f $TESTDIR/root/failed ]] && cp -a $TESTDIR/root/failed $TESTDIR
+    cp -a $TESTDIR/root/var/log/journal $TESTDIR
+    umount $TESTDIR/root
+    [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed
+    ls -l $TESTDIR/journal/*/*.journal
+    test -s $TESTDIR/failed && ret=$(($ret+1))
+    [ -n "$TIMED_OUT" ] && ret=$(($ret+1))
+    return $ret
+}
+
 strip_binaries() {
     if [[ "$STRIP_BINARIES" = "no" ]]; then
         ddebug "Don't strip binaries"
@@ -341,13 +425,14 @@ EOF
 install_execs() {
     ddebug "install any Execs from the service files"
     (
-    export PKG_CONFIG_PATH=$TEST_BASE_DIR/../src/core/
+    export PKG_CONFIG_PATH=$BUILD_DIR/src/core/
     systemdsystemunitdir=$(pkg-config --variable=systemdsystemunitdir systemd)
     systemduserunitdir=$(pkg-config --variable=systemduserunitdir systemd)
     egrep -ho '^Exec[^ ]*=[^ ]+' $initdir/{$systemdsystemunitdir,$systemduserunitdir}/*.service \
          | while read i; do
-         i=${i##Exec*=}; i=${i##-}
-         inst $i
+         i=${i##Exec*=}; i=${i##[@+\!-]}; i=${i##\!}
+         # some {rc,halt}.local scripts and programs are okay to not exist, the rest should
+         inst $i || [ "${i%.local}" != "$i" ] || [ "${i%systemd-update-done}" != "$i" ]
      done
     )
 }
@@ -382,15 +467,15 @@ install_ld_so_conf() {
 }
 
 install_config_files() {
-    inst /etc/sysconfig/init
+    inst /etc/sysconfig/init || true
     inst /etc/passwd
     inst /etc/shadow
     inst /etc/login.defs
     inst /etc/group
     inst /etc/shells
     inst /etc/nsswitch.conf
-    inst /etc/pam.conf
-    inst /etc/securetty
+    inst /etc/pam.conf || true
+    inst /etc/securetty || true
     inst /etc/os-release
     inst /etc/localtime
     # we want an empty environment
@@ -399,8 +484,14 @@ install_config_files() {
     # set the hostname
     echo systemd-testsuite > $initdir/etc/hostname
     # fstab
+    if [[ "$LOOKS_LIKE_SUSE" ]]; then
+       ROOTMOUNT="/dev/sda1           /       ${FSTYPE}    rw 0 1"
+    else
+       ROOTMOUNT="LABEL=systemd           /       ${FSTYPE}    rw 0 1"
+    fi
+
     cat >$initdir/etc/fstab <<EOF
-LABEL=systemd           /       ${FSTYPE}    rw 0 1
+$ROOTMOUNT
 EOF
 }
 
@@ -434,12 +525,12 @@ install_dbus() {
 
 install_pam() {
     (
-    [[ "$LOOKS_LIKE_DEBIAN" ]] && type -p dpkg-architecture &>/dev/null && find "/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)/security" -xtype f
-    find \
-        /etc/pam.d \
-        /etc/security \
-        /lib64/security \
-        /lib/security -xtype f \
+    if [[ "$LOOKS_LIKE_DEBIAN" ]] && type -p dpkg-architecture &>/dev/null; then
+        find "/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)/security" -xtype f
+    else
+        find /lib*/security -xtype f
+    fi
+    find /etc/pam.d /etc/security -xtype f
     ) | while read file; do
         inst $file
     done
@@ -544,7 +635,6 @@ inst_libs() {
 }
 
 import_testdir() {
-    STATEFILE=".testdir"
     [[ -e $STATEFILE ]] && . $STATEFILE
     if [[ -z "$TESTDIR" ]] || [[ ! -d "$TESTDIR" ]]; then
         TESTDIR=$(mktemp --tmpdir=/var/tmp -d -t systemd-test.XXXXXX)
@@ -838,7 +928,7 @@ inst_library() {
 
     # Create additional symlinks.  See rev_symlinks description.
     for _symlink in $(rev_lib_symlinks $_src) $(rev_lib_symlinks $_reallib); do
-        [[ ! -e $initdir/$_symlink ]] && {
+        [[ -e $initdir/$_symlink ]] || {
             ddebug "Creating extra symlink: $_symlink"
             inst_symlink $_symlink
         }
@@ -970,6 +1060,7 @@ inst_rules() {
             fi
         done
         [[ $_found ]] || dinfo "Skipping udev rule: $_rule"
+        _found=
     done
 }
 
@@ -1293,6 +1384,37 @@ inst_libdir_file() {
     fi
 }
 
+setup_suse() {
+    ln -fs ../usr/bin/systemctl $initdir/bin/
+    ln -fs ../usr/lib/systemd $initdir/lib/
+    inst_simple "/usr/lib/systemd/system/haveged.service"
+}
+
+# can be overridden in specific test
+test_cleanup() {
+    umount $TESTDIR/root 2>/dev/null || true
+    [[ $LOOPDEV ]] && losetup -d $LOOPDEV || true
+    return 0
+}
+
+test_run() {
+    if [ -z "$TEST_NO_QEMU" ]; then
+        if run_qemu; then
+            check_result_qemu || return 1
+        else
+            dwarn "can't run QEMU, skipping"
+        fi
+    fi
+    if [ -z "$TEST_NO_NSPAWN" ]; then
+        if run_nspawn; then
+            check_result_nspawn || return 1
+        else
+            dwarn "can't run systemd-nspawn, skipping"
+        fi
+    fi
+    return 0
+}
+
 do_test() {
     if [[ $UID != "0" ]]; then
         echo "TEST: $TEST_DESCRIPTION [SKIPPED]: not root" >&2
@@ -1308,6 +1430,8 @@ do_test() {
         [[ -d $usrlibdir ]] && libdirs+=" $usrlibdir" && break
     done
 
+    mkdir -p "$STATEDIR"
+
     import_testdir
     import_initdir
 
@@ -1315,9 +1439,7 @@ do_test() {
         case $1 in
             --run)
                 echo "TEST RUN: $TEST_DESCRIPTION"
-                test_run
-                ret=$?
-                if [ $ret -eq 0 ]; then
+                if test_run; then
                     echo "TEST RUN: $TEST_DESCRIPTION [OK]"
                 else
                     echo "TEST RUN: $TEST_DESCRIPTION [FAILED]"
@@ -1326,30 +1448,30 @@ do_test() {
             --setup)
                 echo "TEST SETUP: $TEST_DESCRIPTION"
                 test_setup
-                exit $?;;
+                ;;
             --clean)
                 echo "TEST CLEANUP: $TEST_DESCRIPTION"
                 test_cleanup
                 rm -fr "$TESTDIR"
-                rm -f .testdir
-                exit $?;;
+                rm -f "$STATEFILE"
+                ;;
             --all)
+                ret=0
                 echo -n "TEST: $TEST_DESCRIPTION ";
                 (
                     test_setup && test_run
                     ret=$?
                     test_cleanup
                     rm -fr "$TESTDIR"
-                    rm -f .testdir
+                    rm -f "$STATEFILE"
                     exit $ret
-                ) </dev/null >test.log 2>&1
-                ret=$?
+                ) </dev/null >"$TESTLOG" 2>&1 || ret=$?
                 if [ $ret -eq 0 ]; then
-                    rm test.log
+                    rm "$TESTLOG"
                     echo "[OK]"
                 else
                     echo "[FAILED]"
-                    echo "see $(pwd)/test.log"
+                    echo "see $TESTLOG"
                 fi
                 exit $ret;;
             *) break ;;