From 8b55b3e820b005eeac6a6f0cae91d0846b420b79 Mon Sep 17 00:00:00 2001 From: Allison Karlitskaya Date: Fri, 15 Mar 2024 22:55:27 +0100 Subject: [PATCH] test/browser: run tests inside the tasks container This simplifies the "outside" setup quite a bit and gives us the same tasks container that test runs on the Cockpit CI run under. We have to deviate from the starter-kit template here: the tests have setup/teardown logic which wipes the podman slate completely clean. We can't possibly survive that, and trying to carve out an exemption would be difficult and would cut against the spirit of the deep clean that we're trying for. This isn't a problem for the cockpit-ws container, since it gets started after the tests start running. We tried to avoid that by using docker, but it caused other issues. systemd-nspawn seems to be a good approach here. Co-authored-by: Martin Pitt --- test/browser/browser.sh | 68 +++++++++++++++++----------------------- test/browser/main.fmf | 7 +---- test/browser/run-test.sh | 22 ++++++++----- test/vm.install | 3 +- 4 files changed, 45 insertions(+), 55 deletions(-) mode change 100755 => 100644 test/browser/run-test.sh diff --git a/test/browser/browser.sh b/test/browser/browser.sh index 0d5c581b2..074355821 100755 --- a/test/browser/browser.sh +++ b/test/browser/browser.sh @@ -1,27 +1,7 @@ #!/bin/sh -set -eux - -# test plan name, passed on to run-test.sh -PLAN="$1" - -export TEST_BROWSER=${TEST_BROWSER:-firefox} - -TESTS="$(realpath $(dirname "$0"))" -export SOURCE="$(realpath $TESTS/../..)" -# https://tmt.readthedocs.io/en/stable/overview.html#variables -export LOGS="${TMT_TEST_DATA:-$(pwd)/logs}" -mkdir -p "$LOGS" -chmod a+w "$LOGS" - -# install firefox (available everywhere in Fedora and RHEL) -# we don't need the H.264 codec, and it is sometimes not available (rhbz#2005760) -dnf install --disablerepo=fedora-cisco-openh264 -y --setopt=install_weak_deps=False firefox - -# nodejs 10 is too old for current Cockpit test API -if grep -q platform:el8 /etc/os-release; then - dnf module switch-to -y nodejs:16 -fi +set -eux +cd "${0%/*}/../.." # HACK: ensure that critical components are up to date: https://github.com/psss/tmt/issues/682 dnf update -y podman crun conmon criu @@ -37,6 +17,11 @@ fi # Show critical package versions rpm -q runc crun podman criu kernel-core selinux-policy cockpit-podman cockpit-bridge || true +# allow test to set up things on the machine +mkdir -p /root/.ssh +curl https://raw.githubusercontent.com/cockpit-project/bots/main/machine/identity.pub >> /root/.ssh/authorized_keys +chmod 600 /root/.ssh/authorized_keys + # create user account for logging in if ! id admin 2>/dev/null; then useradd -c Administrator -G wheel admin @@ -49,16 +34,6 @@ echo root:foobar | chpasswd # avoid sudo lecture during tests su -c 'echo foobar | sudo --stdin whoami' - admin -# create user account for running the test -if ! id runtest 2>/dev/null; then - useradd -c 'Test runner' runtest - # allow test to set up things on the machine - mkdir -p /root/.ssh - curl https://raw.githubusercontent.com/cockpit-project/bots/main/machine/identity.pub >> /root/.ssh/authorized_keys - chmod 600 /root/.ssh/authorized_keys -fi -chown -R runtest "$SOURCE" - # disable core dumps, we rather investigate them upstream where test VMs are accessible echo core > /proc/sys/kernel/core_pattern @@ -74,15 +49,28 @@ for retry in $(seq 5); do sleep $((5 * retry * retry)) done +CONTAINER="$(cat .cockpit-ci/container)" + +# import the test CONTAINER image as a directory tree for nspawn +mkdir /var/tmp/tasks +podman export "$(podman create --name tasks-import $CONTAINER)" | tar -x -C /var/tmp/tasks +podman rm tasks-import +podman rmi $CONTAINER + # image setup, shared with upstream tests -$TESTS/../vm.install +sh -x test/vm.install systemctl enable --now cockpit.socket podman.socket -# Run tests as unprivileged user -# once we drop support for RHEL 8, use this: -# runuser -u runtest --whitelist-environment=TEST_BROWSER,TEST_ALLOW_JOURNAL_MESSAGES,TEST_AUDIT_NO_SELINUX,SOURCE,LOGS $TESTS/run-test.sh $PLAN -runuser -u runtest --preserve-environment env USER=runtest HOME=$(getent passwd runtest | cut -f6 -d:) $TESTS/run-test.sh $PLAN - -RC=$(cat $LOGS/exitcode) -exit ${RC:-1} +# Run tests in the cockpit tasks container, as unprivileged user +# Use nspawn to avoid the tests killing the tasks container itself +chown -R 1111:1111 "${TMT_TEST_DATA}" . + +SYSTEMD_SECCOMP=0 systemd-nspawn \ + -D /var/tmp/tasks/ \ + --ephemeral \ + --user user \ + --bind="${TMT_TEST_DATA}":/logs --setenv=LOGS=/logs \ + --bind="$(pwd)":/source --setenv=SOURCE=/source \ + --bind-ro=/usr/lib/os-release:/run/host/usr/lib/os-release \ + sh /source/test/browser/run-test.sh "$@" diff --git a/test/browser/main.fmf b/test/browser/main.fmf index 1064b2e1c..e0fcac878 100644 --- a/test/browser/main.fmf +++ b/test/browser/main.fmf @@ -1,14 +1,9 @@ require: + - systemd-container - cockpit-podman - cockpit-ws - cockpit-system - - bzip2 - criu - - git-core - - libvirt-python3 - - make - - nodejs - - python3 # HACK: https://bugzilla.redhat.com/show_bug.cgi?id=2269485 - slirp4netns duration: 30m diff --git a/test/browser/run-test.sh b/test/browser/run-test.sh old mode 100755 new mode 100644 index 9b64cde5d..decf7c6ae --- a/test/browser/run-test.sh +++ b/test/browser/run-test.sh @@ -1,10 +1,10 @@ -#!/bin/sh set -eux PLAN="$1" +cd "${SOURCE}" + # tests need cockpit's bots/ libraries and test infrastructure -cd $SOURCE rm -f bots # common local case: existing bots symlink make bots test/common @@ -17,13 +17,16 @@ else grep '"version"' node_modules/chrome-remote-interface/package.json fi -. /etc/os-release +. /run/host/usr/lib/os-release export TEST_OS="${ID}-${VERSION_ID/./-}" if [ "${TEST_OS#centos-}" != "$TEST_OS" ]; then TEST_OS="${TEST_OS}-stream" fi +# Chromium sometimes gets OOM killed on testing farm +export TEST_BROWSER=firefox + # select subset of tests according to plan TESTS="$(test/common/run-tests -l)" case "$PLAN" in @@ -40,9 +43,12 @@ echo "TEST_ALLOW_JOURNAL_MESSAGES: ${TEST_ALLOW_JOURNAL_MESSAGES:-}" echo "TEST_AUDIT_NO_SELINUX: ${TEST_AUDIT_NO_SELINUX:-}" RC=0 -test/common/run-tests --nondestructive --machine 127.0.0.1:22 --browser 127.0.0.1:9090 $TESTS $EXCLUDES || RC=$? - -echo $RC > "$LOGS/exitcode" +./test/common/run-tests \ + --nondestructive \ + --machine localhost:22 \ + --browser localhost:9090 \ + $TESTS \ + $EXCLUDES \ +|| RC=$? cp --verbose Test* "$LOGS" || true -# deliver test result via exitcode file -exit 0 +exit $RC diff --git a/test/vm.install b/test/vm.install index f6c52cf53..1a3f7ff23 100755 --- a/test/vm.install +++ b/test/vm.install @@ -14,9 +14,10 @@ if grep -q ID.*debian /usr/lib/os-release; then fi # don't force https:// (self-signed cert) +mkdir -p /etc/cockpit printf "[WebService]\\nAllowUnencrypted=true\\n" > /etc/cockpit/cockpit.conf -if type firewall-cmd >/dev/null 2>&1; then +if systemctl is-active -q firewalld.service; then firewall-cmd --add-service=cockpit --permanent fi