QEMU_MEM="${QEMU_MEM:-512M}"
IMAGE_NAME=${IMAGE_NAME:-default}
TEST_REQUIRE_INSTALL_TESTS="${TEST_REQUIRE_INSTALL_TESTS:-1}"
+TEST_PARALLELIZE="${TEST_PARALLELIZE:-0}"
LOOPDEV=
# Decide if we can (and want to) run QEMU with KVM acceleration.
PATH_TO_INIT=$ROOTLIBDIR/systemd
[ "$SYSTEMD_JOURNALD" ] || SYSTEMD_JOURNALD=$(which -a $BUILD_DIR/systemd-journald $ROOTLIBDIR/systemd-journald 2>/dev/null | grep '^/' -m1)
+[ "$SYSTEMD_JOURNAL_REMOTE" ] || SYSTEMD_JOURNAL_REMOTE=$(which -a $BUILD_DIR/systemd-journal-remote $ROOTLIBDIR/systemd-journal-remote 2>/dev/null | grep '^/' -m1)
[ "$SYSTEMD" ] || SYSTEMD=$(which -a $BUILD_DIR/systemd $ROOTLIBDIR/systemd 2>/dev/null | grep '^/' -m1)
[ "$SYSTEMD_NSPAWN" ] || SYSTEMD_NSPAWN=$(which -a $BUILD_DIR/systemd-nspawn systemd-nspawn 2>/dev/null | grep '^/' -m1)
[ "$JOURNALCTL" ] || JOURNALCTL=$(which -a $BUILD_DIR/journalctl journalctl 2>/dev/null | grep '^/' -m1)
mktemp
modprobe
mount
+ mountpoint
mv
nc
nproc
tar
tee
test
+ timeout
touch
tr
true
CONSOLE=ttyS0
+ rm -f "$initdir"/{testok,failed,skipped}
# make sure the initdir is not mounted to avoid concurrent access
cleanup_initdir
umount_loopback
$KERNEL_APPEND \
"
+ [ -e "$IMAGE_PRIVATE" ] && image="$IMAGE_PRIVATE" || image="$IMAGE_PUBLIC"
QEMU_OPTIONS="-smp $QEMU_SMP \
-net none \
-m $QEMU_MEM \
-nographic \
-kernel $KERNEL_BIN \
--drive format=raw,cache=unsafe,file=${IMAGESTATEDIR}/${IMAGE_NAME}.img \
+-drive format=raw,cache=unsafe,file=$image \
$QEMU_OPTIONS \
"
# success), or 1 if nspawn is not available.
run_nspawn() {
[[ -d /run/systemd/system ]] || return 1
+ rm -f "$initdir"/{testok,failed,skipped}
local _nspawn_cmd=(
--register=no
dwarn "nspawn doesn't support SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=hybrid, skipping"
exit
elif [[ "$UNIFIED_CGROUP_HIERARCHY" = "yes" || "$UNIFIED_CGROUP_HIERARCHY" = "no" ]]; then
- _nspawn_pre=("${nspawn_pre[@]}" env SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=$UNIFIED_CGROUP_HIERARCHY)
+ _nspawn_pre=("${_nspawn_pre[@]}" env SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=$UNIFIED_CGROUP_HIERARCHY)
elif [[ "$UNIFIED_CGROUP_HIERARCHY" = "default" ]]; then
- _nspawn_pre=("${nspawn_pre[@]}" env --unset=UNIFIED_CGROUP_HIERARCHY --unset=SYSTEMD_NSPAWN_UNIFIED_HIERARCHY)
+ _nspawn_pre=("${_nspawn_pre[@]}" env --unset=UNIFIED_CGROUP_HIERARCHY --unset=SYSTEMD_NSPAWN_UNIFIED_HIERARCHY)
else
dfatal "Unknown UNIFIED_CGROUP_HIERARCHY. Got $UNIFIED_CGROUP_HIERARCHY, expected [yes|no|hybrid|default]"
exit 1
# under ASan+UBSan in containers, which, in turn, are run in VMs.
# Let's limit which environments such services should be executed in.
mkdir -p /etc/systemd/system/systemd-hwdb-update.service.d
-printf "[Unit]\nConditionVirtualization=container\n\n[Service]\nTimeoutSec=180s\n" >/etc/systemd/system/systemd-hwdb-update.service.d/env-override.conf
+printf "[Unit]\nConditionVirtualization=container\n\n[Service]\nTimeoutSec=240s\n" >/etc/systemd/system/systemd-hwdb-update.service.d/env-override.conf
# Let's override another hard-coded timeout that kicks in too early
mkdir -p /etc/systemd/system/systemd-journal-flush.service.d
else
inst_rules 10-dm.rules 13-dm-disk.rules 95-dm-notify.rules
fi
+ if [[ "$LOOKS_LIKE_SUSE" ]]; then
+ inst_rules 60-persistent-storage.rules 61-persistent-storage-compat.rules 99-systemd.rules
+ fi
}
install_systemd() {
if [ -n "${LOOPDEV}" ]; then
ddebug "losetup -d $LOOPDEV"
losetup -d "${LOOPDEV}"
+ unset LOOPDEV
fi
}
-trap cleanup_loopdev EXIT
+trap cleanup_loopdev EXIT INT QUIT PIPE
create_empty_image() {
if [ -z "$IMAGE_NAME" ]; then
_size=$((4*_size))
fi
- image="${TESTDIR}/${IMAGE_NAME}.img"
- public="$IMAGESTATEDIR/${IMAGE_NAME}.img"
- echo "Setting up $public (${_size} MB)"
- rm -f "$image" "$public"
+ echo "Setting up $IMAGE_PUBLIC (${_size} MB)"
+ rm -f "$IMAGE_PRIVATE" "$IMAGE_PUBLIC"
# Create the blank file to use as a root filesystem
- truncate -s "${_size}M" "$image"
- ln -vs "$(realpath $image)" "$public"
+ truncate -s "${_size}M" "$IMAGE_PUBLIC"
- LOOPDEV=$(losetup --show -P -f "$public")
+ LOOPDEV=$(losetup --show -P -f "$IMAGE_PUBLIC")
[ -b "$LOOPDEV" ] || return 1
sfdisk "$LOOPDEV" <<EOF
,$((_size-50))M
mount_initdir() {
if [ -z "${LOOPDEV}" ]; then
- image="${IMAGESTATEDIR}/${IMAGE_NAME}.img"
+ [ -e "$IMAGE_PRIVATE" ] && image="$IMAGE_PRIVATE" || image="$IMAGE_PUBLIC"
LOOPDEV=$(losetup --show -P -f "$image")
[ -b "$LOOPDEV" ] || return 1
umount_loopback() {
# unmount the loopback device from all places. Otherwise we risk file
# system corruption.
- image="${IMAGESTATEDIR}/${IMAGE_NAME}.img"
- for device in $(losetup -l | awk '$6=="'"$image"'" {print $1}'); do
+ for device in $(losetup -l | awk '$6=="'"$IMAGE_PUBLIC"'" {print $1}'); do
ddebug "Unmounting all uses of $device"
mount | awk '/^'"${device}"'p/{print $1}' | xargs --no-run-if-empty umount -v
done
return $ret
}
+save_journal() {
+ if [ -n "${ARTIFACT_DIRECTORY}" ]; then
+ dest="${ARTIFACT_DIRECTORY}/${testname}.journal"
+ else
+ dest="$TESTDIR/system.journal"
+ fi
+
+ for j in $1/*; do
+ $SYSTEMD_JOURNAL_REMOTE \
+ -o $dest \
+ --getter="$JOURNALCTL -o export -D $j"
+
+ if [ -n "${TEST_SHOW_JOURNAL}" ]; then
+ echo "---- $j ----"
+ $JOURNALCTL --no-pager -o short-monotonic --no-hostname --priority=${TEST_SHOW_JOURNAL} -D $j
+ fi
+
+ rm -r $j
+ done
+
+ # we want to print this sometime later, so save this in a variable
+ JOURNAL_LIST="$(ls -l $dest*)"
+}
+
check_result_nspawn() {
local ret=1
local journald_report=""
local pids=""
[[ -e $1/testok ]] && ret=0
[[ -f $1/failed ]] && cp -a $1/failed $TESTDIR
- cp -a $1/var/log/journal $TESTDIR
- rm -r $1/var/log/journal/*
+ save_journal $1/var/log/journal
[[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed
- ls -l $TESTDIR/journal/*/*.journal
+ echo $JOURNAL_LIST
test -s $TESTDIR/failed && ret=$(($ret+1))
[ -n "$TIMED_OUT" ] && ret=$(($ret+1))
check_asan_reports "$1" || ret=$(($ret+1))
mount_initdir
[[ -e $initdir/testok ]] && ret=0
[[ -f $initdir/failed ]] && cp -a $initdir/failed $TESTDIR
- cp -a $initdir/var/log/journal $TESTDIR
- rm -r $initdir/var/log/journal/*
+ save_journal $initdir/var/log/journal
check_asan_reports "$initdir" || ret=$(($ret+1))
_umount_dir $initdir
[[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed
- ls -l $TESTDIR/journal/*/*.journal
+ echo $JOURNAL_LIST
test -s $TESTDIR/failed && ret=$(($ret+1))
[ -n "$TIMED_OUT" ] && ret=$(($ret+1))
return $ret
# also, plymouth is pulled in by rescue.service, but even there the exit code
# is ignored; as it's not present on some distros, don't fail if it doesn't exist
dinfo "Attempting to install $i"
- inst $i || [ "${i%.local}" != "$i" ] || [ "${i%systemd-update-done}" != "$i" ] || [ "/bin/plymouth" == "$i" ]
+ inst $i || [ "${i%.local}" != "$i" ] || [ "${i%systemd-update-done}" != "$i" ] || [ "${i##*/}" == "plymouth" ]
done
)
}
# /usr/libexec/plymouth/plymouth-populate-initrd -t $initdir
# dracut_install plymouth plymouthd
# else
- rm -f $initdir/{usr/lib,etc}/systemd/system/plymouth* $initdir/{usr/lib,etc}/systemd/system/*/plymouth*
+ rm -f $initdir/{usr/lib,lib,etc}/systemd/system/plymouth* $initdir/{usr/lib,lib,etc}/systemd/system/*/plymouth*
# fi
}
inst /etc/sysconfig/init || :
inst /etc/passwd
inst /etc/shadow
- inst /etc/login.defs
+ inst_any /etc/login.defs /usr/etc/login.defs
inst /etc/group
inst /etc/shells
- inst /etc/nsswitch.conf
+ inst_any /etc/nsswitch.conf /usr/etc/nsswitch.conf
inst /etc/pam.conf || :
inst /etc/os-release
inst /etc/localtime
# set the hostname
echo systemd-testsuite > $initdir/etc/hostname
+
+ # let's set up just one image with the traditional verbose output
+ if [ ${IMAGE_NAME} != "basic" ]; then
+ mkdir -p $initdir/etc/systemd/system.conf.d
+ echo -e '[Manager]\nStatusUnitFormat=name' >$initdir/etc/systemd/system.conf.d/status.conf
+ fi
}
install_basic_tools() {
EOF
export TESTDIR
fi
+
+ IMAGE_PRIVATE="${TESTDIR}/${IMAGE_NAME}.img"
+ IMAGE_PUBLIC="${IMAGESTATEDIR}/${IMAGE_NAME}.img"
}
import_initdir() {
ln -fs ../usr/bin/systemctl $initdir/bin/
ln -fs ../usr/lib/systemd $initdir/lib/
inst_simple "/usr/lib/systemd/system/haveged.service"
+ instmods ext4
}
_umount_dir() {
(
set +e
_umount_dir $initdir
- rm -vf "${IMAGESTATEDIR}/${IMAGE_NAME}.img"
+ rm -vf "$IMAGE_PUBLIC"
rm -vfr "$TESTDIR"
rm -vf "$STATEFILE"
) || :
if [ ${TEST_REQUIRE_INSTALL_TESTS} -ne 0 ] && \
type -P meson >/dev/null && \
[[ "$(meson configure $BUILD_DIR | grep install-tests | awk '{ print $2 }')" != "true" ]]; then
- dfatal "Needs to be built with -Dinstall-tests=true"
+ dfatal "$BUILD_DIR needs to be built with -Dinstall-tests=true"
exit 1
fi
- image="${TESTDIR}/${IMAGE_NAME}.img"
- public="${IMAGESTATEDIR}/${IMAGE_NAME}.img"
- if [ -e "$image" ]; then
- echo "Reusing existing image $PWD/$image → $(realpath $image)"
- mount_initdir
- elif [ -e "$public" ]; then
- echo "Reusing existing cached image $PWD/$public → $(realpath $public)"
- ln -s "$(realpath $public)" "$image"
+ if [ -e "$IMAGE_PRIVATE" ]; then
+ echo "Reusing existing image $IMAGE_PRIVATE → $(realpath $IMAGE_PRIVATE)"
mount_initdir
else
- test_create_image
+ if [ ! -e "$IMAGE_PUBLIC" ]; then
+ # Create the backing public image, but then completely unmount
+ # it and drop the loopback device responsible for it, since we're
+ # going to symlink/copy the image and mount it again from
+ # elsewhere.
+ test_create_image
+ test_setup_cleanup
+ umount_loopback
+ cleanup_loopdev
+ fi
+
+ echo "Reusing existing cached image $IMAGE_PUBLIC → $(realpath $IMAGE_PUBLIC)"
+ if [ ${TEST_PARALLELIZE} -ne 0 ]; then
+ cp -v "$(realpath $IMAGE_PUBLIC)" "$IMAGE_PRIVATE"
+ else
+ ln -sv "$(realpath $IMAGE_PUBLIC)" "$IMAGE_PRIVATE"
+ fi
+
+ mount_initdir
fi
setup_nspawn_root
test_run() {
mount_initdir
- rm -f "$initdir"/{testok,failed,skipped}
if [ -z "$TEST_NO_QEMU" ]; then
if run_qemu "$1"; then