Skip to content

Commit 22ef392

Browse files
committed
Add support for --nest=... --hosts=cache://...
Special care taken for making sure a created VM is destroyed if setup_host fails further down the line. Signed-off-by: Yann Dirson <[email protected]>
1 parent 625e072 commit 22ef392

File tree

1 file changed

+61
-2
lines changed

1 file changed

+61
-2
lines changed

conftest.py

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import itertools
22
import git
33
import logging
4+
import os
45
import pytest
56
import tempfile
67

@@ -9,6 +10,7 @@
910

1011
import lib.config as global_config
1112

13+
from lib import pxe
1214
from lib.common import callable_marker, shortened_nodeid, prefix_object_name
1315
from lib.common import wait_for, vm_image, is_uuid
1416
from lib.common import setup_formatted_and_mounted_disk, teardown_formatted_and_mounted_disk
@@ -33,6 +35,12 @@
3335
# pytest hooks
3436

3537
def pytest_addoption(parser):
38+
parser.addoption(
39+
"--nest",
40+
action="store",
41+
default=None,
42+
help="XCP-ng or XS master of pool to use for nesting hosts under test",
43+
)
3644
parser.addoption(
3745
"--hosts",
3846
action="append",
@@ -142,20 +150,71 @@ def pytest_runtest_makereport(item, call):
142150

143151
@pytest.fixture(scope='session')
144152
def hosts(pytestconfig):
145-
def setup_host(hostname_or_ip):
153+
nested_list = []
154+
155+
def setup_host(hostname_or_ip, *, config=None):
156+
host_vm = None
157+
if hostname_or_ip.startswith("cache://"):
158+
if config is None:
159+
raise RuntimeError("setup_host: a cache:// host requires --nest")
160+
nest_hostname = config.getoption("nest")
161+
if not nest_hostname:
162+
pytest.fail("--hosts=cache://... requires --nest parameter")
163+
nest = Pool(nest_hostname).master
164+
165+
protocol, rest = hostname_or_ip.split(":", 1)
166+
host_vm = nest.import_vm(f"clone:{rest}", nest.main_sr_uuid(),
167+
use_cache=True)
168+
nested_list.append(host_vm)
169+
170+
vif = host_vm.vifs()[0]
171+
mac_address = vif.param_get('MAC')
172+
logging.info("Nested host has MAC %s", mac_address)
173+
174+
host_vm.start()
175+
wait_for(host_vm.is_running, "Wait for nested host VM running")
176+
177+
# catch host-vm IP address
178+
wait_for(lambda: pxe.arp_addresses_for(mac_address),
179+
"Wait for DHCP server to see nested host in ARP tables",
180+
timeout_secs=10 * 60)
181+
ips = pxe.arp_addresses_for(mac_address)
182+
logging.info("Nested host has IPs %s", ips)
183+
assert len(ips) == 1
184+
host_vm.ip = ips[0]
185+
186+
wait_for(lambda: not os.system(f"nc -zw5 {host_vm.ip} 22"),
187+
"Wait for ssh up on nested host", retry_delay_secs=5)
188+
189+
hostname_or_ip = host_vm.ip
190+
146191
pool = Pool(hostname_or_ip)
147192
h = pool.master
148193
return h
149194

195+
def cleanup_hosts():
196+
for vm in nested_list:
197+
logging.info("Destroying nested host VM %s", vm.uuid)
198+
vm.destroy(verify=True)
199+
150200
# a list of master hosts, each from a different pool
151201
hosts_args = pytestconfig.getoption("hosts")
152202
hosts_split = [hostlist.split(',') for hostlist in hosts_args]
153203
hostname_list = list(itertools.chain(*hosts_split))
154-
host_list = [setup_host(hostname_or_ip) for hostname_or_ip in hostname_list]
204+
205+
try:
206+
host_list = [setup_host(hostname_or_ip, config=pytestconfig)
207+
for hostname_or_ip in hostname_list]
208+
except Exception:
209+
cleanup_hosts()
210+
raise
211+
155212
if not host_list:
156213
pytest.fail("This test requires at least one --hosts parameter")
157214
yield host_list
158215

216+
cleanup_hosts()
217+
159218
@pytest.fixture(scope='session')
160219
def registered_xo_cli():
161220
# The fixture is not responsible for establishing the connection.

0 commit comments

Comments
 (0)