summaryrefslogtreecommitdiff
path: root/test/test-functions
diff options
context:
space:
mode:
Diffstat (limited to 'test/test-functions')
-rw-r--r--test/test-functions153
1 files changed, 133 insertions, 20 deletions
diff --git a/test/test-functions b/test/test-functions
index e69420aeca..37069396b7 100644
--- a/test/test-functions
+++ b/test/test-functions
@@ -21,13 +21,38 @@ if ! ROOTLIBDIR=$(pkg-config --variable=systemdutildir systemd); then
ROOTLIBDIR=/usr/lib/systemd
fi
-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"
+PATH_TO_INIT=$ROOTLIBDIR/systemd
+
+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 xargs"
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"
+is_built_with_asan() {
+ if ! type -P objdump >/dev/null; then
+ ddebug "Failed to find objdump. Assuming systemd hasn't been built with ASAN."
+ return 1
+ fi
+
+ # Borrowed from https://github.com/google/oss-fuzz/blob/cd9acd02f9d3f6e80011cc1e9549be526ce5f270/infra/base-images/base-runner/bad_build_check#L182
+ local _asan_calls=$(objdump -dC $BUILD_DIR/systemd | egrep "callq\s+[0-9a-f]+\s+<__asan" -c)
+ if (( $_asan_calls < 1000 )); then
+ return 1
+ else
+ return 0
+ fi
+}
+
+IS_BUILT_WITH_ASAN=$(is_built_with_asan && echo yes || echo no)
+
+if [[ "$IS_BUILT_WITH_ASAN" = "yes" ]]; then
+ STRIP_BINARIES=no
+ SKIP_INITRD=yes
+ PATH_TO_INIT=$ROOTLIBDIR/systemd-under-asan
+fi
+
function find_qemu_bin() {
# SUSE and Red Hat call the binary qemu-kvm. Debian and Gentoo call it kvm.
# Either way, only use this version if we aren't running in KVM, because
@@ -121,7 +146,7 @@ KERNEL_APPEND="$PARAMS \
root=/dev/sda1 \
raid=noautodetect \
loglevel=2 \
-init=$ROOTLIBDIR/systemd \
+init=$PATH_TO_INIT \
console=ttyS0 \
selinux=0 \
printk.devkmsg=on \
@@ -165,7 +190,7 @@ $KERNEL_APPEND \
run_nspawn() {
[[ -d /run/systemd/system ]] || return 1
- local _nspawn_cmd="$BUILD_DIR/systemd-nspawn --register=no --kill-signal=SIGKILL --directory=$TESTDIR/nspawn-root $ROOTLIBDIR/systemd $KERNEL_APPEND"
+ local _nspawn_cmd="$BUILD_DIR/systemd-nspawn $NSPAWN_ARGUMENTS --register=no --kill-signal=SIGKILL --directory=$TESTDIR/$1 $PATH_TO_INIT $KERNEL_APPEND"
if [[ "$NSPAWN_TIMEOUT" != "infinity" ]]; then
_nspawn_cmd="timeout --foreground $NSPAWN_TIMEOUT $_nspawn_cmd"
fi
@@ -217,6 +242,9 @@ setup_basic_environment() {
strip_binaries
install_depmod_files
generate_module_dependencies
+ if [[ "$IS_BUILT_WITH_ASAN" = "yes" ]]; then
+ create_asan_wrapper
+ fi
}
setup_selinux() {
@@ -293,6 +321,46 @@ EOF
chmod 0755 $_valgrind_wrapper
}
+create_asan_wrapper() {
+ local _asan_wrapper=$initdir/$ROOTLIBDIR/systemd-under-asan
+ ddebug "Create $_asan_wrapper"
+ cat >$_asan_wrapper <<EOF
+#!/bin/bash
+
+set -x
+
+DEFAULT_ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1
+DEFAULT_UBSAN_OPTIONS=print_stacktrace=1:print_summary=1
+DEFAULT_ENVIRONMENT="ASAN_OPTIONS=\$DEFAULT_ASAN_OPTIONS UBSAN_OPTIONS=\$DEFAULT_UBSAN_OPTIONS:halt_on_error=1"
+
+mount -t proc proc /proc
+mount -t sysfs sysfs /sys
+mount -o remount,rw /
+
+PATH_TO_ASAN=\$(find / -name '*libasan*' | sed 1q)
+if [[ "\$PATH_TO_ASAN" ]]; then
+ # A lot of services (most notably dbus) won't start without preloading libasan
+ # See https://github.com/systemd/systemd/issues/5004
+ DEFAULT_ENVIRONMENT="\$DEFAULT_ENVIRONMENT LD_PRELOAD=\$PATH_TO_ASAN"
+fi
+echo DefaultEnvironment=\$DEFAULT_ENVIRONMENT >>/etc/systemd/system.conf
+
+# ASAN and syscall filters aren't compatible with each other.
+find / -name '*.service' -type f | xargs sed -i 's/^\\(MemoryDeny\\|SystemCall\\)/#\\1/'
+
+# The redirection of ASAN reports to a file prevents them from ending up in /dev/null.
+# But, apparently, sometimes it doesn't work: https://github.com/google/sanitizers/issues/886.
+JOURNALD_CONF_DIR=/etc/systemd/system/systemd-journald.service.d
+mkdir -p "\$JOURNALD_CONF_DIR"
+printf "[Service]\nEnvironment=ASAN_OPTIONS=\$DEFAULT_ASAN_OPTIONS:log_path=/systemd-journald.asan.log\n" >"\$JOURNALD_CONF_DIR/env.conf"
+
+export ASAN_OPTIONS=\$DEFAULT_ASAN_OPTIONS:log_path=/systemd.asan.log UBSAN_OPTIONS=\$DEFAULT_UBSAN_OPTIONS
+exec $ROOTLIBDIR/systemd "\$@"
+EOF
+
+ chmod 0755 $_asan_wrapper
+}
+
create_strace_wrapper() {
local _strace_wrapper=$initdir/$ROOTLIBDIR/systemd-under-strace
ddebug "Create $_strace_wrapper"
@@ -353,20 +421,24 @@ get_ldpath() {
install_missing_libraries() {
# install possible missing libraries
- for i in $initdir{,/usr}/{sbin,bin}/* $initdir{,/usr}/lib/systemd/*; do
+ for i in $initdir{,/usr}/{sbin,bin}/* $initdir{,/usr}/lib/systemd/{,tests/{,manual/,unsafe/}}*; do
LD_LIBRARY_PATH=$(get_ldpath $i) inst_libs $i
done
}
create_empty_image() {
+ local _size=500
+ if [[ "$STRIP_BINARIES" = "no" ]]; then
+ _size=$((2*_size))
+ fi
rm -f "$TESTDIR/rootdisk.img"
# Create the blank file to use as a root filesystem
- dd if=/dev/null of="$TESTDIR/rootdisk.img" bs=1M seek=400
+ dd if=/dev/null of="$TESTDIR/rootdisk.img" bs=1M seek="$_size"
LOOPDEV=$(losetup --show -P -f $TESTDIR/rootdisk.img)
[ -b "$LOOPDEV" ] || return 1
echo "LOOPDEV=$LOOPDEV" >> $STATEFILE
sfdisk "$LOOPDEV" <<EOF
-,390M
+,$((_size-10))M
,
EOF
@@ -382,10 +454,10 @@ EOF
}
check_result_nspawn() {
- ret=1
- [[ -e $TESTDIR/nspawn-root/testok ]] && ret=0
- [[ -f $TESTDIR/nspawn-root/failed ]] && cp -a $TESTDIR/nspawn-root/failed $TESTDIR
- cp -a $TESTDIR/nspawn-root/var/log/journal $TESTDIR
+ local ret=1
+ [[ -e $TESTDIR/$1/testok ]] && ret=0
+ [[ -f $TESTDIR/$1/failed ]] && cp -a $TESTDIR/$1/failed $TESTDIR
+ cp -a $TESTDIR/$1/var/log/journal $TESTDIR
[[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed
ls -l $TESTDIR/journal/*/*.journal
test -s $TESTDIR/failed && ret=$(($ret+1))
@@ -395,7 +467,7 @@ check_result_nspawn() {
# can be overridden in specific test
check_result_qemu() {
- ret=1
+ local ret=1
mkdir -p $TESTDIR/root
mount ${LOOPDEV}p1 $TESTDIR/root
[[ -e $TESTDIR/root/testok ]] && ret=0
@@ -433,9 +505,8 @@ install_execs() {
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##[@+\!-]}; i=${i##\!}
+ sed -r -n 's|^Exec[a-zA-Z]*=[@+!-]*([^ ]+).*|\1|gp' $initdir/{$systemdsystemunitdir,$systemduserunitdir}/*.service \
+ | sort -u | while read i; do
# 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
@@ -519,7 +590,15 @@ install_libnss() {
install_dbus() {
inst $ROOTLIBDIR/system/dbus.socket
- inst $ROOTLIBDIR/system/dbus.service
+
+ # Fedora rawhide replaced dbus.service with dbus-daemon.service
+ if [ -f $ROOTLIBDIR/system/dbus-daemon.service ]; then
+ inst $ROOTLIBDIR/system/dbus-daemon.service
+ # Alias symlink
+ inst_symlink /etc/systemd/system/dbus.service
+ else
+ inst $ROOTLIBDIR/system/dbus.service
+ fi
find \
/etc/dbus-1 /usr/share/dbus-1 -xtype f \
@@ -552,12 +631,33 @@ install_pam() {
}
install_keymaps() {
+ # The first three paths may be deprecated.
+ # It seems now the last two paths are used by many distributions.
for i in \
/usr/lib/kbd/keymaps/include/* \
/usr/lib/kbd/keymaps/i386/include/* \
- /usr/lib/kbd/keymaps/i386/qwerty/us.*; do
+ /usr/lib/kbd/keymaps/i386/qwerty/us.* \
+ /usr/lib/kbd/keymaps/legacy/include/* \
+ /usr/lib/kbd/keymaps/legacy/i386/qwerty/us.*; do
+ [[ -f $i ]] || continue
+ inst $i
+ done
+
+ # When it takes any argument, then install more keymaps.
+ if [[ -n $1 ]]; then
+ for i in \
+ /usr/lib/kbd/keymaps/i386/*/* \
+ /usr/lib/kbd/keymaps/legacy/i386/*/*; do
[[ -f $i ]] || continue
inst $i
+ done
+ fi
+}
+
+install_zoneinfo() {
+ for i in /usr/share/zoneinfo/{,*/,*/*/}*; do
+ [[ -f $i ]] || continue
+ inst $i
done
}
@@ -595,6 +695,9 @@ setup_nspawn_root() {
cp -ar $initdir $TESTDIR/nspawn-root
# we don't mount in the nspawn root
rm -f $TESTDIR/nspawn-root/etc/fstab
+ if [[ "$RUN_IN_UNPRIVILEGED_CONTAINER" = "yes" ]]; then
+ cp -ar $TESTDIR/nspawn-root $TESTDIR/unprivileged-nspawn-root
+ fi
}
setup_basic_dirs() {
@@ -687,7 +790,7 @@ _lvl2char() {
# This enables:
# dwarn "This is a warning"
# echo "This is a warning" | dwarn
-LOG_LEVEL=4
+LOG_LEVEL=${LOG_LEVEL:-4}
dlog() {
[ -z "$LOG_LEVEL" ] && return 0
@@ -1411,11 +1514,19 @@ test_run() {
fi
fi
if [ -z "$TEST_NO_NSPAWN" ]; then
- if run_nspawn; then
- check_result_nspawn || return 1
+ if run_nspawn "nspawn-root"; then
+ check_result_nspawn "nspawn-root" || return 1
else
dwarn "can't run systemd-nspawn, skipping"
fi
+
+ if [[ "$RUN_IN_UNPRIVILEGED_CONTAINER" = "yes" ]]; then
+ if NSPAWN_ARGUMENTS="-U --private-network $NSPAWN_ARGUMENTS" run_nspawn "unprivileged-nspawn-root"; then
+ check_result_nspawn "unprivileged-nspawn-root" || return 1
+ else
+ dwarn "can't run systemd-nspawn, skipping"
+ fi
+ fi
fi
return 0
}
@@ -1444,7 +1555,9 @@ do_test() {
case $1 in
--run)
echo "TEST RUN: $TEST_DESCRIPTION"
- if test_run; then
+ test_run
+ ret=$?
+ if (( $ret == 0 )); then
echo "TEST RUN: $TEST_DESCRIPTION [OK]"
else
echo "TEST RUN: $TEST_DESCRIPTION [FAILED]"