Skip to content

Commit

Permalink
Merge pull request #284 from grml/mika/ci
Browse files Browse the repository at this point in the history
tests: capture screenshot on failure
  • Loading branch information
zeha committed Aug 19, 2024
2 parents 4dfb0d3 + 13e2a39 commit e43e6cc
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 6 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ jobs:

- name: Archive VM test results
uses: actions/upload-artifact@v4
if: always()
with:
name: vm-results-${{matrix.host_release}}-${{matrix.release}}-${{matrix.debootstrap}}
if-no-files-found: error
Expand Down
23 changes: 23 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Tests

The `tests` directory provides scripts and configuration files which are used within [grml-debootstrap's GitHub actions](https://github.com/grml/grml-debootstrap/actions).

> [!CAUTION]
> executing the scripts is potentially dangerous and may destroy the host system and/or any data. Run the tests only on throw-away systems and at your own risk.
The scripts are **not** designed to be executed manually, though it's possible to run them inside a local Debian throw-away VM.

> [!NOTE]
> make sure to have at least 8GB disk space and 2GB memory available on your VM.
Execute the following steps to build a Debian VM image (`qemu.img`) and run the tests against it:

```
sudo apt install git docker.io
git clone https://github.com/grml/grml-debootstrap
cd grml-debootstrap
sudo ./tests/docker-build-deb.sh --autobuild 01
sudo ./tests/build-vm-and-test.sh setup
sudo ./tests/build-vm-and-test.sh run
sudo ./tests/build-vm-and-test.sh test
```
6 changes: 4 additions & 2 deletions tests/build-vm-and-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ if [ ! -d ./tests ]; then
fi

if [ "$1" == "setup" ]; then
[ -x ./tests/goss ] || curl -fsSL https://goss.rocks/install | GOSS_DST="$(pwd)/tests" sh
sudo apt-get update
sudo apt-get -qq -y install qemu-system-x86 kpartx python3-pexpect python3-serial
sudo apt-get -qq -y install curl qemu-system-x86 kpartx python3-pexpect python3-serial
# vncsnapshot might not be available, though we don't want to abort execution then
sudo apt-get -qq -y install vncsnapshot || true
[ -x ./tests/goss ] || curl -fsSL https://goss.rocks/install | GOSS_DST="$(pwd)/tests" sh
# TODO: docker.io
exit 0
fi
Expand Down
29 changes: 27 additions & 2 deletions tests/serial-console-connection
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import argparse
import serial
import os
import shutil
import subprocess
import sys
import time
from pexpect import fdpexpect
Expand All @@ -15,7 +18,7 @@ parser.add_argument(
help="serial console device to connect " + "to (e.g. /dev/pts/X)",
)
parser.add_argument(
"--hostname", default="buster", help="hostname of the system for login process"
"--hostname", default="bookworm", help="hostname of the system for login process"
)
parser.add_argument("--user", default="root", help="user name to use for login")
parser.add_argument("--password", default="grml", help="password for login")
Expand All @@ -25,6 +28,11 @@ parser.add_argument(
type=int,
help="Maximum time for finding the login prompt, in seconds",
)
parser.add_argument(
"--screenshot",
default="screenshot.jpg",
help="file name for screenshot captured via VNC on error",
)
parser.add_argument(
"--tries",
default="12",
Expand Down Expand Up @@ -74,13 +82,29 @@ def login(ser, hostname, user, password, timeout=5):
child.expect("%s@%s" % (user, hostname), timeout=timeout)


def capture_vnc_screenshot(screenshot_file):
if not shutil.which("vncsnapshot"):
print("WARN: vncsnapshot not available, skipping vnc snapshot capturing.")
return

print("Trying to capture screenshot via vncsnapshot to", screenshot_file)

proc = subprocess.Popen(["vncsnapshot", "localhost", screenshot_file])
proc.wait()
if proc.returncode != 0:
print("WARN: failed to capture vnc snapshot :(")
else:
print("Screenshot file '%s' available" % os.path.abspath(screenshot_file))


def main():
args = parser.parse_args()
hostname = args.hostname
password = args.password
port = args.port
user = args.user
commands = args.command
screenshot_file = args.screenshot

ser = serial.Serial(port, 115200)
ser.flushInput()
Expand Down Expand Up @@ -116,6 +140,7 @@ def main():
# after poweroff, the serial device will probably vanish. do not attempt reading from it anymore.

if not success:
capture_vnc_screenshot(screenshot_file)
sys.exit(1)


Expand Down
13 changes: 11 additions & 2 deletions tests/test-vm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,14 @@ if [ "$success" = "0" ] ; then
exit 1
fi

RC=0
"$TEST_PWD"/tests/serial-console-connection \
--tries 180 \
--screenshot "$TEST_PWD/tests/screenshot.jpg" \
--port "$serial_port" \
--hostname "$VM_HOSTNAME" \
--poweroff \
"mount -t 9p -o trans=virtio,version=9p2000.L,rw $MOUNT_TAG /mnt && cd /mnt && ./testrunner"
"mount -t 9p -o trans=virtio,version=9p2000.L,rw $MOUNT_TAG /mnt && cd /mnt && ./testrunner" || RC=$?

if [ ! -d results ] || [ ! -f ./results/goss.tap ] || [ ! -f ./results/goss.exitcode ]; then
echo "Running tests inside VM failed for unknown reason" >&2
Expand All @@ -133,7 +135,14 @@ fi

echo "Finished serial console connection [timeout=${timeout}]."

mv results/* "$TESTS_RESULTSDIR/"
# in case of errors we might have captured a screenshot via VNC
if [ -r "${TEST_PWD}"/tests/screenshot.jpg ] ; then
cp "${TEST_PWD}"/tests/screenshot.jpg "${TESTS_RESULTSDIR}"
fi

if [ -d results ] ; then
mv results/* "$TESTS_RESULTSDIR/"
fi

bailout $RC

Expand Down

0 comments on commit e43e6cc

Please sign in to comment.