From 4aa66d87e8eb068554c76ec66b23236a542b3a32 Mon Sep 17 00:00:00 2001 From: Bin Li Date: Thu, 9 Nov 2023 12:03:39 +0200 Subject: [PATCH 1/5] Add testcase to check power-mode before and after suspend --- providers/base/units/suspend/suspend.pxu | 34 +++++++++++++ providers/resource/bin/power_mode_resource.py | 49 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100755 providers/resource/bin/power_mode_resource.py diff --git a/providers/base/units/suspend/suspend.pxu b/providers/base/units/suspend/suspend.pxu index 305af613cf..85f2e7c899 100644 --- a/providers/base/units/suspend/suspend.pxu +++ b/providers/base/units/suspend/suspend.pxu @@ -56,6 +56,16 @@ estimated_duration: 1.2 _summary: Dumps memory info to a file for comparison after suspend command: meminfo_resource.py > "$PLAINBOX_SESSION_SHARE"/meminfo_before_suspend +plugin: shell +category_id: com.canonical.plainbox::suspend +id: suspend/power_mode_before_suspend +estimated_duration: 1.2 +requires: + module.name == 'platform_profile' + package.name == 'power-profiles-daemon' +_summary: Dumps power_mode info to a file for comparison after suspend +command: power_mode_resource.py > "$PLAINBOX_SESSION_SHARE"/power_mode_before_suspend + unit: template template-resource: device template-filter: device.category == 'NETWORK' @@ -616,6 +626,30 @@ _purpose: command: meminfo_resource.py | diff "$PLAINBOX_SESSION_SHARE"/meminfo_before_suspend - _summary: Ensure all memory is accessible after waking from suspend mode. +plugin: shell +category_id: com.canonical.plainbox::suspend +id: suspend/power_mode_after_suspend +estimated_duration: 1.2 +requires: + module.name == 'platform_profile' + package.name == 'power-profiles-daemon' +depends: suspend/suspend_advanced_auto suspend/power_mode_before_suspend +_description: + Verify that power mode is changed after resuming from suspend. +command: power_mode_resource.py | diff "$PLAINBOX_SESSION_SHARE"/power_mode_before_suspend - + +plugin: shell +category_id: com.canonical.plainbox::suspend +id: suspend/power_mode_after_suspend_auto +estimated_duration: 1.2 +requires: + module.name == 'platform_profile' + package.name == 'power-profiles-daemon' +depends: suspend/suspend_advanced_auto suspend/power_mode_before_suspend +_description: + Verify that power mode is changed after resuming from suspend. +command: power_mode_resource.py | diff "$PLAINBOX_SESSION_SHARE"/power_mode_before_suspend - + plugin: manual category_id: com.canonical.plainbox::suspend id: suspend/display_after_suspend diff --git a/providers/resource/bin/power_mode_resource.py b/providers/resource/bin/power_mode_resource.py new file mode 100755 index 0000000000..46474a9669 --- /dev/null +++ b/providers/resource/bin/power_mode_resource.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +# +# This file is part of Checkbox. +# +# Copyright 2023 Canonical Ltd. +# +# Checkbox is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 3, +# as published by the Free Software Foundation. + +# +# Checkbox is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Checkbox. If not, see . +# + +"""Modules providing a function running os or sys commands.""" +import sys +import os + + +def main(): + """Dump the power mode.""" + sysfs_root = "/sys/firmware/acpi/" + if not os.path.isdir(sysfs_root): + return 1 + + profile_filename = os.path.join(sysfs_root, "platform_profile") + if (not os.path.isfile(profile_filename) or + not os.access(profile_filename, os.R_OK)): + return 1 + + with open(profile_filename, "rt", encoding="utf-8") as stream: + profile = stream.read().strip().split() + if len(profile) < 1: + return 1 + else: + print(profile[0]) + # uncomment the following line to do local testing + #os.system(f"powerprofilesctl set power-saver") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) From 02dba0f782842ce2bd9e6d5255ec919936297ca9 Mon Sep 17 00:00:00 2001 From: Bin Li Date: Tue, 26 Mar 2024 15:06:14 +0800 Subject: [PATCH 2/5] Remove the duplicated test id --- providers/base/units/suspend/suspend.pxu | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/providers/base/units/suspend/suspend.pxu b/providers/base/units/suspend/suspend.pxu index 85f2e7c899..7c02005144 100644 --- a/providers/base/units/suspend/suspend.pxu +++ b/providers/base/units/suspend/suspend.pxu @@ -638,18 +638,6 @@ _description: Verify that power mode is changed after resuming from suspend. command: power_mode_resource.py | diff "$PLAINBOX_SESSION_SHARE"/power_mode_before_suspend - -plugin: shell -category_id: com.canonical.plainbox::suspend -id: suspend/power_mode_after_suspend_auto -estimated_duration: 1.2 -requires: - module.name == 'platform_profile' - package.name == 'power-profiles-daemon' -depends: suspend/suspend_advanced_auto suspend/power_mode_before_suspend -_description: - Verify that power mode is changed after resuming from suspend. -command: power_mode_resource.py | diff "$PLAINBOX_SESSION_SHARE"/power_mode_before_suspend - - plugin: manual category_id: com.canonical.plainbox::suspend id: suspend/display_after_suspend From 3b0e8324bbbe5b1fbe7b5b80c2e1ab63ba3a4e2e Mon Sep 17 00:00:00 2001 From: Bin Li Date: Wed, 3 Apr 2024 21:33:48 +0800 Subject: [PATCH 3/5] Using platform_profile resource --- providers/base/units/suspend/suspend.pxu | 2 ++ 1 file changed, 2 insertions(+) diff --git a/providers/base/units/suspend/suspend.pxu b/providers/base/units/suspend/suspend.pxu index 7c02005144..145d2e638d 100644 --- a/providers/base/units/suspend/suspend.pxu +++ b/providers/base/units/suspend/suspend.pxu @@ -63,6 +63,7 @@ estimated_duration: 1.2 requires: module.name == 'platform_profile' package.name == 'power-profiles-daemon' + platform_profile.supported == 'True' _summary: Dumps power_mode info to a file for comparison after suspend command: power_mode_resource.py > "$PLAINBOX_SESSION_SHARE"/power_mode_before_suspend @@ -633,6 +634,7 @@ estimated_duration: 1.2 requires: module.name == 'platform_profile' package.name == 'power-profiles-daemon' + platform_profile.supported == 'True' depends: suspend/suspend_advanced_auto suspend/power_mode_before_suspend _description: Verify that power mode is changed after resuming from suspend. From 422a5d299f31f12a27260101c0b4322459605be1 Mon Sep 17 00:00:00 2001 From: Bin Li Date: Wed, 3 Apr 2024 22:32:54 +0800 Subject: [PATCH 4/5] Rename file --- providers/base/bin/check_power_mode.py | 38 ++++++++++++++ providers/base/units/suspend/suspend.pxu | 4 +- providers/resource/bin/power_mode_resource.py | 49 ------------------- 3 files changed, 40 insertions(+), 51 deletions(-) create mode 100755 providers/base/bin/check_power_mode.py delete mode 100755 providers/resource/bin/power_mode_resource.py diff --git a/providers/base/bin/check_power_mode.py b/providers/base/bin/check_power_mode.py new file mode 100755 index 0000000000..a0683d2c99 --- /dev/null +++ b/providers/base/bin/check_power_mode.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +# +# This file is part of Checkbox. +# +# Copyright 2023 Canonical Ltd. +# +# Checkbox is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 3, +# as published by the Free Software Foundation. + +# +# Checkbox is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Checkbox. If not, see . +# + +"""Check current power mode.""" +from pathlib import Path +from switch_power_mode import get_sysfs_content + + +def main(): + """main function to read the power mode.""" + sysfs_root = Path("/sys/firmware/acpi/") + profile_path = sysfs_root / "platform_profile" + + profile = get_sysfs_content(profile_path).split() + print(profile[0]) + # uncomment the following line to change another mode + # os.system(f"powerprofilesctl set power-saver") + + +if __name__ == "__main__": + main() diff --git a/providers/base/units/suspend/suspend.pxu b/providers/base/units/suspend/suspend.pxu index 145d2e638d..50282bcb12 100644 --- a/providers/base/units/suspend/suspend.pxu +++ b/providers/base/units/suspend/suspend.pxu @@ -65,7 +65,7 @@ requires: package.name == 'power-profiles-daemon' platform_profile.supported == 'True' _summary: Dumps power_mode info to a file for comparison after suspend -command: power_mode_resource.py > "$PLAINBOX_SESSION_SHARE"/power_mode_before_suspend +command: check_power_mode.py > "$PLAINBOX_SESSION_SHARE"/power_mode_before_suspend unit: template template-resource: device @@ -638,7 +638,7 @@ requires: depends: suspend/suspend_advanced_auto suspend/power_mode_before_suspend _description: Verify that power mode is changed after resuming from suspend. -command: power_mode_resource.py | diff "$PLAINBOX_SESSION_SHARE"/power_mode_before_suspend - +command: check_power_mode.py | diff "$PLAINBOX_SESSION_SHARE"/power_mode_before_suspend - plugin: manual category_id: com.canonical.plainbox::suspend diff --git a/providers/resource/bin/power_mode_resource.py b/providers/resource/bin/power_mode_resource.py deleted file mode 100755 index 46474a9669..0000000000 --- a/providers/resource/bin/power_mode_resource.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python3 -# -# This file is part of Checkbox. -# -# Copyright 2023 Canonical Ltd. -# -# Checkbox is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 3, -# as published by the Free Software Foundation. - -# -# Checkbox is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Checkbox. If not, see . -# - -"""Modules providing a function running os or sys commands.""" -import sys -import os - - -def main(): - """Dump the power mode.""" - sysfs_root = "/sys/firmware/acpi/" - if not os.path.isdir(sysfs_root): - return 1 - - profile_filename = os.path.join(sysfs_root, "platform_profile") - if (not os.path.isfile(profile_filename) or - not os.access(profile_filename, os.R_OK)): - return 1 - - with open(profile_filename, "rt", encoding="utf-8") as stream: - profile = stream.read().strip().split() - if len(profile) < 1: - return 1 - else: - print(profile[0]) - # uncomment the following line to do local testing - #os.system(f"powerprofilesctl set power-saver") - return 0 - - -if __name__ == "__main__": - sys.exit(main()) From ebf8361aef914c662a50c6d6da88cdcdafc9817f Mon Sep 17 00:00:00 2001 From: Bin Li Date: Thu, 4 Apr 2024 00:04:23 +0800 Subject: [PATCH 5/5] Add unittest --- providers/base/bin/check_power_mode.py | 12 ++-- providers/base/tests/test_check_power_mode.py | 58 +++++++++++++++++++ 2 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 providers/base/tests/test_check_power_mode.py diff --git a/providers/base/bin/check_power_mode.py b/providers/base/bin/check_power_mode.py index a0683d2c99..c31a407c8c 100755 --- a/providers/base/bin/check_power_mode.py +++ b/providers/base/bin/check_power_mode.py @@ -2,7 +2,8 @@ # # This file is part of Checkbox. # -# Copyright 2023 Canonical Ltd. +# Copyright 2024 Canonical Ltd. +# Authors: Bin Li # # Checkbox is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3, @@ -28,10 +29,11 @@ def main(): sysfs_root = Path("/sys/firmware/acpi/") profile_path = sysfs_root / "platform_profile" - profile = get_sysfs_content(profile_path).split() - print(profile[0]) - # uncomment the following line to change another mode - # os.system(f"powerprofilesctl set power-saver") + profile = get_sysfs_content(profile_path) + print(profile) + # uncomment the following lines to set another mode for testing + # from switch_power_mode import set_power_profile + # set_power_profile("power-saver") if __name__ == "__main__": diff --git a/providers/base/tests/test_check_power_mode.py b/providers/base/tests/test_check_power_mode.py new file mode 100644 index 0000000000..033f2b45b2 --- /dev/null +++ b/providers/base/tests/test_check_power_mode.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +# Copyright 2024 Canonical Ltd. +# Written by: +# Bin Li +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 3, +# as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# pylint: disable=import-error + +""" A unittest module for the check_power_mode module. """ +import unittest +from unittest.mock import patch +import io + +from check_power_mode import main + + +class TestCheckPowerMode(unittest.TestCase): + """Tests for the check_power_mode module.""" + + @patch("sys.stdout", new_callable=io.StringIO) + @patch("check_power_mode.get_sysfs_content") + def test_main_success(self, mock_get_sysfs_content, mock_stdout): + """ + Tests successful execution of the main function. + """ + mock_get_sysfs_content.return_value = "balanced" + + # Call the main function + main() + + self.assertEqual(mock_stdout.getvalue(), "balanced\n") + + @patch("sys.stdout", new_callable=io.StringIO) + @patch("check_power_mode.get_sysfs_content") + def test_main_failure(self, mock_get_sysfs_content, mock_stdout): + """ + Tests failed execution of the main function. + """ + mock_get_sysfs_content.return_value = "" + + main() + + self.assertNotEqual(mock_stdout.getvalue(), "balanced\n") + + +if __name__ == "__main__": + unittest.main()