aboutsummaryrefslogtreecommitdiff
path: root/tests/functional/qemu_test
diff options
context:
space:
mode:
Diffstat (limited to 'tests/functional/qemu_test')
-rw-r--r--tests/functional/qemu_test/__init__.py4
-rw-r--r--tests/functional/qemu_test/asset.py1
-rw-r--r--tests/functional/qemu_test/decorators.py18
-rw-r--r--tests/functional/qemu_test/gdb.py86
4 files changed, 107 insertions, 2 deletions
diff --git a/tests/functional/qemu_test/__init__.py b/tests/functional/qemu_test/__init__.py
index 6e666a0..3201935 100644
--- a/tests/functional/qemu_test/__init__.py
+++ b/tests/functional/qemu_test/__init__.py
@@ -15,6 +15,8 @@ from .testcase import QemuBaseTest, QemuUserTest, QemuSystemTest
from .linuxkernel import LinuxKernelTest
from .decorators import skipIfMissingCommands, skipIfNotMachine, \
skipFlakyTest, skipUntrustedTest, skipBigDataTest, skipSlowTest, \
- skipIfMissingImports, skipIfOperatingSystem, skipLockedMemoryTest
+ skipIfMissingImports, skipIfOperatingSystem, skipLockedMemoryTest, \
+ skipIfMissingEnv
from .archive import archive_extract
from .uncompress import uncompress
+from .gdb import GDB
diff --git a/tests/functional/qemu_test/asset.py b/tests/functional/qemu_test/asset.py
index 2971a98..f666125 100644
--- a/tests/functional/qemu_test/asset.py
+++ b/tests/functional/qemu_test/asset.py
@@ -225,7 +225,6 @@ class Asset:
log.addHandler(handler)
for name, asset in vars(test.__class__).items():
if name.startswith("ASSET_") and type(asset) == Asset:
- log.info("Attempting to cache '%s'" % asset)
try:
asset.fetch()
except AssetError as e:
diff --git a/tests/functional/qemu_test/decorators.py b/tests/functional/qemu_test/decorators.py
index c0d1567..b239295 100644
--- a/tests/functional/qemu_test/decorators.py
+++ b/tests/functional/qemu_test/decorators.py
@@ -11,6 +11,24 @@ from unittest import skipIf, skipUnless
from .cmd import which
'''
+Decorator to skip execution of a test if the provided
+environment variables are not set.
+Example:
+
+ @skipIfMissingEnv("QEMU_ENV_VAR0", "QEMU_ENV_VAR1")
+'''
+def skipIfMissingEnv(*vars_):
+ missing_vars = []
+ for var in vars_:
+ if os.getenv(var) == None:
+ missing_vars.append(var)
+
+ has_vars = True if len(missing_vars) == 0 else False
+
+ return skipUnless(has_vars, f"Missing env var(s): {', '.join(missing_vars)}")
+
+'''
+
Decorator to skip execution of a test if the list
of command binaries is not available in $PATH.
Example:
diff --git a/tests/functional/qemu_test/gdb.py b/tests/functional/qemu_test/gdb.py
new file mode 100644
index 0000000..558d476
--- /dev/null
+++ b/tests/functional/qemu_test/gdb.py
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# A simple interface module built around pygdbmi for handling GDB commands.
+#
+# Copyright (c) 2025 Linaro Limited
+#
+# Author:
+# Gustavo Romero <gustavo.romero@linaro.org>
+#
+
+import re
+
+
+class GDB:
+ """Provides methods to run and capture GDB command output."""
+
+
+ def __init__(self, gdb_path, echo=True, suffix='# ', prompt="$ "):
+ from pygdbmi.gdbcontroller import GdbController
+ from pygdbmi.constants import GdbTimeoutError
+ type(self).TimeoutError = GdbTimeoutError
+
+ gdb_cmd = [gdb_path, "-q", "--interpreter=mi2"]
+ self.gdbmi = GdbController(gdb_cmd)
+ self.echo = echo
+ self.suffix = suffix
+ self.prompt = prompt
+ self.response = None
+ self.cmd_output = None
+
+
+ def get_payload(self, response, kind):
+ output = []
+ for o in response:
+ # Unpack payloads of the same type.
+ _type, _, payload, *_ = o.values()
+ if _type == kind:
+ output += [payload]
+
+ # Some output lines do not end with \n but begin with it,
+ # so remove the leading \n and merge them with the next line
+ # that ends with \n.
+ lines = [line.lstrip('\n') for line in output]
+ lines = "".join(lines)
+ lines = lines.splitlines(keepends=True)
+
+ return lines
+
+
+ def cli(self, cmd, timeout=32.0):
+ self.response = self.gdbmi.write(cmd, timeout_sec=timeout)
+ self.cmd_output = self.get_payload(self.response, kind="console")
+ if self.echo:
+ print(self.suffix + self.prompt + cmd)
+
+ if len(self.cmd_output) > 0:
+ cmd_output = self.suffix.join(self.cmd_output)
+ print(self.suffix + cmd_output, end="")
+
+ return self
+
+
+ def get_addr(self):
+ address_pattern = r"0x[0-9A-Fa-f]+"
+ cmd_output = "".join(self.cmd_output) # Concat output lines.
+
+ match = re.search(address_pattern, cmd_output)
+
+ return int(match[0], 16) if match else None
+
+
+ def get_log(self):
+ r = self.get_payload(self.response, kind="log")
+ r = "".join(r)
+
+ return r
+
+
+ def get_console(self):
+ r = "".join(self.cmd_output)
+
+ return r
+
+
+ def exit(self):
+ self.gdbmi.exit()