| #!/usr/bin/python3 |
| # SPDX-License-Identifier: MIT |
| |
| """ |
| This module contains unit tests for the pstate tool in the amd-debug-tools package. |
| """ |
| |
| import logging |
| import unittest |
| from unittest.mock import patch, MagicMock |
| |
| from amd_debug.pstate import ( |
| AmdPstateTriage, |
| amd_cppc_cap_lowest_perf, |
| amd_cppc_cap_lownonlin_perf, |
| amd_cppc_cap_nominal_perf, |
| amd_cppc_cap_highest_perf, |
| amd_cppc_max_perf, |
| amd_cppc_min_perf, |
| amd_cppc_des_perf, |
| amd_cppc_epp_perf, |
| ) |
| |
| |
| class TestAmdPstateTriage(unittest.TestCase): |
| """Test AmdPstateTriage class""" |
| |
| @classmethod |
| def setUpClass(cls): |
| logging.basicConfig(filename="/dev/null", level=logging.DEBUG) |
| |
| @patch("amd_debug.pstate.relaunch_sudo") |
| @patch("amd_debug.pstate.get_pretty_distro", return_value="Test Distro") |
| @patch("amd_debug.pstate.print_color") |
| @patch("amd_debug.pstate.Context") |
| def test_init( |
| self, |
| _mock_context, |
| mock_print_color, |
| mock_get_pretty_distro, |
| mock_relaunch_sudo, |
| ): |
| """Test initialization of AmdPstateTriage class""" |
| triage = AmdPstateTriage(logging=True) |
| mock_relaunch_sudo.assert_called_once() |
| mock_get_pretty_distro.assert_called_once() |
| mock_print_color.assert_called_with("Test Distro", "🐧") |
| self.assertIsNotNone(triage.context) |
| |
| @patch("amd_debug.pstate.os.path.exists", return_value=True) |
| @patch("amd_debug.pstate.read_file", return_value="test_value") |
| @patch("amd_debug.pstate.print_color") |
| @patch("amd_debug.pstate.relaunch_sudo") |
| def test_gather_amd_pstate_info( |
| self, _mock_relaunch_sudo, mock_print_color, mock_read_file, mock_path_exists |
| ): |
| """Test gather_amd_pstate_info method""" |
| triage = AmdPstateTriage(logging=False) |
| triage.gather_amd_pstate_info() |
| mock_path_exists.assert_called() |
| mock_read_file.assert_called() |
| mock_print_color.assert_any_call("'status':\ttest_value", "○") |
| mock_print_color.assert_any_call("'prefcore':\ttest_value", "○") |
| |
| @patch( |
| "amd_debug.pstate.os.uname", |
| return_value=MagicMock(sysname="Linux", release="5.15.0"), |
| ) |
| @patch("amd_debug.pstate.print_color") |
| @patch("amd_debug.pstate.relaunch_sudo") |
| def test_gather_kernel_info( |
| self, _mock_relaunch_sudo, mock_print_color, mock_uname |
| ): |
| """Test gather_kernel_info method""" |
| triage = AmdPstateTriage(logging=False) |
| triage.gather_kernel_info() |
| mock_uname.assert_called() |
| mock_print_color.assert_called_with("Kernel:\t5.15.0", "🐧") |
| |
| @patch("amd_debug.pstate.os.path.exists", return_value=True) |
| @patch("amd_debug.pstate.read_file", return_value="1") |
| @patch("amd_debug.pstate.print_color") |
| @patch("amd_debug.pstate.relaunch_sudo") |
| def test_gather_scheduler_info( |
| self, _mock_relaunch_sudo, mock_print_color, mock_read_file, mock_path_exists |
| ): |
| """Test gather_scheduler_info method""" |
| triage = AmdPstateTriage(logging=False) |
| triage.gather_scheduler_info() |
| mock_path_exists.assert_called() |
| mock_read_file.assert_called() |
| mock_print_color.assert_any_call("ITMT:\t1", "🐧") |
| |
| @patch("amd_debug.pstate.read_msr") |
| @patch("amd_debug.pstate.print_color") |
| @patch("amd_debug.pstate.Context") |
| @patch("amd_debug.pstate.relaunch_sudo") |
| def test_gather_msrs( |
| self, _mock_relaunch_sudo, mock_context, mock_print_color, mock_read_msr |
| ): |
| """Test gather_msrs method""" |
| # Mock the list of CPUs |
| mock_context.return_value.list_devices.return_value = [ |
| MagicMock(sys_name="cpu0"), |
| MagicMock(sys_name="cpu1"), |
| ] |
| |
| # Mock MSR values for the CPUs |
| mock_read_msr.side_effect = [ |
| 0x1, # MSR_AMD_CPPC_ENABLE for cpu0 |
| 0x2, # MSR_AMD_CPPC_STATUS for cpu0 |
| 0x12345678, # MSR_AMD_CPPC_CAP1 for cpu0 |
| 0x87654321, # MSR_AMD_CPPC_CAP2 for cpu0 |
| 0xABCDEF, # MSR_AMD_CPPC_REQ for cpu0 |
| 0x1, # MSR_AMD_CPPC_ENABLE for cpu1 |
| 0x2, # MSR_AMD_CPPC_STATUS for cpu1 |
| 0x12345678, # MSR_AMD_CPPC_CAP1 for cpu1 |
| 0x87654321, # MSR_AMD_CPPC_CAP2 for cpu1 |
| 0xABCDEF, # MSR_AMD_CPPC_REQ for cpu1 |
| ] |
| |
| triage = AmdPstateTriage(logging=False) |
| result = triage.gather_msrs() |
| |
| # Assert that MSR values were read for both CPUs |
| self.assertEqual(mock_read_msr.call_count, 10) |
| |
| # Assert that print_color was called to display the MSR information |
| self.assertTrue(mock_print_color.called) |
| |
| # Assert that the method returned True (indicating success) |
| self.assertIsNone(result) |
| |
| def test_amd_cppc_cap_lowest_perf(self): |
| """Test amd_cppc_cap_lowest_perf function""" |
| self.assertEqual(amd_cppc_cap_lowest_perf(0x12345678), 0x78) |
| |
| def test_amd_cppc_cap_lownonlin_perf(self): |
| """Test amd_cppc_cap_lownonlin_perf function""" |
| self.assertEqual(amd_cppc_cap_lownonlin_perf(0x12345678), 0x56) |
| |
| def test_amd_cppc_cap_nominal_perf(self): |
| """Test amd_cppc_cap_nominal_perf function""" |
| self.assertEqual(amd_cppc_cap_nominal_perf(0x12345678), 0x34) |
| |
| def test_amd_cppc_cap_highest_perf(self): |
| """Test amd_cppc_cap_highest_perf function""" |
| self.assertEqual(amd_cppc_cap_highest_perf(0x12345678), 0x12) |
| |
| def test_amd_cppc_max_perf(self): |
| """Test amd_cppc_max_perf function""" |
| self.assertEqual(amd_cppc_max_perf(0x12345678), 0x78) |
| |
| def test_amd_cppc_min_perf(self): |
| """Test amd_cppc_min_perf function""" |
| self.assertEqual(amd_cppc_min_perf(0x12345678), 0x56) |
| |
| def test_amd_cppc_des_perf(self): |
| """Test amd_cppc_des_perf function""" |
| self.assertEqual(amd_cppc_des_perf(0x12345678), 0x34) |
| |
| def test_amd_cppc_epp_perf(self): |
| """Test amd_cppc_epp_perf function""" |
| self.assertEqual(amd_cppc_epp_perf(0x12345678), 0x12) |