|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [RFC XEN PATCH 10/13] pytest: Add guest test
From: Anthony PERARD <anthony.perard@xxxxxxxxxx>
Adding a second test, to help show how to improve the fixtures, and
needed code in libraries
That test copies part of the run tools-test tests, but we could shared
that better.
Then, we ssh to the host, to both follow the guest log files and to
prepare and start the guest, over several SSH channel.
tail_log() could go into a lib.
And I don't know yet what to do with the collected threads object.
I also want to get rid of the guest_boot_script marker, and ssh to the
guest instead.
Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
---
automation/pytest/test_boot.py | 97 ++++++++++++++++++++++++++++++++++
1 file changed, 97 insertions(+)
diff --git a/automation/pytest/test_boot.py b/automation/pytest/test_boot.py
index 5a7ec43fa52b..089aa1e6c063 100644
--- a/automation/pytest/test_boot.py
+++ b/automation/pytest/test_boot.py
@@ -3,8 +3,11 @@ import os
import paramiko
from pathlib import Path
import pytest
+from queue import Queue
import random
import string
+from textwrap import dedent
+from threading import Thread
from typing import Generator
from lib.boot_binary import BootBinary
@@ -138,3 +141,97 @@ def test_xen_tools_tests(machine_on_ipmi: IPMI,
errormsg = stderr.read()
if errormsg:
logging.info(f"cmd errro: {errormsg!r}")
+
+
+@pytest.mark.timeout(600)
+@pytest.mark.guest_boot_script(dedent(f"""
+ ifconfig eth0 10.1.105.101
+ until ping -c 10 {os.environ["HOST_IP4"].partition('/')[0]}; do
+ sleep 1
+ done
+ echo \"guest ping test passed\"
+ """))
+def test_guest(
+ machine_on_ipmi: IPMI,
+ sshkey_for_test: paramiko.pkey.PKey,
+ boot_string: str,
+ ) -> None:
+ expect_string = boot_string
+ for line in machine_on_ipmi.console_output_generator():
+ #
+ # Wait for `expect_string` for the test to succeed
+ #
+ if expect_string in line:
+ logging.info(f"got expect_string '{line}'.")
+ break
+ #
+ # Some common expected or not console outputs.
+ #
+ if "Latest ChangeSet:" in line:
+ logging.info(f"Test xen build from '{line}'.")
+ if "Manual reset required ('noreboot' specified)" in line:
+ # Test failed, could wait a bit before failing the test.
+ logging.error("Xen panic")
+
+ with paramiko.client.SSHClient() as ssh:
+ threads = []
+ ssh_logs: Queue[str] = Queue()
+ ssh.set_missing_host_key_policy(paramiko.client.WarningPolicy)
+ logging.debug(f"connecting to {os.environ['HOST_IP4'].split('/')[0]}")
+ ssh.connect(os.environ['HOST_IP4'].split('/')[0],
+ username='root',
+ pkey=sshkey_for_test,
+ timeout=10,
+ )
+
+ def ssh_channel_read(stdout, prefix):
+ for output in stdout:
+ ssh_logs.put(f"{prefix}{output.strip()}")
+
+ def tail_log(file: Path, prefix: str):
+ stdin, stdout, stderr = ssh.exec_command(f"tail -n0 -F {file}")
+ stdin.close()
+ # Dirty, should keep `stderr` to clean it up
+ t = Thread(target=ssh_channel_read, args=(stdout, prefix))
+ t.start()
+ return t
+
+ threads += [
+ tail_log(Path("/var/log/xen/console/guest-domU.log"), "(domU) "),
+ tail_log(Path("/var/log/xen/qemu-dm-domU.log"), "(qemu-dm) "),
+ ]
+
+ cmd = dedent(f"""
+ set -x
+ pxe_host="{os.environ["PXE_HOST"]}"
+ http_pxe_path="{os.environ["PXE_HTTP_PATH"]}"
+ wget http://${{pxe_host}}/${{http_pxe_path}}/bzImage -O
/boot/vmlinuz-domU
+ wget http://${{pxe_host}}/${{http_pxe_path}}/guest-rootfs.cpio.gz
-O /boot/initrd-domU
+ xl -Tvvv create /etc/xen/domU.cfg 2>&1
+ """)
+ logging.info(f"Exec command: {cmd}")
+ stdin, stdout, stderr = ssh.exec_command(cmd)
+
+ # everything is on stderr, both wget and xl output
+ t = Thread(target=ssh_channel_read, args=(stderr, ""))
+ t.start()
+ threads.append(t)
+ t = Thread(target=ssh_channel_read, args=(stdout, ""))
+ t.start()
+ threads.append(t)
+
+ # Log while `xl` is preparing the guest to start
+ while t.is_alive():
+ line = ssh_logs.get()
+ logging.debug(line)
+
+ xl_exit_status = stderr.channel.recv_exit_status()
+ assert xl_exit_status == 0
+
+ # `xl` have exited, continue logging the guest output
+ while True:
+ line = ssh_logs.get()
+ logging.debug(line)
+ if "guest ping test passed" in line:
+ logging.info("found expected guest line in logs")
+ break
--
Anthony PERARD
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |