blob: 4b0a8996564bfecdeb8b8980d7ef9277237d4c0b [file] [log] [blame]
#!/usr/bin/python3
# SPDX-License-Identifier: MIT
"""
This module contains unit tests for the bios tool in the amd-debug-tools package.
"""
import argparse
import logging
import unittest
from unittest.mock import patch, MagicMock
from amd_debug.bios import AmdBios, parse_args, main
class TestAmdBios(unittest.TestCase):
"""Test AmdBios class"""
@classmethod
def setUpClass(cls):
logging.basicConfig(filename="/dev/null", level=logging.DEBUG)
@patch("amd_debug.bios.get_kernel_log")
def test_init(self, mock_get_kernel_log):
"""Test initialization of AmdBios class"""
mock_kernel_log = MagicMock()
mock_get_kernel_log.return_value = mock_kernel_log
app = AmdBios("test_input", debug=True)
self.assertEqual(app.kernel_log, mock_kernel_log)
@patch("amd_debug.bios.relaunch_sudo")
@patch("amd_debug.bios.minimum_kernel")
@patch("amd_debug.bios.AcpicaTracer")
@patch("amd_debug.bios.print_color")
@patch("subprocess.run")
def test_set_tracing_enable(
self,
_mock_run,
_mock_print,
mock_acpica_tracer,
mock_minimum_kernel,
mock_relaunch_sudo,
):
"""Test enabling tracing"""
mock_minimum_kernel.return_value = True
mock_tracer = MagicMock()
mock_acpica_tracer.return_value = mock_tracer
mock_tracer.trace_bios.return_value = True
app = AmdBios(None, debug=False)
result = app.set_tracing(enable=True)
mock_relaunch_sudo.assert_called_once()
mock_tracer.trace_bios.assert_called_once()
self.assertTrue(result)
@patch("amd_debug.bios.relaunch_sudo")
@patch("amd_debug.bios.minimum_kernel")
@patch("amd_debug.bios.AcpicaTracer")
@patch("amd_debug.bios.print_color")
@patch("subprocess.run")
def test_set_tracing_disable(
self,
_mock_run,
_mock_print,
mock_acpica_tracer,
mock_minimum_kernel,
mock_relaunch_sudo,
):
"""Test disabling tracing"""
mock_minimum_kernel.return_value = True
mock_tracer = MagicMock()
mock_acpica_tracer.return_value = mock_tracer
mock_tracer.disable.return_value = True
app = AmdBios(None, debug=False)
result = app.set_tracing(enable=False)
mock_relaunch_sudo.assert_called_once()
mock_tracer.disable.assert_called_once()
self.assertTrue(result)
@patch("amd_debug.bios.sscanf_bios_args")
@patch("amd_debug.bios.print_color")
@patch("subprocess.run")
def test_analyze_kernel_log_line(
self, _mock_run, mock_print_color, mock_sscanf_bios_args
):
"""Test analyzing kernel log line"""
mock_sscanf_bios_args.return_value = "BIOS argument found"
app = AmdBios(None, debug=False)
app._analyze_kernel_log_line( # pylint: disable=protected-access
"test log line", priority="INFO"
)
mock_sscanf_bios_args.assert_called_once_with("test log line")
mock_print_color.assert_called_once_with("BIOS argument found", "🖴")
@patch("amd_debug.bios.sscanf_bios_args")
@patch("amd_debug.bios.print_color")
@patch("subprocess.run")
def test_analyze_kernel_log_line_no_bios_args(
self, _mock_run, mock_print_color, mock_sscanf_bios_args
):
"""Test analyzing kernel log line with no BIOS arguments"""
mock_sscanf_bios_args.return_value = None
app = AmdBios(None, debug=False)
app._analyze_kernel_log_line( # pylint: disable=protected-access
"[123.456] test log line", priority="INFO"
)
mock_sscanf_bios_args.assert_called_once_with("[123.456] test log line")
mock_print_color.assert_called_once_with("test log line", "INFO")
@patch("amd_debug.bios.get_kernel_log")
def test_run(self, _mock_run):
"""Test run method"""
mock_kernel_log = MagicMock()
app = AmdBios(None, debug=False)
app.kernel_log = mock_kernel_log
app.run()
mock_kernel_log.process_callback.assert_called_once_with(
app._analyze_kernel_log_line # pylint: disable=protected-access
)
@patch("sys.argv", ["bios.py", "parse", "--input", "test.log", "--tool-debug"])
def test_parse_args_parse_command(self):
"""Test parse_args with parse command"""
args = parse_args()
self.assertEqual(args.command, "parse")
self.assertEqual(args.input, "test.log")
self.assertTrue(args.tool_debug)
@patch("sys.argv", ["bios.py", "trace", "--enable", "--tool-debug"])
def test_parse_args_trace_enable(self):
"""Test parse_args with trace enable command"""
args = parse_args()
self.assertEqual(args.command, "trace")
self.assertTrue(args.enable)
self.assertFalse(args.disable)
self.assertTrue(args.tool_debug)
@patch("sys.argv", ["bios.py", "trace", "--disable"])
def test_parse_args_trace_disable(self):
"""Test parse_args with trace disable command"""
args = parse_args()
self.assertEqual(args.command, "trace")
self.assertFalse(args.enable)
self.assertTrue(args.disable)
@patch("sys.argv", ["bios.py", "--version"])
def test_parse_args_version_command(self):
"""Test parse_args with version command"""
args = parse_args()
self.assertTrue(args.version)
@patch("sys.argv", ["bios.py"])
@patch("argparse.ArgumentParser.print_help")
@patch("sys.exit")
def test_parse_args_no_arguments(self, mock_exit, mock_print_help):
"""Test parse_args with no arguments"""
parse_args()
mock_print_help.assert_called_once()
mock_exit.assert_called_once_with(1)
@patch("sys.argv", ["bios.py", "trace", "--enable", "--disable"])
@patch("sys.exit")
def test_parse_args_conflicting_trace_arguments(self, mock_exit):
"""Test parse_args with conflicting trace arguments"""
parse_args()
mock_exit.assert_called_once_with("can't set both enable and disable")
@patch("sys.argv", ["bios.py", "trace"])
@patch("sys.exit")
def test_parse_args_missing_trace_arguments(self, mock_exit):
"""Test parse_args with missing trace arguments"""
parse_args()
mock_exit.assert_called_once_with("must set either enable or disable")
@patch("amd_debug.bios.AmdBios")
@patch("amd_debug.bios.parse_args")
@patch("amd_debug.bios.version")
@patch("amd_debug.bios.show_log_info")
def test_main_trace_command(
self, mock_show_log_info, _mock_version, mock_parse_args, mock_amd_bios
):
"""Test main function with trace command"""
mock_app = MagicMock()
mock_amd_bios.return_value = mock_app
mock_parse_args.return_value = argparse.Namespace(
command="trace", enable=True, disable=False, tool_debug=True
)
mock_app.set_tracing.return_value = True
result = main()
mock_parse_args.assert_called_once()
mock_amd_bios.assert_called_once_with(None, True)
mock_app.set_tracing.assert_called_once_with(True)
mock_show_log_info.assert_called_once()
self.assertIsNone(result)
@patch("amd_debug.bios.AmdBios")
@patch("amd_debug.bios.parse_args")
@patch("amd_debug.bios.version")
@patch("amd_debug.bios.show_log_info")
def test_main_parse_command(
self, mock_show_log_info, _mock_version, mock_parse_args, mock_amd_bios
):
"""Test main function with parse command"""
mock_app = MagicMock()
mock_amd_bios.return_value = mock_app
mock_parse_args.return_value = argparse.Namespace(
command="parse", input="test.log", tool_debug=True
)
mock_app.run.return_value = True
result = main()
mock_parse_args.assert_called_once()
mock_amd_bios.assert_called_once_with("test.log", True)
mock_app.run.assert_called_once()
mock_show_log_info.assert_called_once()
self.assertIsNone(result)
@patch("amd_debug.bios.parse_args")
@patch("amd_debug.bios.version")
@patch("amd_debug.bios.show_log_info")
@patch("amd_debug.bios.print")
def test_main_version_command(
self, _mock_print, mock_show_log_info, mock_version, mock_parse_args
):
"""Test main function with version command"""
mock_parse_args.return_value = argparse.Namespace(version=True, command=None)
mock_version.return_value = "1.0.0"
result = main()
mock_parse_args.assert_called_once()
mock_version.assert_called_once()
mock_show_log_info.assert_called_once()
self.assertEqual(result, 1)
@patch("amd_debug.bios.parse_args")
@patch("amd_debug.bios.show_log_info")
def test_main_invalid_command(self, mock_show_log_info, mock_parse_args):
"""Test main function with an invalid command"""
mock_parse_args.return_value = argparse.Namespace(
version=False, command="invalid"
)
result = main()
mock_parse_args.assert_called_once()
mock_show_log_info.assert_called_once()
self.assertEqual(result, 1)