|
8 | 8 | import tempfile
|
9 | 9 |
|
10 | 10 | from packaging import version
|
11 |
| -from typing import Dict, Generator |
| 11 | +from typing import Dict, Generator, Iterable |
12 | 12 |
|
13 | 13 | import lib.config as global_config
|
14 | 14 |
|
15 | 15 | from lib import pxe
|
16 |
| -from lib.common import DiskDevName |
| 16 | +from lib.common import DiskDevName, HostAddress |
17 | 17 | from lib.common import callable_marker, shortened_nodeid, prefix_object_name
|
18 | 18 | from lib.common import wait_for, vm_image, is_uuid
|
19 | 19 | from lib.common import setup_formatted_and_mounted_disk, teardown_formatted_and_mounted_disk
|
@@ -75,6 +75,14 @@ def pytest_addoption(parser):
|
75 | 75 | default=20,
|
76 | 76 | help="Max lines to output in a ssh log (0 if no limit)"
|
77 | 77 | )
|
| 78 | + parser.addoption( |
| 79 | + "--disk", |
| 80 | + action="append", |
| 81 | + default=[], |
| 82 | + # FIXME: do we want explicit --disk=* to authorize all? |
| 83 | + help="HOST:DISK to authorize for use by tests. " |
| 84 | + "No mention of a given host authorizes use of all its disks." |
| 85 | + ) |
78 | 86 | parser.addoption(
|
79 | 87 | "--sr-disk",
|
80 | 88 | action="append",
|
@@ -219,6 +227,13 @@ def cleanup_hosts():
|
219 | 227 |
|
220 | 228 | cleanup_hosts()
|
221 | 229 |
|
| 230 | +@pytest.fixture(scope='session') |
| 231 | +def pools_hosts_by_name_or_ip(hosts: list[Host]) -> Generator[dict[HostAddress, Host], None, None]: |
| 232 | + yield {host.hostname_or_ip: host |
| 233 | + for pool_master in hosts |
| 234 | + for host in pool_master.pool.hosts |
| 235 | + } |
| 236 | + |
222 | 237 | @pytest.fixture(scope='session')
|
223 | 238 | def registered_xo_cli():
|
224 | 239 | # The fixture is not responsible for establishing the connection.
|
@@ -331,9 +346,29 @@ def local_sr_on_hostB1(hostB1):
|
331 | 346 | yield sr
|
332 | 347 |
|
333 | 348 | @pytest.fixture(scope='session')
|
334 |
| -def disks(hosts: list[Host]) -> Generator[dict[Host, list[DiskDevName]], None, None]: |
335 |
| - ret = {host: host.disks() |
336 |
| - for pool_master in hosts |
| 349 | +def disks(pytestconfig, pools_hosts_by_name_or_ip: dict[HostAddress, Host] |
| 350 | + ) -> Generator[dict[Host, list[DiskDevName]], None, None]: |
| 351 | + def _parse_disk_option(option_text: str) -> tuple[HostAddress, DiskDevName]: |
| 352 | + parsed = tuple(option_text.split(sep=":", maxsplit=1)) |
| 353 | + assert len(parsed) == 2, f"--disk option {option_text!r} is not <host>:<disk>" |
| 354 | + return parsed |
| 355 | + def _cli_disks_per_host(options_list: Iterable[tuple[HostAddress, DiskDevName]] |
| 356 | + ) -> dict[Host, list[DiskDevName]]: |
| 357 | + ret: dict[Host, list[DiskDevName]] = {host: [] |
| 358 | + for pool_master in pools_hosts_by_name_or_ip.values() |
| 359 | + for host in pool_master.pool.hosts |
| 360 | + } |
| 361 | + for (hostname, disk) in options_list: |
| 362 | + host = pools_hosts_by_name_or_ip[hostname] |
| 363 | + assert host in ret |
| 364 | + ret[host].append(disk) |
| 365 | + return ret |
| 366 | + |
| 367 | + cli_disks = _cli_disks_per_host(_parse_disk_option(option_text) |
| 368 | + for option_text in pytestconfig.getoption("disk")) |
| 369 | + ret = {host: [disk for disk in host.disks() |
| 370 | + if not cli_disks[host] or disk in cli_disks[host]] |
| 371 | + for pool_master in pools_hosts_by_name_or_ip.values() |
337 | 372 | for host in pool_master.pool.hosts
|
338 | 373 | }
|
339 | 374 | logging.debug("disks collected: %s", {host.hostname_or_ip: value for host, value in ret.items()})
|
|
0 commit comments