1919from queue import Queue
2020from typing import Any
2121
22+ from test_driver .errors import MachineError , RequestedAssertionFailed
2223from test_driver .logger import AbstractLogger
2324
2425from .qmp import QMPSession
@@ -129,7 +130,7 @@ def _preprocess_screenshot(screenshot_path: str, negate: bool = False) -> str:
129130 )
130131
131132 if ret .returncode != 0 :
132- raise Exception (
133+ raise MachineError (
133134 f"Image processing failed with exit code { ret .returncode } , stdout: { ret .stdout .decode ()} , stderr: { ret .stderr .decode ()} "
134135 )
135136
@@ -140,7 +141,7 @@ def _perform_ocr_on_screenshot(
140141 screenshot_path : str , model_ids : Iterable [int ]
141142) -> list [str ]:
142143 if shutil .which ("tesseract" ) is None :
143- raise Exception ("OCR requested but enableOCR is false" )
144+ raise MachineError ("OCR requested but enableOCR is false" )
144145
145146 processed_image = _preprocess_screenshot (screenshot_path , negate = False )
146147 processed_negative = _preprocess_screenshot (screenshot_path , negate = True )
@@ -163,7 +164,7 @@ def _perform_ocr_on_screenshot(
163164 capture_output = True ,
164165 )
165166 if ret .returncode != 0 :
166- raise Exception (f"OCR failed with exit code { ret .returncode } " )
167+ raise MachineError (f"OCR failed with exit code { ret .returncode } " )
167168 model_results .append (ret .stdout .decode ("utf-8" ))
168169
169170 return model_results
@@ -180,7 +181,9 @@ def retry(fn: Callable, timeout: int = 900) -> None:
180181 time .sleep (1 )
181182
182183 if not fn (True ):
183- raise Exception (f"action timed out after { timeout } seconds" )
184+ raise RequestedAssertionFailed (
185+ f"action timed out after { timeout } tries with one-second pause in-between"
186+ )
184187
185188
186189class StartCommand :
@@ -409,14 +412,14 @@ def wait_for_unit(
409412 def check_active (_last_try : bool ) -> bool :
410413 state = self .get_unit_property (unit , "ActiveState" , user )
411414 if state == "failed" :
412- raise Exception (f'unit "{ unit } " reached state "{ state } "' )
415+ raise RequestedAssertionFailed (f'unit "{ unit } " reached state "{ state } "' )
413416
414417 if state == "inactive" :
415418 status , jobs = self .systemctl ("list-jobs --full 2>&1" , user )
416419 if "No jobs" in jobs :
417420 info = self .get_unit_info (unit , user )
418421 if info ["ActiveState" ] == state :
419- raise Exception (
422+ raise RequestedAssertionFailed (
420423 f'unit "{ unit } " is inactive and there are no pending jobs'
421424 )
422425
@@ -431,7 +434,7 @@ def check_active(_last_try: bool) -> bool:
431434 def get_unit_info (self , unit : str , user : str | None = None ) -> dict [str , str ]:
432435 status , lines = self .systemctl (f'--no-pager show "{ unit } "' , user )
433436 if status != 0 :
434- raise Exception (
437+ raise RequestedAssertionFailed (
435438 f'retrieving systemctl info for unit "{ unit } "'
436439 + ("" if user is None else f' under user "{ user } "' )
437440 + f" failed with exit code { status } "
@@ -461,7 +464,7 @@ def get_unit_property(
461464 user ,
462465 )
463466 if status != 0 :
464- raise Exception (
467+ raise RequestedAssertionFailed (
465468 f'retrieving systemctl property "{ property } " for unit "{ unit } "'
466469 + ("" if user is None else f' under user "{ user } "' )
467470 + f" failed with exit code { status } "
@@ -509,7 +512,7 @@ def require_unit_state(self, unit: str, require_state: str = "active") -> None:
509512 info = self .get_unit_info (unit )
510513 state = info ["ActiveState" ]
511514 if state != require_state :
512- raise Exception (
515+ raise RequestedAssertionFailed (
513516 f"Expected unit '{ unit } ' to to be in state "
514517 f"'{ require_state } ' but it is in state '{ state } '"
515518 )
@@ -663,7 +666,9 @@ def succeed(self, *commands: str, timeout: int | None = None) -> str:
663666 (status , out ) = self .execute (command , timeout = timeout )
664667 if status != 0 :
665668 self .log (f"output: { out } " )
666- raise Exception (f"command `{ command } ` failed (exit code { status } )" )
669+ raise RequestedAssertionFailed (
670+ f"command `{ command } ` failed (exit code { status } )"
671+ )
667672 output += out
668673 return output
669674
@@ -677,7 +682,9 @@ def fail(self, *commands: str, timeout: int | None = None) -> str:
677682 with self .nested (f"must fail: { command } " ):
678683 (status , out ) = self .execute (command , timeout = timeout )
679684 if status == 0 :
680- raise Exception (f"command `{ command } ` unexpectedly succeeded" )
685+ raise RequestedAssertionFailed (
686+ f"command `{ command } ` unexpectedly succeeded"
687+ )
681688 output += out
682689 return output
683690
@@ -922,7 +929,7 @@ def screenshot(self, filename: str) -> None:
922929 ret = subprocess .run (f"pnmtopng '{ tmp } ' > '{ filename } '" , shell = True )
923930 os .unlink (tmp )
924931 if ret .returncode != 0 :
925- raise Exception ("Cannot convert screenshot" )
932+ raise MachineError ("Cannot convert screenshot" )
926933
927934 def copy_from_host_via_shell (self , source : str , target : str ) -> None :
928935 """Copy a file from the host into the guest by piping it over the
0 commit comments