Skip to content

Commit dbd5832

Browse files
committed
Capture full kernel log on pre-req failure
1 parent 1e5ca7d commit dbd5832

File tree

3 files changed

+91
-1
lines changed

3 files changed

+91
-1
lines changed

src/amd_debug/kernel.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ def match_pattern(self, _pattern) -> str:
168168
"""Find lines that match a pattern"""
169169
return ""
170170

171+
def get_full_log(self) -> str:
172+
"""Get the full log as a string"""
173+
return ""
174+
171175

172176
class InputFile(KernelLogger):
173177
"""Class for input file parsing"""
@@ -183,6 +187,10 @@ def process_callback(self, callback, priority=None):
183187
for entry in self.buffer.split("\n"):
184188
callback(entry, priority)
185189

190+
def get_full_log(self):
191+
"""Get the full log as a string"""
192+
return self.buffer
193+
186194

187195
class DmesgLogger(KernelLogger):
188196
"""Class for dmesg logging"""
@@ -256,6 +264,10 @@ def capture_header(self):
256264
"""Capture the header of the log"""
257265
return self.buffer.split("\n")[0]
258266

267+
def get_full_log(self):
268+
"""Get the full log as a string"""
269+
return self.buffer
270+
259271

260272
class CySystemdLogger(KernelLogger):
261273
"""Class for logging using systemd journal using cython"""
@@ -319,6 +331,11 @@ def match_pattern(self, pattern):
319331
return entry["MESSAGE"]
320332
return None
321333

334+
def get_full_log(self):
335+
"""Get the full log as a string"""
336+
self.seek()
337+
return "\n".join([entry["MESSAGE"] for entry in self.journal])
338+
322339

323340
class SystemdLogger(KernelLogger):
324341
"""Class for logging using systemd journal"""
@@ -363,6 +380,11 @@ def match_pattern(self, pattern):
363380
return entry["MESSAGE"]
364381
return ""
365382

383+
def get_full_log(self):
384+
"""Get the full log as a string"""
385+
self.seek()
386+
return "\n".join([entry["MESSAGE"] for entry in self.journal])
387+
366388

367389
def get_kernel_log(input_file=None) -> KernelLogger:
368390
"""Get the kernel log provider"""

src/amd_debug/prerequisites.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,6 +1415,7 @@ def run(self):
14151415
result = False
14161416
if not result:
14171417
self.db.record_prereq(Headers.BrokenPrerequisites, "🚫")
1418+
self.db.record_debug(self.kernel_log.get_full_log())
14181419
self.db.sync()
14191420
clear_temporary_message(len(msg))
14201421
return result

src/test_prerequisites.py

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1991,11 +1991,78 @@ def test_check_dpia_pg_dmcub_usb4_found(
19911991
"USB4 routers found, no need to check DMCUB version"
19921992
)
19931993

1994+
@patch("amd_debug.prerequisites.clear_temporary_message")
1995+
def test_run_failure_records_kernel_log(self, _mock_clear):
1996+
"""Test that the whole kernel log is recorded when prerequisites fail"""
1997+
# Mock all check and info methods to avoid system access
1998+
check_methods = [
1999+
"check_aspm",
2000+
"check_i2c_hid",
2001+
"check_pinctrl_amd",
2002+
"check_amd_hsmp",
2003+
"check_amd_xdna",
2004+
"check_amd_pmc",
2005+
"check_amd_cpu_hpet_wa",
2006+
"check_port_pm_override",
2007+
"check_usb3",
2008+
"check_usb4",
2009+
"check_sleep_mode",
2010+
"check_storage",
2011+
"check_wcn6855_bug",
2012+
"check_amdgpu",
2013+
"check_amdgpu_parameters",
2014+
"check_cpu",
2015+
"check_msr",
2016+
"check_smt",
2017+
"check_iommu",
2018+
"check_asus_rog_ally",
2019+
"check_dpia_pg_dmcub",
2020+
"check_isp4",
2021+
"check_fadt",
2022+
"check_logger",
2023+
"check_lps0",
2024+
"check_permissions",
2025+
"check_wlan",
2026+
"check_taint",
2027+
"capture_acpi",
2028+
"map_acpi_path",
2029+
"check_device_firmware",
2030+
"check_network",
2031+
"capture_disabled_pins",
2032+
]
2033+
for method in check_methods:
2034+
setattr(self.validator, method, MagicMock(return_value=True))
2035+
2036+
# Mock one check to fail
2037+
self.validator.check_permissions.return_value = False
2038+
2039+
# Mock get_cpu_vendor
2040+
self.validator.get_cpu_vendor = MagicMock(return_value="AuthenticAMD")
2041+
2042+
# Set a mock kernel log
2043+
mock_log_content = "Mocked full kernel log content"
2044+
self.mock_kernel_log.get_full_log.return_value = mock_log_content
2045+
2046+
# Run the validator
2047+
with patch(
2048+
"amd_debug.prerequisites.print_temporary_message", return_value="msg"
2049+
):
2050+
result = self.validator.run()
2051+
2052+
self.assertFalse(result)
2053+
# Verify Headers.BrokenPrerequisites was recorded
2054+
from amd_debug.prerequisites import Headers
2055+
2056+
self.mock_db.record_prereq.assert_any_call(Headers.BrokenPrerequisites, "🚫")
2057+
# Verify the whole kernel log was recorded to debug
2058+
self.mock_db.record_debug.assert_called_with(mock_log_content)
2059+
19942060
@patch("amd_debug.prerequisites.find_ip_version", return_value=True)
19952061
@patch("amd_debug.prerequisites.os.path.exists", return_value=True)
19962062
@patch("amd_debug.prerequisites.read_file", return_value="0x90001B01")
2063+
@patch("amd_debug.prerequisites.version.parse")
19972064
def test_check_dpia_pg_dmcub_dmcub_fw_version_new_enough(
1998-
self, mock_read_file, mock_path_exists, mock_find_ip_version
2065+
self, mock_version_parse, mock_read_file, mock_path_exists, mock_find_ip_version
19992066
):
20002067
"""Test check_dpia_pg_dmcub when DMCUB firmware version is new enough"""
20012068
self.mock_pyudev.list_devices.side_effect = [

0 commit comments

Comments
 (0)