amd-debug-tools 0.2.0__py3-none-any.whl → 0.2.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,45 @@
1
+ launcher.py,sha256=_Gs0W8tUB2wkTy5Nz4qEzG0VqQcnO7xuIQj0GwV_KbY,968
2
+ test_acpi.py,sha256=wtS43Rz95h7YEEJBeFa6Mswaeo4syBZrw4hY8i0YbJY,3117
3
+ test_batteries.py,sha256=nN5pfP5El7Whypq3HHEpW8bufdf5EWSTVGbayfNQYP4,3360
4
+ test_bios.py,sha256=GBAXE_rXd2G-JE0XJ8AvYcF9Me6LTyQQQ8h0Ib3cpxQ,8981
5
+ test_common.py,sha256=fb16Oilh5ga6VgF-UgBj6azoYzZnPrS7KpECQ3nCwlg,16335
6
+ test_database.py,sha256=q5ZjI5u20f7ki6iCY5o1iPi0YOvPz1_W0LTDraU8mN4,10040
7
+ test_display.py,sha256=hHggv-zBthF1BlwWWSjzAm7BBw1DWcElwil5xAuz87g,5822
8
+ test_failures.py,sha256=H1UxXeVjhJs9-j9yas4vwAha676GX1Es7Kz8RN2B590,6845
9
+ test_installer.py,sha256=oDMCvaKqqAWjTggltacnasQ-s1gyUvXPDcNrCUGnux4,10216
10
+ test_kernel.py,sha256=RW-eLbae02Bhwfu1cegqA1pTj6AS5IqD5lLe-6T0Rjo,7871
11
+ test_launcher.py,sha256=govYHL0Cpj9d5msteV5SfR7Covft31rJuzRkDeytHcY,1461
12
+ test_prerequisites.py,sha256=4Ltxx7vGU91b9MX1AtdPLS8iyWJBCNuEKCuO0nnEb_g,83381
13
+ test_pstate.py,sha256=a9oAJ9-LANX32XNQhplz6Y75VNYc__QqoSBKIrwvANg,6058
14
+ test_s2idle.py,sha256=-S3yymjprf3_LIgaPGWgzN9FmnyQG55dNc4xqWAF8Z8,32344
15
+ test_sleep_report.py,sha256=R3cUPPT9r9q4q93xk6NFvi4ySgT5laqidk2SASuTWIo,5878
16
+ test_validator.py,sha256=NeiX8kT5DiHiiB5lRSJkjIpV32UzaIrW5ljKLmFtBMk,30490
17
+ test_wake.py,sha256=6zi5GVFHQKU1sTWw3O5-aGriB9uu5713QLn4l2wjhpM,7152
18
+ amd_debug/__init__.py,sha256=aOtpIEKGLUStrh0e4qgilHW7HgF4Od-r9pOoZ87NwAM,1105
19
+ amd_debug/acpi.py,sha256=fkD3Sov8cRT5ryPlakRlT7Z9jiCLT9x_MPWxt3xU_tc,3161
20
+ amd_debug/battery.py,sha256=WN-6ys9PHCZIwg7PdwyBOa62GjBp8WKG0v1YZt5_W5s,3122
21
+ amd_debug/bios.py,sha256=wmPKDsTZeQqsHjWpv-YHdgRNlCtFdzHQ6jJf0H3hjN8,3971
22
+ amd_debug/common.py,sha256=H9tIRlRFOMwe0d3f2-vXQeK2rJl5Z1WJzkpQM9ivpOc,10347
23
+ amd_debug/database.py,sha256=GkRg3cmaNceyQ2_hy0MBAlMbnTDPHo2co2o4ObWpnQg,10621
24
+ amd_debug/display.py,sha256=5L9x9tI_UoulHpIvuxuVASRtdXta7UCW_JjTb5StEB0,953
25
+ amd_debug/failures.py,sha256=Otv3YDu7Je4ljSifVmvjObGoOY4OvLIY20pw-v4Dqkw,22911
26
+ amd_debug/installer.py,sha256=r6r_nVWv8qYdrqAvnAzQhRiS5unBDOkXsqUfHvFK8uM,14249
27
+ amd_debug/kernel.py,sha256=xzAy-sDY5-sd4jxyU7EaBokS7YsvEjoWRuexaTJNRBc,11851
28
+ amd_debug/prerequisites.py,sha256=bKJA9ztyapB8rxrNEgc-hxazw5Uh-sP5X0S7zplGA0c,50413
29
+ amd_debug/pstate.py,sha256=akGdJkIxBp0bx3AeGv6ictNxwv8m0j9vQ2IZB0Jx3dM,9518
30
+ amd_debug/s2idle-hook,sha256=LLiaqPtGd0qetu9n6EYxKHZaIdHpVQDONdOuSc0pfFg,1695
31
+ amd_debug/s2idle.py,sha256=lzxLYZBcQllyqEMZfxYEUvQO3ArgVzwL5FHymzvZvSs,13281
32
+ amd_debug/sleep_report.py,sha256=zgwcmSk7S8GAmPtPZJGP29Mr5bcWUBxwNL8HBubKs6Q,15516
33
+ amd_debug/validator.py,sha256=fgG3D0k6DS9ArgzK1SuPUds1FNGoKf2asPUwWoyCsXE,33205
34
+ amd_debug/wake.py,sha256=xT8WrFrN6voCmXWo5dsn4mQ7iR2QJxHrrYBd3EREG-Q,3936
35
+ amd_debug/bash/amd-s2idle,sha256=g_cle1ElCJpwE4wcLezL6y-BdasDKTnNMhrtzKLE9ks,1142
36
+ amd_debug/templates/html,sha256=tnpqHDZF5FfhC6YNRUfOG6Vn9ZtISFr10kEXSB476Mw,14518
37
+ amd_debug/templates/md,sha256=r8X2aehnH2gzj0WHYTZ5K9wAqC5y39i_3nkDORSC0uM,787
38
+ amd_debug/templates/stdout,sha256=hyoOJ96K2dJfnWRWhyCuariLKbEHXvs9mstV_g5aMdI,469
39
+ amd_debug/templates/txt,sha256=nNdsvbPFOhGdL7VA-_4k5aN3nB-6ouGQt6AsWst7T3w,649
40
+ amd_debug_tools-0.2.2.dist-info/licenses/LICENSE,sha256=RBlZI6r3MRGzymI2VDX2iW__D2APDbMhu_Xg5t6BWeo,1066
41
+ amd_debug_tools-0.2.2.dist-info/METADATA,sha256=oZ5H5dL216bbAqtOF8VmvtqkqctPIf5iPibPCjjc1tQ,6877
42
+ amd_debug_tools-0.2.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
43
+ amd_debug_tools-0.2.2.dist-info/entry_points.txt,sha256=HC11T2up0pPfroAn6Pg5M2jOZXhkWIipToJ1YPTKqu8,116
44
+ amd_debug_tools-0.2.2.dist-info/top_level.txt,sha256=XYjxExbUTEtiIlag_5iQvZSVOC1EIxhKM4NLklReQ0k,234
45
+ amd_debug_tools-0.2.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.3.1)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,18 @@
1
+ amd_debug
2
+ launcher
3
+ test_acpi
4
+ test_batteries
5
+ test_bios
6
+ test_common
7
+ test_database
8
+ test_display
9
+ test_failures
10
+ test_installer
11
+ test_kernel
12
+ test_launcher
13
+ test_prerequisites
14
+ test_pstate
15
+ test_s2idle
16
+ test_sleep_report
17
+ test_validator
18
+ test_wake
launcher.py ADDED
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/python3
2
+ # SPDX-License-Identifier: MIT
3
+ """
4
+ This module is a launcher for the AMD Debug Tools package. It is meant for
5
+ launching various tools within the package without installation.
6
+ """
7
+
8
+ import sys
9
+ import os
10
+
11
+ URL = "git://git.kernel.org/pub/scm/linux/kernel/git/superm1/amd-debug-tools.git"
12
+ try:
13
+ import amd_debug
14
+ from amd_debug.common import fatal_error
15
+ except ModuleNotFoundError:
16
+ sys.exit(
17
+ f"\033[91m{sys.argv[0]} can not be run standalone.\n"
18
+ f"\033[0m\033[94mCheck out the full branch from {URL}\033[0m"
19
+ )
20
+
21
+
22
+ def main():
23
+ """Main function to launch the appropriate tool based on the script name."""
24
+ try:
25
+ return amd_debug.launch_tool(os.path.basename(sys.argv[0]))
26
+ except ModuleNotFoundError as e:
27
+ fatal_error(
28
+ f"Missing dependency: {e}\n"
29
+ f"Run ./install_deps.py to install dependencies."
30
+ )
31
+ return False
32
+
33
+
34
+ if __name__ == "__main__":
35
+ sys.exit(main())
test_acpi.py ADDED
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/python3
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ """
5
+ This module contains unit tests for the acpi functions in the amd-debug-tools package.
6
+ """
7
+ from unittest.mock import patch, mock_open, call
8
+
9
+ import logging
10
+ import unittest
11
+
12
+ from amd_debug.acpi import search_acpi_tables, AcpicaTracer, ACPI_METHOD
13
+
14
+
15
+ class TestAcpi(unittest.TestCase):
16
+ """Test acpi functions"""
17
+
18
+ @classmethod
19
+ def setUpClass(cls):
20
+ logging.basicConfig(filename="/dev/null", level=logging.DEBUG)
21
+
22
+ def test_search_acpi_tables(self):
23
+ """Test search_acpi_tables function"""
24
+ pattern = "test_pattern"
25
+ bad_pattern = "bad_pattern"
26
+ mock_listdir = ["ABA", "SSDT1", "DSDT2", "SSDT3"]
27
+ mock_file_content = b"test_pattern"
28
+
29
+ with patch("os.listdir", return_value=mock_listdir), patch(
30
+ "builtins.open", mock_open(read_data=mock_file_content)
31
+ ):
32
+ result = search_acpi_tables(pattern)
33
+ self.assertTrue(result)
34
+
35
+ with patch("os.listdir", return_value=mock_listdir), patch(
36
+ "builtins.open", mock_open(read_data=mock_file_content)
37
+ ):
38
+ result = search_acpi_tables(bad_pattern)
39
+ self.assertFalse(result)
40
+
41
+ with patch("os.listdir", return_value=["OTHER1", "OTHER2"]), patch(
42
+ "builtins.open", mock_open(read_data=b"no_match")
43
+ ):
44
+ result = search_acpi_tables(pattern)
45
+ self.assertFalse(result)
46
+
47
+ def test_acpica_tracer_missing_bios(self):
48
+ """Test AcpicaTracer class when ACPI tracing is not supported"""
49
+
50
+ mock_listdir = ["SSDT1", "DSDT2", "SSDT3"]
51
+
52
+ with patch("os.listdir", return_value=mock_listdir), patch(
53
+ "builtins.open", mock_open(read_data=b"foo")
54
+ ), patch("os.path.exists", return_value=True):
55
+
56
+ tracer = AcpicaTracer()
57
+ self.assertTrue(tracer.supported)
58
+
59
+ self.assertFalse(tracer.trace_bios())
60
+
61
+ def test_acpica_tracer(self):
62
+ """Test AcpicaTracer class"""
63
+
64
+ mock_listdir = ["SSDT1", "DSDT2", "SSDT3"]
65
+ mock_file_content = bytes(ACPI_METHOD, "utf-8")
66
+
67
+ with patch("os.listdir", return_value=mock_listdir), patch(
68
+ "builtins.open", mock_open(read_data=mock_file_content)
69
+ ), patch("os.path.exists", return_value=True):
70
+
71
+ tracer = AcpicaTracer()
72
+ self.assertTrue(tracer.supported)
73
+
74
+ self.assertTrue(tracer.trace_notify())
75
+ self.assertTrue(tracer.trace_bios())
76
+ self.assertTrue(tracer.disable())
77
+ self.assertTrue(tracer.restore())
78
+
79
+ def test_acpica_trace_no_acpi_debug(self):
80
+ """Test AcpicaTracer class when ACPI tracing is not supported"""
81
+ with patch("os.path.exists", return_value=False), patch(
82
+ "builtins.open", mock_open(read_data="foo")
83
+ ):
84
+ tracer = AcpicaTracer()
85
+ self.assertFalse(tracer.supported)
86
+
87
+ self.assertFalse(tracer.trace_notify())
88
+ self.assertFalse(tracer.trace_bios())
89
+ self.assertFalse(tracer.disable())
90
+ self.assertFalse(tracer.restore())
test_batteries.py ADDED
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/python3
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ """
5
+ This module contains unit tests for the battery functions in the amd-debug-tools package.
6
+ """
7
+ import unittest
8
+ import logging
9
+ from unittest.mock import MagicMock, patch
10
+
11
+
12
+ from amd_debug.battery import Batteries
13
+
14
+
15
+ class TestBatteries(unittest.TestCase):
16
+ """Test battery functions"""
17
+
18
+ @classmethod
19
+ def setUpClass(cls):
20
+ logging.basicConfig(filename="/dev/null", level=logging.DEBUG)
21
+
22
+ @patch("amd_debug.battery.Context")
23
+ def setUp(self, mock_context):
24
+ """Set up a mock context for testing"""
25
+ self.mock_context = mock_context.return_value
26
+ self.batteries = Batteries()
27
+
28
+ def test_get_batteries(self):
29
+ """Test getting battery names"""
30
+ mock_device = MagicMock()
31
+ mock_device.device_path = "/devices/LNXSYSTM:00/device:00/PNP0C0A:00"
32
+ mock_device.properties = {"POWER_SUPPLY_NAME": "BAT0"}
33
+ self.mock_context.list_devices.return_value = [mock_device]
34
+
35
+ result = self.batteries.get_batteries()
36
+ self.assertEqual(result, ["BAT0"])
37
+
38
+ def test_get_energy_unit(self):
39
+ """Test getting energy unit for a battery"""
40
+ mock_device = MagicMock()
41
+ mock_device.device_path = "/devices/LNXSYSTM:00/device:00/PNP0C0A:00"
42
+ mock_device.properties = {
43
+ "POWER_SUPPLY_NAME": "BAT0",
44
+ "POWER_SUPPLY_ENERGY_NOW": "50000",
45
+ }
46
+ self.mock_context.list_devices.return_value = [mock_device]
47
+ result = self.batteries.get_energy_unit("BAT0")
48
+ self.assertEqual(result, "µWh")
49
+
50
+ def test_get_energy(self):
51
+ """Test getting current energy for a battery"""
52
+ mock_device = MagicMock()
53
+ mock_device.device_path = "/devices/LNXSYSTM:00/device:00/PNP0C0A:00"
54
+ mock_device.properties = {
55
+ "POWER_SUPPLY_NAME": "BAT0",
56
+ "POWER_SUPPLY_ENERGY_NOW": "50000",
57
+ }
58
+ self.mock_context.list_devices.return_value = [mock_device]
59
+ result = self.batteries.get_energy("BAT0")
60
+ self.assertEqual(result, "50000")
61
+
62
+ def test_get_energy_full(self):
63
+ """Test getting full energy for a battery"""
64
+ mock_device = MagicMock()
65
+ mock_device.device_path = "/devices/LNXSYSTM:00/device:00/PNP0C0A:00"
66
+ mock_device.properties = {
67
+ "POWER_SUPPLY_NAME": "BAT0",
68
+ "POWER_SUPPLY_ENERGY_FULL": "60000",
69
+ }
70
+ self.mock_context.list_devices.return_value = [mock_device]
71
+
72
+ result = self.batteries.get_energy_full("BAT0")
73
+ self.assertEqual(result, "60000")
74
+
75
+ def test_get_description_string(self):
76
+ """Test getting description string for a battery"""
77
+ mock_device = MagicMock()
78
+ mock_device.device_path = "/devices/LNXSYSTM:00/device:00/PNP0C0A:00"
79
+ mock_device.properties = {
80
+ "POWER_SUPPLY_NAME": "BAT0",
81
+ "POWER_SUPPLY_MANUFACTURER": "ACME",
82
+ "POWER_SUPPLY_MODEL_NAME": "SuperBattery",
83
+ "POWER_SUPPLY_ENERGY_FULL": "60000",
84
+ "POWER_SUPPLY_ENERGY_FULL_DESIGN": "80000",
85
+ }
86
+ self.mock_context.list_devices.return_value = [mock_device]
87
+
88
+ result = self.batteries.get_description_string("BAT0")
89
+ self.assertEqual(
90
+ result,
91
+ "Battery BAT0 (ACME SuperBattery) is operating at 75.00% of design",
92
+ )
test_bios.py ADDED
@@ -0,0 +1,250 @@
1
+ #!/usr/bin/python3
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ """
5
+ This module contains unit tests for the bios tool in the amd-debug-tools package.
6
+ """
7
+ import argparse
8
+ import logging
9
+ import unittest
10
+ from unittest.mock import patch, MagicMock
11
+
12
+ from amd_debug.bios import AmdBios, parse_args, main
13
+
14
+
15
+ class TestAmdBios(unittest.TestCase):
16
+ """Test AmdBios class"""
17
+
18
+ @classmethod
19
+ def setUpClass(cls):
20
+ logging.basicConfig(filename="/dev/null", level=logging.DEBUG)
21
+
22
+ @patch("amd_debug.bios.get_kernel_log")
23
+ def test_init(self, mock_get_kernel_log):
24
+ """Test initialization of AmdBios class"""
25
+ mock_kernel_log = MagicMock()
26
+ mock_get_kernel_log.return_value = mock_kernel_log
27
+
28
+ app = AmdBios("test_input", debug=True)
29
+
30
+ self.assertEqual(app.kernel_log, mock_kernel_log)
31
+
32
+ @patch("amd_debug.bios.relaunch_sudo")
33
+ @patch("amd_debug.bios.minimum_kernel")
34
+ @patch("amd_debug.bios.AcpicaTracer")
35
+ @patch("amd_debug.bios.print_color")
36
+ def test_set_tracing_enable(
37
+ self, _mock_print, mock_acpica_tracer, mock_minimum_kernel, mock_relaunch_sudo
38
+ ):
39
+ """Test enabling tracing"""
40
+ mock_minimum_kernel.return_value = True
41
+ mock_tracer = MagicMock()
42
+ mock_acpica_tracer.return_value = mock_tracer
43
+ mock_tracer.trace_bios.return_value = True
44
+
45
+ app = AmdBios(None, debug=False)
46
+ result = app.set_tracing(enable=True)
47
+
48
+ mock_relaunch_sudo.assert_called_once()
49
+ mock_tracer.trace_bios.assert_called_once()
50
+ self.assertTrue(result)
51
+
52
+ @patch("amd_debug.bios.relaunch_sudo")
53
+ @patch("amd_debug.bios.minimum_kernel")
54
+ @patch("amd_debug.bios.AcpicaTracer")
55
+ @patch("amd_debug.bios.print_color")
56
+ def test_set_tracing_disable(
57
+ self, _mock_print, mock_acpica_tracer, mock_minimum_kernel, mock_relaunch_sudo
58
+ ):
59
+ """Test disabling tracing"""
60
+ mock_minimum_kernel.return_value = True
61
+ mock_tracer = MagicMock()
62
+ mock_acpica_tracer.return_value = mock_tracer
63
+ mock_tracer.disable.return_value = True
64
+
65
+ app = AmdBios(None, debug=False)
66
+ result = app.set_tracing(enable=False)
67
+
68
+ mock_relaunch_sudo.assert_called_once()
69
+ mock_tracer.disable.assert_called_once()
70
+ self.assertTrue(result)
71
+
72
+ @patch("amd_debug.bios.sscanf_bios_args")
73
+ @patch("amd_debug.bios.print_color")
74
+ def test_analyze_kernel_log_line(self, mock_print_color, mock_sscanf_bios_args):
75
+ """Test analyzing kernel log line"""
76
+ mock_sscanf_bios_args.return_value = "BIOS argument found"
77
+
78
+ app = AmdBios(None, debug=False)
79
+ app._analyze_kernel_log_line( # pylint: disable=protected-access
80
+ "test log line", priority="INFO"
81
+ )
82
+
83
+ mock_sscanf_bios_args.assert_called_once_with("test log line")
84
+ mock_print_color.assert_called_once_with("BIOS argument found", "🖴")
85
+
86
+ @patch("amd_debug.bios.sscanf_bios_args")
87
+ @patch("amd_debug.bios.print_color")
88
+ def test_analyze_kernel_log_line_no_bios_args(
89
+ self, mock_print_color, mock_sscanf_bios_args
90
+ ):
91
+ """Test analyzing kernel log line with no BIOS arguments"""
92
+ mock_sscanf_bios_args.return_value = None
93
+
94
+ app = AmdBios(None, debug=False)
95
+ app._analyze_kernel_log_line( # pylint: disable=protected-access
96
+ "[123.456] test log line", priority="INFO"
97
+ )
98
+
99
+ mock_sscanf_bios_args.assert_called_once_with("[123.456] test log line")
100
+ mock_print_color.assert_called_once_with("test log line", "INFO")
101
+
102
+ @patch("amd_debug.bios.get_kernel_log")
103
+ def test_run(self, _mock_run):
104
+ """Test run method"""
105
+ mock_kernel_log = MagicMock()
106
+ app = AmdBios(None, debug=False)
107
+ app.kernel_log = mock_kernel_log
108
+
109
+ app.run()
110
+
111
+ mock_kernel_log.process_callback.assert_called_once_with(
112
+ app._analyze_kernel_log_line # pylint: disable=protected-access
113
+ )
114
+
115
+ @patch("sys.argv", ["bios.py", "parse", "--input", "test.log", "--tool-debug"])
116
+ def test_parse_args_parse_command(self):
117
+ """Test parse_args with parse command"""
118
+
119
+ args = parse_args()
120
+ self.assertEqual(args.command, "parse")
121
+ self.assertEqual(args.input, "test.log")
122
+ self.assertTrue(args.tool_debug)
123
+
124
+ @patch("sys.argv", ["bios.py", "trace", "--enable", "--tool-debug"])
125
+ def test_parse_args_trace_enable(self):
126
+ """Test parse_args with trace enable command"""
127
+
128
+ args = parse_args()
129
+ self.assertEqual(args.command, "trace")
130
+ self.assertTrue(args.enable)
131
+ self.assertFalse(args.disable)
132
+ self.assertTrue(args.tool_debug)
133
+
134
+ @patch("sys.argv", ["bios.py", "trace", "--disable"])
135
+ def test_parse_args_trace_disable(self):
136
+ """Test parse_args with trace disable command"""
137
+
138
+ args = parse_args()
139
+ self.assertEqual(args.command, "trace")
140
+ self.assertFalse(args.enable)
141
+ self.assertTrue(args.disable)
142
+
143
+ @patch("sys.argv", ["bios.py", "version"])
144
+ def test_parse_args_version_command(self):
145
+ """Test parse_args with version command"""
146
+
147
+ args = parse_args()
148
+ self.assertEqual(args.command, "version")
149
+
150
+ @patch("sys.argv", ["bios.py"])
151
+ @patch("argparse.ArgumentParser.print_help")
152
+ @patch("sys.exit")
153
+ def test_parse_args_no_arguments(self, mock_exit, mock_print_help):
154
+ """Test parse_args with no arguments"""
155
+
156
+ parse_args()
157
+ mock_print_help.assert_called_once()
158
+ mock_exit.assert_called_once_with(1)
159
+
160
+ @patch("sys.argv", ["bios.py", "trace", "--enable", "--disable"])
161
+ @patch("sys.exit")
162
+ def test_parse_args_conflicting_trace_arguments(self, mock_exit):
163
+ """Test parse_args with conflicting trace arguments"""
164
+
165
+ parse_args()
166
+ mock_exit.assert_called_once_with("can't set both enable and disable")
167
+
168
+ @patch("sys.argv", ["bios.py", "trace"])
169
+ @patch("sys.exit")
170
+ def test_parse_args_missing_trace_arguments(self, mock_exit):
171
+ """Test parse_args with missing trace arguments"""
172
+
173
+ parse_args()
174
+ mock_exit.assert_called_once_with("must set either enable or disable")
175
+
176
+ @patch("amd_debug.bios.AmdBios")
177
+ @patch("amd_debug.bios.parse_args")
178
+ @patch("amd_debug.bios.version")
179
+ @patch("amd_debug.bios.show_log_info")
180
+ def test_main_trace_command(
181
+ self, mock_show_log_info, _mock_version, mock_parse_args, mock_amd_bios
182
+ ):
183
+ """Test main function with trace command"""
184
+ mock_app = MagicMock()
185
+ mock_amd_bios.return_value = mock_app
186
+ mock_parse_args.return_value = argparse.Namespace(
187
+ command="trace", enable=True, disable=False, tool_debug=True
188
+ )
189
+ mock_app.set_tracing.return_value = True
190
+
191
+ result = main()
192
+
193
+ mock_parse_args.assert_called_once()
194
+ mock_amd_bios.assert_called_once_with(None, True)
195
+ mock_app.set_tracing.assert_called_once_with(True)
196
+ mock_show_log_info.assert_called_once()
197
+ self.assertTrue(result)
198
+
199
+ @patch("amd_debug.bios.AmdBios")
200
+ @patch("amd_debug.bios.parse_args")
201
+ @patch("amd_debug.bios.version")
202
+ @patch("amd_debug.bios.show_log_info")
203
+ def test_main_parse_command(
204
+ self, mock_show_log_info, _mock_version, mock_parse_args, mock_amd_bios
205
+ ):
206
+ """Test main function with parse command"""
207
+ mock_app = MagicMock()
208
+ mock_amd_bios.return_value = mock_app
209
+ mock_parse_args.return_value = argparse.Namespace(
210
+ command="parse", input="test.log", tool_debug=True
211
+ )
212
+ mock_app.run.return_value = True
213
+
214
+ result = main()
215
+
216
+ mock_parse_args.assert_called_once()
217
+ mock_amd_bios.assert_called_once_with("test.log", True)
218
+ mock_app.run.assert_called_once()
219
+ mock_show_log_info.assert_called_once()
220
+ self.assertTrue(result)
221
+
222
+ @patch("amd_debug.bios.parse_args")
223
+ @patch("amd_debug.bios.version")
224
+ @patch("amd_debug.bios.show_log_info")
225
+ @patch("amd_debug.bios.print")
226
+ def test_main_version_command(
227
+ self, _mock_print, mock_show_log_info, mock_version, mock_parse_args
228
+ ):
229
+ """Test main function with version command"""
230
+ mock_parse_args.return_value = argparse.Namespace(command="version")
231
+ mock_version.return_value = "1.0.0"
232
+
233
+ result = main()
234
+
235
+ mock_parse_args.assert_called_once()
236
+ mock_version.assert_called_once()
237
+ mock_show_log_info.assert_called_once()
238
+ self.assertEqual(result, False)
239
+
240
+ @patch("amd_debug.bios.parse_args")
241
+ @patch("amd_debug.bios.show_log_info")
242
+ def test_main_invalid_command(self, mock_show_log_info, mock_parse_args):
243
+ """Test main function with an invalid command"""
244
+ mock_parse_args.return_value = argparse.Namespace(command="invalid")
245
+
246
+ result = main()
247
+
248
+ mock_parse_args.assert_called_once()
249
+ mock_show_log_info.assert_called_once()
250
+ self.assertFalse(result)