|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
| 3 | +import pytest |
| 4 | + |
| 5 | +import enum |
| 6 | +import functools |
3 | 7 | import logging |
| 8 | +import re |
| 9 | +import shlex |
4 | 10 | import time |
5 | 11 |
|
6 | 12 | import lib.commands as commands |
|
26 | 32 | from lib.host import Host |
27 | 33 | from lib.pool import Pool |
28 | 34 |
|
| 35 | +QUICKTEST_BIN = "/opt/xensource/debug/quicktest" |
| 36 | + |
| 37 | +QUICKTEST_SR_SUITES = ( |
| 38 | + "cbt,copy,SR tests,Quicktest_vdi,Quicktest_async_calls," |
| 39 | + "Quicktest_vm_import_export,Quicktest_vm_lifecycle,Quicktest_vm_snapshot," |
| 40 | + "Quicktest_vdi_ops_data_integrity,Quicktest_max_vdi_size,Quicktest_static_vdis" |
| 41 | +) |
| 42 | + |
| 43 | +QUICKTEST_COMMON_SUITES = ( |
| 44 | + "Quicktest_example,Quicktest_message,xenstore,event,import_raw_vdi," |
| 45 | + "Quicktest_date,Quicktest_crypt_r,http,unixext,Timer" |
| 46 | +) |
| 47 | + |
| 48 | +class QuicktestScoping(enum.Enum): |
| 49 | + WITH_TAG_PARAM = enum.auto() |
| 50 | + RUN_ONLY_PARAM = enum.auto() |
| 51 | + NO_PARAM = enum.auto() |
| 52 | + |
| 53 | +@functools.lru_cache(maxsize=None) |
| 54 | +def _quicktest_scoping(hostname_or_ip: str) -> QuicktestScoping: |
| 55 | + tags_output = commands.ssh_with_result(hostname_or_ip, f"{QUICKTEST_BIN} -list-tags") |
| 56 | + if tags_output.returncode == 0 and re.search(r"^sr:", tags_output.stdout, re.MULTILINE): |
| 57 | + return QuicktestScoping.WITH_TAG_PARAM |
| 58 | + |
| 59 | + help_output = commands.ssh(hostname_or_ip, f"{QUICKTEST_BIN} -help", check=False) |
| 60 | + if "-run-only" in help_output: |
| 61 | + return QuicktestScoping.RUN_ONLY_PARAM |
| 62 | + |
| 63 | + return QuicktestScoping.NO_PARAM |
| 64 | + |
29 | 65 | class SR: |
30 | 66 | xe_prefix = 'sr' |
31 | 67 |
|
@@ -230,14 +266,29 @@ def create_vdi( |
230 | 266 | vdi_uuid = self.pool.master.xe('vdi-create', args) |
231 | 267 | return VDI(vdi_uuid, sr=self) |
232 | 268 |
|
233 | | - def run_quicktest(self) -> None: |
234 | | - logging.info(f"Run quicktest on SR {self.uuid}") |
| 269 | + def run_quicktest(self, sr_specific: bool = True) -> None: |
| 270 | + scoping = _quicktest_scoping(self.pool.master.hostname_or_ip) |
| 271 | + cmd = f"{QUICKTEST_BIN} -sr {self.uuid}" |
| 272 | + |
| 273 | + if scoping is QuicktestScoping.WITH_TAG_PARAM: |
| 274 | + cmd += " -with-tag sr" if sr_specific else " -without-tag sr" |
| 275 | + elif scoping is QuicktestScoping.RUN_ONLY_PARAM: |
| 276 | + suites = QUICKTEST_SR_SUITES if sr_specific else QUICKTEST_COMMON_SUITES |
| 277 | + cmd += f" -run-only {shlex.quote(suites)}" |
| 278 | + elif not sr_specific: |
| 279 | + # QuicktestScoping.NO_PARAM: no way to select just the common suites, and every |
| 280 | + # per-SR pass on this host is already unfiltered, so this run adds nothing. |
| 281 | + pytest.skip("quicktest has no scoping support on this host; " |
| 282 | + "common suites are already covered by the per-SR runs.") |
| 283 | + |
| 284 | + logging.info(f"Run quicktest on SR {self.uuid}: {cmd}") |
| 285 | + |
235 | 286 | # Always display the output of quicktest, failed or not. |
236 | 287 | # This will duplicate the output in some cases, but it ensures we always have it for failure analysis, |
237 | 288 | # even when quicktest leaves SRs in a state which makes teardown fail (in this case, pytest often doesn't |
238 | 289 | # manage to display the details of the failed command, for a reason unknown - no usable reproducer found) |
239 | 290 | try: |
240 | | - output = self.pool.master.ssh(f'/opt/xensource/debug/quicktest -sr {self.uuid}') |
| 291 | + output = self.pool.master.ssh(cmd) |
241 | 292 | logging.info(f"Quicktest output: {output}") |
242 | 293 | except commands.SSHCommandFailed as e: |
243 | 294 | logging.error(f"Quicktest output: {e.stdout}") |
|
0 commit comments