[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 2/4] iotests: add VerboseProcessError
From: |
John Snow |
Subject: |
[PATCH 2/4] iotests: add VerboseProcessError |
Date: |
Tue, 15 Feb 2022 17:08:51 -0500 |
This adds an Exception that extends the garden variety
subprocess.CalledProcessError. When this exception is raised, it will
still be caught when selecting for the stdlib variant.
The difference is that the str() method of this Exception also adds the
stdout/stderr logs. In effect, if this exception goes unhandled, Python
will print the output in a nice, highlighted box to the terminal so that
it's easy to spot.
This should save some headache from having to re-run test suites with
debugging enabled if we augment the exceptions we print more information
in the default case.
Signed-off-by: John Snow <jsnow@redhat.com>
---
tests/qemu-iotests/iotests.py | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 6ba65eb1ffe..7df393df2c3 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -30,6 +30,7 @@
import struct
import subprocess
import sys
+import textwrap
import time
from typing import (Any, Callable, Dict, Iterable, Iterator,
List, Optional, Sequence, TextIO, Tuple, Type, TypeVar)
@@ -39,6 +40,7 @@
from qemu.machine import qtest
from qemu.qmp import QMPMessage
+from qemu.utils import enboxify
# Use this logger for logging messages directly from the iotests module
logger = logging.getLogger('qemu.iotests')
@@ -117,6 +119,38 @@
sample_img_dir = os.environ['SAMPLE_IMG_DIR']
+class VerboseProcessError(subprocess.CalledProcessError):
+ """
+ The same as CalledProcessError, but more verbose.
+
+ This is useful for debugging failed calls during test executions.
+ The return code, signal (if any), and terminal output will be displayed
+ on unhandled exceptions.
+ """
+ def summary(self) -> str:
+ return super().__str__()
+
+ def __str__(self) -> str:
+ lmargin = ' '
+ width = shutil.get_terminal_size()[0] - len(lmargin)
+ sections = []
+
+ if self.stdout:
+ name = 'output' if self.stderr is None else 'stdout'
+ sections.append(enboxify(self.stdout, width, name))
+ else:
+ sections.append(f"{name}: N/A")
+
+ if self.stderr:
+ sections.append(enboxify(self.stderr, width, 'stderr'))
+ elif self.stderr is not None:
+ sections.append("stderr: N/A")
+
+ return os.linesep.join((
+ self.summary(),
+ textwrap.indent(os.linesep.join(sections), prefix=lmargin),
+ ))
+
@contextmanager
def change_log_level(
logger_name: str, level: int = logging.CRITICAL) -> Iterator[None]:
--
2.34.1
- Re: [PATCH 3/4] iotests: Remove explicit checks for qemu_img() == 0, (continued)
[PATCH 4/4] iotests: make qemu_img raise on non-zero rc by default, John Snow, 2022/02/15
[PATCH 2/4] iotests: add VerboseProcessError,
John Snow <=