diff options
Diffstat (limited to 'test')
-rwxr-xr-x | test/TEST-02-CRYPTSETUP/test.sh | 1 | ||||
-rwxr-xr-x | test/TEST-03-JOBS/test-jobs.sh | 7 | ||||
-rwxr-xr-x | test/TEST-04-JOURNAL/test-journal.sh | 8 | ||||
-rwxr-xr-x | test/TEST-04-JOURNAL/test.sh | 9 | ||||
-rw-r--r-- | test/TEST-06-SELINUX/Makefile | 10 | ||||
-rw-r--r-- | test/TEST-06-SELINUX/systemd_test.if | 8 | ||||
-rw-r--r-- | test/TEST-06-SELINUX/systemd_test.te | 50 | ||||
-rwxr-xr-x | test/TEST-06-SELINUX/test-selinux-checks.sh | 13 | ||||
-rwxr-xr-x | test/TEST-06-SELINUX/test.sh | 135 | ||||
-rw-r--r-- | test/sysv-generator-test.py | 18 | ||||
-rw-r--r-- | test/test-execute/exec-capabilityambientset-merge.service | 9 | ||||
-rw-r--r-- | test/test-execute/exec-capabilityambientset.service | 8 | ||||
-rw-r--r-- | test/test-functions | 100 |
13 files changed, 367 insertions, 9 deletions
diff --git a/test/TEST-02-CRYPTSETUP/test.sh b/test/TEST-02-CRYPTSETUP/test.sh index dada99df59..242090c761 100755 --- a/test/TEST-02-CRYPTSETUP/test.sh +++ b/test/TEST-02-CRYPTSETUP/test.sh @@ -77,7 +77,6 @@ EOF /dev/mapper/varcrypt /var ext3 defaults 0 1 EOF ) || return 1 - setup_nspawn_root ddebug "umount $TESTDIR/root/var" umount $TESTDIR/root/var diff --git a/test/TEST-03-JOBS/test-jobs.sh b/test/TEST-03-JOBS/test-jobs.sh index 42d475fe2f..4252a9a75d 100755 --- a/test/TEST-03-JOBS/test-jobs.sh +++ b/test/TEST-03-JOBS/test-jobs.sh @@ -4,9 +4,12 @@ # installed job. systemctl start --no-block hello-after-sleep.target -# sleep is now running, hello/start is waiting. Verify that: + systemctl list-jobs > /root/list-jobs.txt -grep 'sleep\.service.*running' /root/list-jobs.txt || exit 1 +while ! grep 'sleep\.service.*running' /root/list-jobs.txt; do + systemctl list-jobs > /root/list-jobs.txt +done + grep 'hello\.service.*waiting' /root/list-jobs.txt || exit 1 # This is supposed to finish quickly, not wait for sleep to finish. diff --git a/test/TEST-04-JOURNAL/test-journal.sh b/test/TEST-04-JOURNAL/test-journal.sh index 1ee39df432..3a05619ad5 100755 --- a/test/TEST-04-JOURNAL/test-journal.sh +++ b/test/TEST-04-JOURNAL/test-journal.sh @@ -51,5 +51,13 @@ journalctl --sync journalctl -b -o cat -t "$ID" >/output cmp /expected /output +# Don't lose streams on restart +systemctl start forever-print-hola +sleep 3 +systemctl restart systemd-journald +sleep 3 +systemctl stop forever-print-hola +[[ ! -f "/i-lose-my-logs" ]] + touch /testok exit 0 diff --git a/test/TEST-04-JOURNAL/test.sh b/test/TEST-04-JOURNAL/test.sh index 6c5b5cf34e..1a14f76060 100755 --- a/test/TEST-04-JOURNAL/test.sh +++ b/test/TEST-04-JOURNAL/test.sh @@ -57,6 +57,15 @@ ExecStart=/test-journal.sh Type=oneshot EOF + cat >$initdir/etc/systemd/system/forever-print-hola.service <<EOF +[Unit] +Description=ForeverPrintHola service + +[Service] +Type=simple +ExecStart=/bin/sh -x -c 'while :; do printf "Hola\n" || touch /i-lose-my-logs; sleep 1; done' +EOF + cp test-journal.sh $initdir/ setup_testsuite diff --git a/test/TEST-06-SELINUX/Makefile b/test/TEST-06-SELINUX/Makefile new file mode 100644 index 0000000000..5e89a29eff --- /dev/null +++ b/test/TEST-06-SELINUX/Makefile @@ -0,0 +1,10 @@ +all: + @make -s --no-print-directory -C ../.. all + @basedir=../.. TEST_BASE_DIR=../ ./test.sh --all +setup: + @make --no-print-directory -C ../.. all + @basedir=../.. TEST_BASE_DIR=../ ./test.sh --setup +clean: + @basedir=../.. TEST_BASE_DIR=../ ./test.sh --clean +run: + @basedir=../.. TEST_BASE_DIR=../ ./test.sh --run diff --git a/test/TEST-06-SELINUX/systemd_test.if b/test/TEST-06-SELINUX/systemd_test.if new file mode 100644 index 0000000000..25c91adce9 --- /dev/null +++ b/test/TEST-06-SELINUX/systemd_test.if @@ -0,0 +1,8 @@ +template(`systemd_test_base_template', ` + gen_require(` + attribute systemd_test_domain_type; + ') + + type $1_t, systemd_test_domain_type; + domain_type($1_t) +') diff --git a/test/TEST-06-SELINUX/systemd_test.te b/test/TEST-06-SELINUX/systemd_test.te new file mode 100644 index 0000000000..ff01c09b5e --- /dev/null +++ b/test/TEST-06-SELINUX/systemd_test.te @@ -0,0 +1,50 @@ +policy_module(systemd_test, 0.0.1) + +# declarations +attribute systemd_test_domain_type; + +systemd_test_base_template(systemd_test) +systemd_test_base_template(systemd_test_status) +systemd_test_base_template(systemd_test_start) +systemd_test_base_template(systemd_test_stop) +systemd_test_base_template(systemd_test_reload) + +# systemd_test_domain_type + +require { + role system_r; + role unconfined_r; + type bin_t; + type initrc_t; + type systemd_systemctl_exec_t; + type unconfined_service_t; +} + +role system_r types systemd_test_domain_type; +role unconfined_r types systemd_test_domain_type; + +allow systemd_test_domain_type bin_t: file entrypoint; +allow systemd_test_domain_type systemd_systemctl_exec_t: file entrypoint; +allow initrc_t systemd_test_domain_type: process transition; +allow unconfined_service_t systemd_test_domain_type: process transition; +corecmd_exec_bin(systemd_test_domain_type) +init_signal_script(systemd_test_domain_type) +init_sigchld_script(systemd_test_domain_type) +systemd_exec_systemctl(systemd_test_domain_type) +userdom_use_user_ttys(systemd_test_domain_type) +userdom_use_user_ptys(systemd_test_domain_type) + +optional_policy(` + dbus_system_bus_client(systemd_test_domain_type) + init_dbus_chat(systemd_test_domain_type) +') + +# systemd_test_*_t +require { + type systemd_unit_file_t; +} + +allow systemd_test_status_t systemd_unit_file_t: service { status }; +allow systemd_test_start_t systemd_unit_file_t: service { start }; +allow systemd_test_stop_t systemd_unit_file_t: service { stop }; +allow systemd_test_reload_t systemd_unit_file_t: service { reload }; diff --git a/test/TEST-06-SELINUX/test-selinux-checks.sh b/test/TEST-06-SELINUX/test-selinux-checks.sh new file mode 100755 index 0000000000..08d2ddf4f0 --- /dev/null +++ b/test/TEST-06-SELINUX/test-selinux-checks.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -x +set -e +set -o pipefail + +echo 1 >/sys/fs/selinux/enforce +runcon -t systemd_test_start_t systemctl start hola +runcon -t systemd_test_reload_t systemctl reload hola +runcon -t systemd_test_stop_t systemctl stop hola + +touch /testok +exit 0 diff --git a/test/TEST-06-SELINUX/test.sh b/test/TEST-06-SELINUX/test.sh new file mode 100755 index 0000000000..4f5895be66 --- /dev/null +++ b/test/TEST-06-SELINUX/test.sh @@ -0,0 +1,135 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh +TEST_DESCRIPTION="SELinux tests" + +# Requirements: +# Fedora 23 +# selinux-policy-targeted +# selinux-policy-devel + +. $TEST_BASE_DIR/test-functions +SETUP_SELINUX=yes +KERNEL_APPEND="$KERNEL_APPEND selinux=1" + +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)) + return $ret +} + +test_run() { + if run_qemu; then + check_result_qemu || return 1 + else + dwarn "can't run QEMU, skipping" + fi + return 0 +} + +test_setup() { + create_empty_image + mkdir -p $TESTDIR/root + mount ${LOOPDEV}p1 $TESTDIR/root + + # Create what will eventually be our root filesystem onto an overlay + ( + LOG_LEVEL=5 + eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) + + setup_basic_environment + + # setup the testsuite service + cat <<EOF >$initdir/etc/systemd/system/testsuite.service +[Unit] +Description=Testsuite service +After=multi-user.target + +[Service] +ExecStart=/test-selinux-checks.sh +Type=oneshot +EOF + + cat <<EOF >$initdir/etc/systemd/system/hola.service +[Service] +Type=oneshot +ExecStart=/bin/echo Start Hola +ExecReload=/bin/echo Reload Hola +ExecStop=/bin/echo Stop Hola +RemainAfterExit=yes +EOF + + setup_testsuite + + cat <<EOF >$initdir/etc/systemd/system/load-systemd-test-module.service +[Unit] +Description=Load systemd-test module +DefaultDependencies=no +Requires=local-fs.target +Conflicts=shutdown.target +After=local-fs.target +Before=sysinit.target shutdown.target autorelabel.service +ConditionSecurity=selinux +ConditionPathExists=|/.load-systemd-test-module + +[Service] +ExecStart=/bin/sh -x -c 'echo 0 >/sys/fs/selinux/enforce && cd /systemd-test-module && make -f /usr/share/selinux/devel/Makefile load && rm /.load-systemd-test-module' +Type=oneshot +TimeoutSec=0 +RemainAfterExit=yes +EOF + + touch $initdir/.load-systemd-test-module + mkdir -p $initdir/etc/systemd/system/basic.target.wants + ln -fs load-systemd-test-module.service $initdir/etc/systemd/system/basic.target.wants/load-systemd-test-module.service + + local _modules_dir=/var/lib/selinux + rm -rf $initdir/$_modules_dir + if ! cp -ar $_modules_dir $initdir/$_modules_dir; then + dfatal "Failed to copy $_modules_dir" + exit 1 + fi + + local _policy_headers_dir=/usr/share/selinux/devel + rm -rf $initdir/$_policy_headers_dir + inst_dir /usr/share/selinux + if ! cp -ar $_policy_headers_dir $initdir/$_policy_headers_dir; then + dfatal "Failed to copy $_policy_headers_dir" + exit 1 + fi + + mkdir $initdir/systemd-test-module + cp systemd_test.te $initdir/systemd-test-module + cp systemd_test.if $initdir/systemd-test-module + cp test-selinux-checks.sh $initdir + dracut_install -o sesearch + dracut_install runcon + dracut_install checkmodule semodule semodule_package m4 make /usr/libexec/selinux/hll/pp load_policy sefcontext_compile + ) || return 1 + + # mask some services that we do not want to run in these tests + ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service + ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service + ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service + ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket + ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service + + ddebug "umount $TESTDIR/root" + umount $TESTDIR/root +} + +test_cleanup() { + umount $TESTDIR/root 2>/dev/null + [[ $LOOPDEV ]] && losetup -d $LOOPDEV + return 0 +} + +do_test "$@" diff --git a/test/sysv-generator-test.py b/test/sysv-generator-test.py index 721e53a4ee..aca5f1eec6 100644 --- a/test/sysv-generator-test.py +++ b/test/sysv-generator-test.py @@ -23,6 +23,7 @@ import subprocess import tempfile import shutil from glob import glob +import collections try: from configparser import RawConfigParser @@ -32,6 +33,12 @@ except ImportError: sysv_generator = os.path.join(os.environ.get('builddir', '.'), 'systemd-sysv-generator') +class MultiDict(collections.OrderedDict): + def __setitem__(self, key, value): + if isinstance(value, list) and key in self: + self[key].extend(value) + else: + super(MultiDict, self).__setitem__(key, value) class SysvGeneratorTest(unittest.TestCase): def setUp(self): @@ -77,7 +84,14 @@ class SysvGeneratorTest(unittest.TestCase): for service in glob(self.out_dir + '/*.service'): if os.path.islink(service): continue - cp = RawConfigParser() + try: + # for python3 we need here strict=False to parse multiple + # lines with the same key + cp = RawConfigParser(dict_type=MultiDict, strict=False) + except TypeError: + # RawConfigParser in python2 does not have the strict option + # but it allows multiple lines with the same key by default + cp = RawConfigParser(dict_type=MultiDict) cp.optionxform = lambda o: o # don't lower-case option names with open(service) as f: cp.readfp(f) @@ -224,7 +238,7 @@ class SysvGeneratorTest(unittest.TestCase): s = self.run_generator()[1]['foo.service'] self.assertEqual(set(s.options('Unit')), set(['Documentation', 'SourcePath', 'Description', 'After'])) - self.assertEqual(s.get('Unit', 'After'), 'nss-lookup.target rpcbind.target') + self.assertEqual(s.get('Unit', 'After').split(), ['nss-lookup.target', 'rpcbind.target']) def test_lsb_deps(self): '''LSB header dependencies to other services''' diff --git a/test/test-execute/exec-capabilityambientset-merge.service b/test/test-execute/exec-capabilityambientset-merge.service new file mode 100644 index 0000000000..64964380e2 --- /dev/null +++ b/test/test-execute/exec-capabilityambientset-merge.service @@ -0,0 +1,9 @@ +[Unit] +Description=Test for AmbientCapabilities + +[Service] +ExecStart=/bin/sh -x -c 'c=$$(grep "CapAmb:" /proc/self/status); test "$$c" = "CapAmb: 0000000000003000"' +Type=oneshot +User=nobody +AmbientCapabilities=CAP_NET_ADMIN +AmbientCapabilities=CAP_NET_RAW diff --git a/test/test-execute/exec-capabilityambientset.service b/test/test-execute/exec-capabilityambientset.service new file mode 100644 index 0000000000..d63f884ef8 --- /dev/null +++ b/test/test-execute/exec-capabilityambientset.service @@ -0,0 +1,8 @@ +[Unit] +Description=Test for AmbientCapabilities + +[Service] +ExecStart=/bin/sh -x -c 'c=$$(grep "CapAmb:" /proc/self/status); test "$$c" = "CapAmb: 0000000000003000"' +Type=oneshot +User=nobody +AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW diff --git a/test/test-functions b/test/test-functions index 9288200717..59167b009b 100644 --- a/test/test-functions +++ b/test/test-functions @@ -92,7 +92,7 @@ $KERNEL_APPEND \ run_nspawn() { set -x - ../../systemd-nspawn --register=no --boot --directory=$TESTDIR/nspawn-root $ROOTLIBDIR/systemd $KERNEL_APPEND + ../../systemd-nspawn --register=no --directory=$TESTDIR/nspawn-root $ROOTLIBDIR/systemd $KERNEL_APPEND } setup_basic_environment() { @@ -111,21 +111,105 @@ setup_basic_environment() { install_keymaps install_terminfo install_execs + install_fsck install_plymouth install_debug_tools install_ld_so_conf + setup_selinux strip_binaries install_depmod_files generate_module_dependencies - # softlink mtab - ln -fs /proc/self/mounts $initdir/etc/mtab +} + +setup_selinux() { + # don't forget KERNEL_APPEND='... selinux=1 ...' + if [[ "$SETUP_SELINUX" != "yes" ]]; then + ddebug "Don't setup SELinux" + return 0 + fi + ddebug "Setup SELinux" + local _conf_dir=/etc/selinux + local _fixfiles_tools="bash uname cat sort uniq awk grep egrep head expr find rm secon setfiles" + + rm -rf $initdir/$_conf_dir + if ! cp -ar $_conf_dir $initdir/$_conf_dir; then + dfatal "Failed to copy $_conf_dir" + exit 1 + fi + + cat <<EOF >$initdir/etc/systemd/system/autorelabel.service +[Unit] +Description=Relabel all filesystems +DefaultDependencies=no +Requires=local-fs.target +Conflicts=shutdown.target +After=local-fs.target +Before=sysinit.target shutdown.target +ConditionSecurity=selinux +ConditionPathExists=|/.autorelabel + +[Service] +ExecStart=/bin/sh -x -c 'echo 0 >/sys/fs/selinux/enforce && fixfiles -f -F relabel && rm /.autorelabel && systemctl --force reboot' +Type=oneshot +TimeoutSec=0 +RemainAfterExit=yes +EOF + + touch $initdir/.autorelabel + mkdir -p $initdir/etc/systemd/system/basic.target.wants + ln -fs autorelabel.service $initdir/etc/systemd/system/basic.target.wants/autorelabel.service + + dracut_install $_fixfiles_tools + dracut_install fixfiles + dracut_install sestatus +} + +install_valgrind() { + if ! type -p valgrind; then + dfatal "Failed to install valgrind" + exit 1 + fi + + local _valgrind_bins=$(strace -e execve valgrind /bin/true 2>&1 >/dev/null | perl -lne 'print $1 if /^execve\("([^"]+)"/') + dracut_install $_valgrind_bins + + local _valgrind_libs=$(LD_DEBUG=files valgrind /bin/true 2>&1 >/dev/null | perl -lne 'print $1 if m{calling init: (/.*vgpreload_.*)}') + dracut_install $_valgrind_libs + + local _valgrind_dbg_and_supp=$( + strace -e open valgrind /bin/true 2>&1 >/dev/null | + perl -lne 'if (my ($fname) = /^open\("([^"]+).*= (?!-)\d+/) { print $fname if $fname =~ /debug|\.supp$/ }' + ) + dracut_install $_valgrind_dbg_and_supp +} + +create_valgrind_wrapper() { + local _valgrind_wrapper=$initdir/$ROOTLIBDIR/systemd-under-valgrind + ddebug "Create $_valgrind_wrapper" + cat >$_valgrind_wrapper <<EOF +#!/bin/bash + +exec valgrind --leak-check=full --log-file=/valgrind.out $ROOTLIBDIR/systemd "\$@" +EOF + chmod 0755 $_valgrind_wrapper +} + +install_fsck() { + dracut_install /sbin/fsck* + dracut_install -o /bin/fsck* } install_dmevent() { instmods dm_crypt =crypto type -P dmeventd >/dev/null && dracut_install dmeventd inst_libdir_file "libdevmapper-event.so*" - inst_rules 10-dm.rules 13-dm-disk.rules 95-dm-notify.rules + 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 + else + inst_rules 10-dm.rules 13-dm-disk.rules 95-dm-notify.rules + fi } install_systemd() { @@ -172,6 +256,10 @@ check_result_nspawn() { } strip_binaries() { + if [[ "$STRIP_BINARIES" = "no" ]]; then + ddebug "Don't strip binaries" + return 0 + fi ddebug "Strip binaries" find "$initdir" -executable -not -path '*/lib/modules/*.ko' -type f | xargs strip --strip-unneeded | ddebug } @@ -291,6 +379,10 @@ install_pam() { inst $file done + # pam_unix depends on unix_chkpwd. + # see http://www.linux-pam.org/Linux-PAM-html/sag-pam_unix.html + dracut_install -o unix_chkpwd + [[ "$LOOKS_LIKE_DEBIAN" ]] && cp /etc/pam.d/systemd-user $initdir/etc/pam.d/ } |