Skip to content

Commit

Permalink
tests: Try to capture screenshot via VNC if serial-console-connection…
Browse files Browse the repository at this point in the history
… fails

While debugging the failing GitHub Actions (see #278), we noticed that
it might serve useful to have a screenshot of the booted system
available. We can capture such a screenshot via vncsnapshot.

NOTE: we move the files inside `results` only if the directory as such
exists in $PWD, otherwise we'd fail the build when being executed as
`tests/build-vm-and-test.sh test` from inside the grml-debootstrap.git.
This happens when manually reproducing the GH tests, though then
`build-vm-and-test.sh` is supposed to be executed from the parent
directory of the `tests` directory (being the grml-debootstrap.git
checkout).
  • Loading branch information
mika committed Aug 17, 2024
1 parent 0b7adae commit ab13ef3
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
2 changes: 2 additions & 0 deletions tests/build-vm-and-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ fi
if [ "$1" == "setup" ]; then
sudo apt-get update
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
Expand Down
25 changes: 24 additions & 1 deletion tests/serial-console-connection
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#!/usr/bin/env python3
import argparse
import multiprocessing
import os
import pexpect
import serial
import shutil
import subprocess
import sys
import time
from pexpect import fdpexpect, TIMEOUT
Expand All @@ -19,6 +22,8 @@ parser.add_argument('--user', default="root",
help='user name to use for login (default: root)')
parser.add_argument('--password', default="grml",
help='password for login (default: grml)')
parser.add_argument('--screenshot', default="screenshot.jpg",
help='file name for screenshot captured via VNC on error (default: screenshot.jpg)')
parser.add_argument('--tries', default="12", type=int,
help='Number of retries for finding the login prompt')
parser.add_argument('--timeout', default="300", type=int,
Expand Down Expand Up @@ -64,6 +69,21 @@ 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(0)

print("Trying to capture screenshot via vncsnapshot")

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_login(args, ser, hostname, user, password, port, commands):
success = False
for i in range(args.tries):
Expand Down Expand Up @@ -102,6 +122,7 @@ def main():
user = args.user
commands = args.command
timeout = args.timeout
screenshot_file = args.screenshot

ser = serial.Serial(port, 115200)
ser.flushInput()
Expand All @@ -112,8 +133,10 @@ def main():
process.join(timeout=timeout)

if process.is_alive():
print("Reached timeout of %s seconds, aborting." % timeout)
print("Reached timeout of %s seconds" % timeout)
capture_vnc_screenshot(screenshot_file)
process.terminate()
print("Giving up serial-console-connection execution now")
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,13 +114,15 @@ if [ "$success" = "0" ] ; then
exit 1
fi

RC=0
"$TEST_PWD"/tests/serial-console-connection \
--screenshot "$TEST_PWD/tests/screenshot.jpg" \
--timeout 300 \
--tries 60 \
--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 @@ -134,7 +136,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 ab13ef3

Please sign in to comment.