#!/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[0-9]+),(?P[0-9]+),(?P[0-9]+),(?P[^;]*)(,[^;]*)*;(?P.*)" ) RE_tag = re.compile(r" (?P[^=]+)=(?P.*)") 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()