Skip to content

Commit 9c68191

Browse files
authored
Merge pull request #527 from xcp-ng/install/fix
Fix auto-install tests
2 parents e273f0a + b003a88 commit 9c68191

3 files changed

Lines changed: 57 additions & 41 deletions

File tree

lib/installer.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ def _defn_to_xml_et(defn: dict[str, Any], *, parent: ET.Element | None = None) -
8383

8484
def poweroff(ip: str) -> None:
8585
try:
86-
ssh(ip, "poweroff")
86+
# disable multiplexing to get proper info in SSHCommandFailed
87+
ssh(ip, "poweroff", multiplexing=False)
8788
except SSHCommandFailed as e:
8889
# ignore connection closed by reboot
8990
if e.returncode == 255 and "closed by remote host" in e.stdout:

tests/install/conftest.py

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from data import ARP_SERVER, ISO_IMAGES, ISO_IMAGES_BASE, ISO_IMAGES_CACHE, TEST_SSH_PUBKEY, TOOLS
1212
from lib import installer, pxe
1313
from lib.commands import local_cmd
14-
from lib.common import Defer, callable_marker, url_download, wait_for
14+
from lib.common import callable_marker, url_download, wait_for
1515
from lib.installer import AnswerFile
1616

1717
from typing import TYPE_CHECKING, Any, Generator, Sequence
@@ -103,9 +103,10 @@ def installer_iso(request: pytest.FixtureRequest) -> dict[str, str | bool]:
103103
)
104104

105105
@pytest.fixture(scope='function')
106-
def system_disks_names(request: pytest.FixtureRequest) -> Generator[str, None, None]:
106+
def system_disks_names(request: pytest.FixtureRequest) -> tuple[str, ...]:
107107
firmware = request.getfixturevalue("firmware")
108-
yield {"uefi": "nvme0n1", "bios": "sda"}[firmware]
108+
main_disk = {"uefi": "nvme0n1", "bios": "sda"}[firmware]
109+
return (main_disk,)
109110

