aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/Makefile4
-rw-r--r--tools/testing/selftests/devices/Makefile4
-rw-r--r--tools/testing/selftests/devices/error_logs/Makefile3
-rwxr-xr-xtools/testing/selftests/devices/error_logs/test_device_error_logs.py85
-rw-r--r--tools/testing/selftests/devices/probe/Makefile4
-rw-r--r--tools/testing/selftests/devices/probe/boards/Dell Inc.,XPS 13 9300.yaml (renamed from tools/testing/selftests/devices/boards/Dell Inc.,XPS 13 9300.yaml)0
-rw-r--r--tools/testing/selftests/devices/probe/boards/google,spherion.yaml (renamed from tools/testing/selftests/devices/boards/google,spherion.yaml)4
-rwxr-xr-xtools/testing/selftests/devices/probe/test_discoverable_devices.py (renamed from tools/testing/selftests/devices/test_discoverable_devices.py)44
-rw-r--r--tools/testing/selftests/kselftest/ksft.py (renamed from tools/testing/selftests/devices/ksft.py)0
9 files changed, 141 insertions, 7 deletions
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 06eed383fdc0..bc8fe9e8f7f2 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -13,7 +13,8 @@ TARGETS += core
TARGETS += cpufreq
TARGETS += cpu-hotplug
TARGETS += damon
-TARGETS += devices
+TARGETS += devices/error_logs
+TARGETS += devices/probe
TARGETS += dmabuf-heaps
TARGETS += drivers/dma-buf
TARGETS += drivers/s390x/uvdevice
@@ -252,6 +253,7 @@ ifdef INSTALL_PATH
install -m 744 kselftest/runner.sh $(INSTALL_PATH)/kselftest/
install -m 744 kselftest/prefix.pl $(INSTALL_PATH)/kselftest/
install -m 744 kselftest/ktap_helpers.sh $(INSTALL_PATH)/kselftest/
+ install -m 744 kselftest/ksft.py $(INSTALL_PATH)/kselftest/
install -m 744 run_kselftest.sh $(INSTALL_PATH)/
rm -f $(TEST_LIST)
@ret=1; \
diff --git a/tools/testing/selftests/devices/Makefile b/tools/testing/selftests/devices/Makefile
deleted file mode 100644
index ca29249b30c3..000000000000
--- a/tools/testing/selftests/devices/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-TEST_PROGS := test_discoverable_devices.py
-TEST_FILES := boards ksft.py
-
-include ../lib.mk
diff --git a/tools/testing/selftests/devices/error_logs/Makefile b/tools/testing/selftests/devices/error_logs/Makefile
new file mode 100644
index 000000000000..d546c3fb0a7f
--- /dev/null
+++ b/tools/testing/selftests/devices/error_logs/Makefile
@@ -0,0 +1,3 @@
+TEST_PROGS := test_device_error_logs.py
+
+include ../../lib.mk
diff --git a/tools/testing/selftests/devices/error_logs/test_device_error_logs.py b/tools/testing/selftests/devices/error_logs/test_device_error_logs.py
new file mode 100755
index 000000000000..3dd56c8ec92c
--- /dev/null
+++ b/tools/testing/selftests/devices/error_logs/test_device_error_logs.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (c) 2024 Collabora Ltd
+#
+# This test checks for the presence of error (or more critical) log messages
+# coming from devices in the kernel log.
+#
+# One failed test case is reported for each device that has outputted error
+# logs. Devices with no errors do not produce a passing test case to avoid
+# polluting the results, therefore a successful run will list 0 tests run.
+#
+
+import glob
+import os
+import re
+import sys
+
+# Allow ksft module to be imported from different directory
+this_dir = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(this_dir, "../../kselftest/"))
+
+import ksft
+
+kmsg = "/dev/kmsg"
+
+RE_log = re.compile(
+ r"(?P<prefix>[0-9]+),(?P<sequence>[0-9]+),(?P<timestamp>[0-9]+),(?P<flag>[^;]*)(,[^;]*)*;(?P<message>.*)"
+)
+RE_tag = re.compile(r" (?P<key>[^=]+)=(?P<value>.*)")
+
+PREFIX_ERROR = 3
+
+logs = []
+error_log_per_device = {}
+
+
+def parse_kmsg():
+ current_log = {}
+
+ with open(kmsg) as f:
+ os.set_blocking(f.fileno(), False)
+
+ for line in f:
+ tag_line = RE_tag.match(line)
+ log_line = RE_log.match(line)
+
+ if log_line:
+ if current_log:
+ logs.append(current_log) # Save last log
+
+ current_log = {
+ "prefix": int(log_line.group("prefix")),
+ "sequence": int(log_line.group("sequence")),
+ "timestamp": int(log_line.group("timestamp")),
+ "flag": log_line.group("flag"),
+ "message": log_line.group("message"),
+ }
+ elif tag_line:
+ current_log[tag_line.group("key")] = tag_line.group("value")
+
+
+def generate_per_device_error_log():
+ for log in logs:
+ if log.get("DEVICE") and log["prefix"] <= PREFIX_ERROR:
+ if not error_log_per_device.get(log["DEVICE"]):
+ error_log_per_device[log["DEVICE"]] = []
+ error_log_per_device[log["DEVICE"]].append(log)
+
+
+parse_kmsg()
+
+generate_per_device_error_log()
+num_tests = len(error_log_per_device)
+
+ksft.print_header()
+ksft.set_plan(num_tests)
+
+for device in error_log_per_device:
+ for log in error_log_per_device[device]:
+ ksft.print_msg(log["message"])
+ ksft.test_result_fail(device)
+if num_tests == 0:
+ ksft.print_msg("No device error logs found")
+ksft.finished()
diff --git a/tools/testing/selftests/devices/probe/Makefile b/tools/testing/selftests/devices/probe/Makefile
new file mode 100644
index 000000000000..f630108c3fdf
--- /dev/null
+++ b/tools/testing/selftests/devices/probe/Makefile
@@ -0,0 +1,4 @@
+TEST_PROGS := test_discoverable_devices.py
+TEST_FILES := boards
+
+include ../../lib.mk
diff --git a/tools/testing/selftests/devices/boards/Dell Inc.,XPS 13 9300.yaml b/tools/testing/selftests/devices/probe/boards/Dell Inc.,XPS 13 9300.yaml
index ff932eb19f0b..ff932eb19f0b 100644
--- a/tools/testing/selftests/devices/boards/Dell Inc.,XPS 13 9300.yaml
+++ b/tools/testing/selftests/devices/probe/boards/Dell Inc.,XPS 13 9300.yaml
diff --git a/tools/testing/selftests/devices/boards/google,spherion.yaml b/tools/testing/selftests/devices/probe/boards/google,spherion.yaml
index 17157ecd8c14..3ea843324797 100644
--- a/tools/testing/selftests/devices/boards/google,spherion.yaml
+++ b/tools/testing/selftests/devices/probe/boards/google,spherion.yaml
@@ -11,6 +11,10 @@
# this, several optional keys can be used:
# - dt-mmio: identify the MMIO address of the controller as defined in the
# Devicetree.
+# - of-fullname-regex: regular expression to match against the OF_FULLNAME
+# property. Useful when the controller's address is not unique across other
+# sibling controllers. In this case, dt-mmio can't be used, and this property
+# allows the matching to include parent nodes as well to make it unique.
# - usb-version: for USB controllers to differentiate between USB3 and USB2
# buses sharing the same controller.
# - acpi-uid: _UID property of the controller as supplied by the ACPI. Useful to
diff --git a/tools/testing/selftests/devices/test_discoverable_devices.py b/tools/testing/selftests/devices/probe/test_discoverable_devices.py
index fbae8deb593d..d94a74b8a054 100755
--- a/tools/testing/selftests/devices/test_discoverable_devices.py
+++ b/tools/testing/selftests/devices/probe/test_discoverable_devices.py
@@ -14,13 +14,19 @@
# the description and examples of the file structure and vocabulary.
#
+import argparse
import glob
-import ksft
import os
import re
import sys
import yaml
+# Allow ksft module to be imported from different directory
+this_dir = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(this_dir, "../../kselftest/"))
+
+import ksft
+
pci_controllers = []
usb_controllers = []
@@ -63,6 +69,22 @@ def get_dt_mmio(sysfs_dev_dir):
sysfs_dev_dir = os.path.dirname(sysfs_dev_dir)
+def get_of_fullname(sysfs_dev_dir):
+ re_of_fullname = re.compile("OF_FULLNAME=(.*)")
+ of_full_name = None
+
+ # PCI controllers' sysfs don't have an of_node, so have to read it from the
+ # parent
+ while not of_full_name:
+ try:
+ with open(os.path.join(sysfs_dev_dir, "uevent")) as f:
+ of_fullname = re_of_fullname.search(f.read()).group(1)
+ return of_fullname
+ except:
+ pass
+ sysfs_dev_dir = os.path.dirname(sysfs_dev_dir)
+
+
def get_acpi_uid(sysfs_dev_dir):
with open(os.path.join(sysfs_dev_dir, "firmware_node", "uid")) as f:
return f.read()
@@ -96,6 +118,11 @@ def find_controller_in_sysfs(controller, parent_sysfs=None):
if str(controller["dt-mmio"]) != get_dt_mmio(c):
continue
+ if controller.get("of-fullname-regex"):
+ re_of_fullname = re.compile(str(controller["of-fullname-regex"]))
+ if not re_of_fullname.match(get_of_fullname(c)):
+ continue
+
if controller.get("usb-version"):
if controller["usb-version"] != get_usb_version(c):
continue
@@ -194,6 +221,9 @@ def generate_pathname(device):
if device.get("dt-mmio"):
pathname += "@" + str(device["dt-mmio"])
+ if device.get("of-fullname-regex"):
+ pathname += "-" + str(device["of-fullname-regex"])
+
if device.get("name"):
pathname = pathname + "/" + device["name"]
@@ -296,14 +326,24 @@ def run_test(yaml_file):
parse_device_tree_node(device_tree)
+parser = argparse.ArgumentParser()
+parser.add_argument(
+ "--boards-dir", default="boards", help="Directory containing the board YAML files"
+)
+args = parser.parse_args()
+
find_pci_controller_dirs()
find_usb_controller_dirs()
ksft.print_header()
+if not os.path.exists(args.boards_dir):
+ ksft.print_msg(f"Boards directory '{args.boards_dir}' doesn't exist")
+ ksft.exit_fail()
+
board_file = ""
for board_filename in get_board_filenames():
- full_board_filename = os.path.join("boards", board_filename + ".yaml")
+ full_board_filename = os.path.join(args.boards_dir, board_filename + ".yaml")
if os.path.exists(full_board_filename):
board_file = full_board_filename
diff --git a/tools/testing/selftests/devices/ksft.py b/tools/testing/selftests/kselftest/ksft.py
index cd89fb2bc10e..cd89fb2bc10e 100644
--- a/tools/testing/selftests/devices/ksft.py
+++ b/tools/testing/selftests/kselftest/ksft.py