110111
# Remasters the ISO sepecified by `installer_iso` mark, with:
111112
# - network and ssh support activated, and .ssh/authorized_key so tests can
@@ -154,8 +155,9 @@ def remastered_iso(installer_iso: dict[str, str | bool], answerfile: AnswerFile
154155
set -ex
155156
INSTALLIMG="$1"
156157
157-
mkdir -p "$INSTALLIMG/root/.ssh"
158+
install -d -m 750 "$INSTALLIMG/root/.ssh"
158159
echo "{TEST_SSH_PUBKEY}" > "$INSTALLIMG/root/.ssh/authorized_keys"
160+
chmod 600 "$INSTALLIMG/root/.ssh/authorized_keys"
159161
160162
test ! -e "{answerfile_xml}" ||
161163
cp "{answerfile_xml}" "$INSTALLIMG/root/answerfile.xml"
@@ -271,8 +273,7 @@ def remastered_iso(installer_iso: dict[str, str | bool], answerfile: AnswerFile
271273
yield remastered_iso
272274

273275
@pytest.fixture(scope='function')
274-
def vm_booted_with_installer(host: Host, create_vms: list[VM], remastered_iso: str, defer: Defer) \
275-
-> Generator[VM, None, None]:
276+
def vm_booted_with_installer(host: Host, create_vms: list[VM], remastered_iso: str) -> Generator[VM, None, None]:
276277
host_vm, = create_vms # one single VM
277278
iso = remastered_iso
278279

@@ -281,39 +282,52 @@ def vm_booted_with_installer(host: Host, create_vms: list[VM], remastered_iso: s
281282
assert mac_address is not None
282283
logging.info("Host VM has MAC %s", mac_address)
283284

284-
remote_iso = host.pool.push_iso(iso)
285-
host_vm.insert_cd(os.path.basename(remote_iso))
286-
defer(lambda: host.pool.remove_iso(remote_iso))
287-
288-
host_vm.start()
289-
defer(lambda: host_vm.shutdown(force=True))
290-
wait_for(host_vm.is_running, "Wait for host VM running")
291-
292-
# catch host-vm IP address
293-
wait_for(lambda: pxe.arp_addresses_for(mac_address),
294-
"Wait for DHCP server to see Host VM in ARP tables",
295-
timeout_secs=10 * 60)
296-
ips = pxe.arp_addresses_for(mac_address)
297-
logging.info("Host VM has IPs %s", ips)
298-
assert len(ips) == 1
299-
host_vm.ip = ips[0]
300-
ip = host_vm.ip
301-
assert ip is not None
302-
303-
# host may not be up if ARP cache was filled
304-
wait_for(lambda: local_cmd(["ping", "-c1", ip], check=False),
305-
"Wait for host up", timeout_secs=10 * 60, retry_delay_secs=10)
306-
wait_for(lambda: local_cmd(["nc", "-zw5", ip, "22"], check=False),
307-
"Wait for ssh up on host", timeout_secs=10 * 60, retry_delay_secs=5)
308-
309-
yield host_vm
310-
311-
logging.info("Shutting down Host VM")
312-
assert host_vm.ip is not None
313-
installer.poweroff(host_vm.ip)
314-
wait_for(host_vm.is_halted, "Wait for host VM halted")
315-
316-
host_vm.eject_cd()
285+
remote_iso = None
286+
try:
287+
remote_iso = host.pool.push_iso(iso)
288+
host_vm.insert_cd(os.path.basename(remote_iso))
289+
290+
try:
291+
host_vm.start()
292+
wait_for(host_vm.is_running, "Wait for host VM running")
293+
294+
# catch host-vm IP address
295+
wait_for(lambda: pxe.arp_addresses_for(mac_address),
296+
"Wait for DHCP server to see Host VM in ARP tables",
297+
timeout_secs=10 * 60)
298+
ips = pxe.arp_addresses_for(mac_address)
299+
logging.info("Host VM has IPs %s", ips)
300+
assert len(ips) == 1
301+
host_vm.ip = ips[0]
302+
ip = host_vm.ip
303+
assert ip is not None
304+
305+
# host may not be up if ARP cache was filled
306+
wait_for(lambda: local_cmd(["ping", "-c1", ip], check=False),
307+
"Wait for host up", timeout_secs=10 * 60, retry_delay_secs=10)
308+
wait_for(lambda: local_cmd(["nc", "-zw5", ip, "22"], check=False),
309+
"Wait for ssh up on host", timeout_secs=10 * 60, retry_delay_secs=5)
310+
311+
yield host_vm
312+
313+
logging.info("Shutting down Host VM")
314+
assert host_vm.ip is not None
315+
installer.poweroff(host_vm.ip)
316+
wait_for(host_vm.is_halted, "Wait for host VM halted")
317+
318+
except Exception as e:
319+
logging.critical("caught exception %s", e)
320+
host_vm.shutdown(force=True)
321+
raise
322+
except KeyboardInterrupt:
323+
logging.warning("keyboard interrupt")
324+
host_vm.shutdown(force=True)
325+
raise
326+
327+
host_vm.eject_cd()
328+
finally:
329+
if remote_iso:
330+
host.pool.remove_iso(remote_iso)
317331

318332
@pytest.fixture(scope='function')
319333
def xcpng_chained(request: pytest.FixtureRequest) -> None:

tests/install/test.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,8 @@ def _test_firstboot(self, create_vms: list[VM], mode: str, *,
273273
# use "poweroff" because "reboot" would cause ARP and
274274
# SSH to be checked before host is down, and require
275275
# ssh retries
276-
pool.master.ssh("poweroff")
276+
# disable multiplexing to get proper info in SSHCommandFailed
277+
pool.master.ssh("poweroff", multiplexing=False)
277278
except commands.SSHCommandFailed as e:
278279
# ignore connection closed by reboot
279280
if e.returncode == 255 and "closed by remote host" in e.stdout:

0 commit comments

Comments
 (0)