[neon/backports-jammy/power-profiles-daemon/Neon/unstable] /: 0.12-1 (patches unapplied)

git-ubuntu importer null at kde.org
Tue Sep 24 23:21:42 BST 2024


Git commit 4986fca855d8e356fe846e5ccd81cf591f2c793e by git-ubuntu importer, on behalf of Jeremy Bicha.
Committed on 14/08/2022 at 22:34.
Pushed by carlosdem into branch 'Neon/unstable'.

0.12-1 (patches unapplied)

Imported using git-ubuntu import.

M  +1    -1    .gitlab-ci.yml
M  +10   -0    NEWS
M  +16   -8    README.md
M  +8    -0    debian/changelog
A  +2    -0    debian/docs
M  +19   -3    meson.build
M  +4    -0    meson_options.txt
M  +1    -0    src/meson.build
M  +166  -32   src/ppd-driver-intel-pstate.c
M  +2    -0    src/ppd-driver.c
M  +3    -0    src/ppd-driver.h
M  +60   -11   tests/integration-test.py

https://invent.kde.org/neon/backports-jammy/power-profiles-daemon/-/commit/4986fca855d8e356fe846e5ccd81cf591f2c793e

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e0bd869..714a85c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -24,7 +24,7 @@ build_stable:
     - dnf update -y && dnf install -y $DEPENDENCIES
     - mkdir tmpdir/
   script:
-    - meson -Dgtk_doc=true -Dpylint=true _build
+    - meson -Dgtk_doc=true -Dpylint=true -Dtests=true _build
     - ninja -v -C _build
     - ninja -v -C _build install
     - ninja -v -C _build uninstall
diff --git a/NEWS b/NEWS
index b8488c0..8b75a65 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,13 @@
+0.12
+----
+
+This release adds support for the Intel "Energy Performance Bias" feature, which
+can be used on hardware that doesn't have a platform_profile or doesn't support
+HWP. It will also be used to eke out a bit more performance, or power, on systems
+which already supported HWP.
+
+More information is available in the README.
+
 0.11.1
 ------
 
diff --git a/README.md b/README.md
index 8684372..1093b19 100644
--- a/README.md
+++ b/README.md
@@ -101,13 +101,14 @@ Operations on Intel-based machines
 ----------------------------------
 
 The "driver" for making the hardware act on the user-selected power profile on Intel
-CPU-based machines is based on the [Intel P-State scaling driver](https://www.kernel.org/doc/html/v5.17/admin-guide/pm/intel_pstate.html).
+CPU-based machines is based on the [Intel P-State scaling driver](https://www.kernel.org/doc/html/v5.17/admin-guide/pm/intel_pstate.html)
+or the Energy Performance Bias (EPB) feature if available.
 
 It is only used if a `platform_profile` driver isn't available for the system, and the
-CPU supports hardware-managed P-states (HWP). If HWP isn't supported, or the P-State
-scaling driver is set to `passive` mode.
+CPU supports either hardware-managed P-states (HWP) or Energy Performance Bias (EPB).
 
-System without `platform_profile support` but with `active` P-State operation mode:
+Example of a system without `platform_profile support` but with `active` P-State
+operation mode:
 ```
 $ cat /sys/firmware/acpi/platform_profile_choices
 cat: /sys/firmware/acpi/platform_profile_choices: No such file or directory
@@ -115,16 +116,23 @@ $ cat /sys/devices/system/cpu/intel_pstate/status
 active
 ```
 
+Example of a system with `EPB` support:
+```
+$ cat /sys/devices/system/cpu/cpu0/power/energy_perf_bias
+0
+```
+
 If the Intel P-State scaling driver is in `passive` mode, either because the system doesn't
-support HWP, or the administator has disabled it, then the placeholder driver will be
-used, and there won't be a performance mode.
+support HWP, or the administator has disabled it, and `EPB` isn't available, then the
+placeholder driver will be used, and there won't be a performance mode.
 
 Finally, if the Intel P-State scaling driver is used in `active` mode, the P-State
 scaling governor will be changed to `powersave` as it is the only P-State scaling
 governor that allows for the "Energy vs Performance Hints" to be taken into consideration,
-ie. the only P-State scaling governor that allows power-profiles-daemon to work.
+ie. the only P-State scaling governor that allows HWP to work.
 
-For more information, please refer to the [Intel P-State scaling driver documentation](https://www.kernel.org/doc/html/v5.17/admin-guide/pm/intel_pstate.html).
+For more information, please refer to the [Intel P-State scaling driver documentation](https://www.kernel.org/doc/html/v5.17/admin-guide/pm/intel_pstate.html)
+and the [Intel Performance and Energy Bias Hint](https://www.kernel.org/doc/html/v5.17/admin-guide/pm/intel_epb.html).
 
 Testing
 -------
diff --git a/debian/changelog b/debian/changelog
index f144c32..534c710 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+power-profiles-daemon (0.12-1) unstable; urgency=medium
+
+  * Team upload
+  * New upstream release
+  * Add debian/docs to install NEWS and README.md
+
+ -- Jeremy Bicha <jbicha at ubuntu.com>  Sun, 14 Aug 2022 10:04:33 -0400
+
 power-profiles-daemon (0.11.1-1) unstable; urgency=medium
 
   * New upstream version
diff --git a/debian/docs b/debian/docs
new file mode 100644
index 0000000..8913f46
--- /dev/null
+++ b/debian/docs
@@ -0,0 +1,2 @@
+NEWS
+README.md
diff --git a/meson.build b/meson.build
index 165f5b0..7f31046 100644
--- a/meson.build
+++ b/meson.build
@@ -1,5 +1,5 @@
 project('power-profiles-daemon', [ 'c' ],
-        version: '0.11.1',
+        version: '0.12',
         license: 'GPLv3+',
         default_options: [
           'buildtype=debugoptimized',
@@ -23,7 +23,7 @@ common_cflags = cc.get_supported_arguments([
 prefix = get_option('prefix')
 libexecdir = prefix / get_option('libexecdir')
 bindir = get_option('bindir')
-dbusconfdir = get_option('sysconfdir') / 'dbus-1' / 'system.d'
+dbusconfdir = get_option('datadir') / 'dbus-1' / 'system.d'
 dbusservicedir = get_option('datadir') / 'dbus-1' / 'system-services'
 
 systemd_system_unit_dir = get_option('systemdsystemunitdir')
@@ -44,6 +44,7 @@ add_global_arguments(common_cflags, language: 'c')
 
 if get_option('pylint')
     pylint = find_program('pylint-3', 'pylint3', 'pylint', required: true)
+    nomalloc = environment({'MALLOC_PERTURB_': '0'})
     pylint_flags = ['-d', 'C0116', '-d', 'C0114', '-d', 'W0707', '-d', 'W0706' ]
 endif
 xmllint = find_program('xmllint', required: false)
@@ -61,7 +62,22 @@ if get_option('gtk_doc')
   subdir('docs')
 endif
 
-subdir('tests')
+if get_option('tests')
+  # Python 3 required modules
+  python3_required_modules = ['dbusmock', 'gi']
+
+  python = import('python')
+  python3 = python.find_installation('python3')
+  foreach p : python3_required_modules
+    # Source: https://docs.python.org/3/library/importlib.html#checking-if-a-module-can-be-imported
+    script = 'import importlib.util; import sys; exit(1) if importlib.util.find_spec(\''+ p +'\') is None else exit(0)'
+    if run_command(python3, '-c', script, check: false).returncode() != 0
+      error('Python3 module \'' + p + '\' required for running tests but not found')
+    endif
+  endforeach
+
+  subdir('tests')
+endif
 
 meson.add_dist_script(
   find_program('check-news.sh').path(),
diff --git a/meson_options.txt b/meson_options.txt
index 7e89619..307bc6a 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -10,3 +10,7 @@ option('pylint',
        type: 'boolean',
        value: false,
        description: 'Run pylint checks, for developers only')
+option('tests',
+       description: 'Whether to run tests',
+       type: 'boolean',
+       value: false)
diff --git a/src/meson.build b/src/meson.build
index f20e42a..2094079 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -76,5 +76,6 @@ if get_option('pylint')
   test('pylint-powerprofilesctl',
        pylint,
        args: pylint_flags + [ script ],
+       env: nomalloc,
        )
 endif
diff --git a/src/ppd-driver-intel-pstate.c b/src/ppd-driver-intel-pstate.c
index 5939d77..17b6af4 100644
--- a/src/ppd-driver-intel-pstate.c
+++ b/src/ppd-driver-intel-pstate.c
@@ -12,18 +12,25 @@
 #include "ppd-utils.h"
 #include "ppd-driver-intel-pstate.h"
 
+#define CPU_DIR "/sys/devices/system/cpu/"
 #define CPUFREQ_POLICY_DIR "/sys/devices/system/cpu/cpufreq/"
 #define DEFAULT_CPU_FREQ_SCALING_GOV "powersave"
 #define PSTATE_STATUS_PATH "/sys/devices/system/cpu/intel_pstate/status"
 #define NO_TURBO_PATH "/sys/devices/system/cpu/intel_pstate/no_turbo"
 #define TURBO_PCT_PATH "/sys/devices/system/cpu/intel_pstate/turbo_pct"
 
+#define SYSTEMD_DBUS_NAME                       "org.freedesktop.login1"
+#define SYSTEMD_DBUS_PATH                       "/org/freedesktop/login1"
+#define SYSTEMD_DBUS_INTERFACE                  "org.freedesktop.login1.Manager"
+
 struct _PpdDriverIntelPstate
 {
   PpdDriver  parent_instance;
 
   PpdProfile activated_profile;
-  GList *devices; /* GList of paths */
+  GList *epp_devices; /* GList of paths */
+  GList *epb_devices; /* GList of paths */
+  GDBusProxy *logind_proxy;
   GFileMonitor *no_turbo_mon;
   char *no_turbo_path;
 };
@@ -100,15 +107,6 @@ monitor_no_turbo_prop (const char *path)
   return g_file_monitor (no_turbo, G_FILE_MONITOR_NONE, NULL, NULL);
 }
 
-static GDir *
-open_policy_dir (void)
-{
-  g_autofree char *dir = NULL;
-  dir = ppd_utils_get_sysfs_path (CPUFREQ_POLICY_DIR);
-  g_debug ("Opening policy dir '%s'", dir);
-  return g_dir_open (dir, 0, NULL);
-}
-
 static gboolean
 has_turbo (void)
 {
@@ -126,10 +124,90 @@ has_turbo (void)
   return has_turbo;
 }
 
-static gboolean
-ppd_driver_intel_pstate_probe (PpdDriver  *driver)
+static void
+logind_proxy_signal_cb (GDBusProxy  *proxy,
+                        const char  *sender_name,
+                        const char  *signal_name,
+                        GVariant    *parameters,
+                        gpointer     user_data)
+{
+  PpdDriverIntelPstate *pstate = user_data;
+  g_autoptr(GError) error = NULL;
+  gboolean start;
+  PpdProbeResult ret;
+
+  if (g_strcmp0 (signal_name, "PrepareForSleep") != 0)
+    return;
+  g_variant_get (parameters, "(b)", &start);
+  if (start)
+    return;
+
+  g_debug ("System woke up from suspend, re-applying energy_perf_bias");
+  ret = ppd_driver_intel_pstate_activate_profile (PPD_DRIVER (pstate),
+                                                  pstate->activated_profile,
+                                                  PPD_PROFILE_ACTIVATION_REASON_RESUME,
+                                                  &error);
+  if (ret != PPD_PROBE_RESULT_SUCCESS) {
+    g_warning ("Could not reapply energy_perf_bias preference on resume: %s",
+               error->message);
+  }
+}
+
+static PpdProbeResult
+probe_epb (PpdDriverIntelPstate *pstate)
+{
+  g_autoptr(GDir) dir = NULL;
+  g_autofree char *policy_dir = NULL;
+  const char *dirname;
+  g_autoptr(GError) error = NULL;
+  PpdProbeResult ret = PPD_PROBE_RESULT_FAIL;
+
+  policy_dir = ppd_utils_get_sysfs_path (CPU_DIR);
+  dir = g_dir_open (policy_dir, 0, NULL);
+  if (!dir) {
+    g_debug ("Could not open %s", CPU_DIR);
+    return ret;
+  }
+
+  while ((dirname = g_dir_read_name (dir)) != NULL) {
+    g_autofree char *path = NULL;
+    g_autofree char *gov_path = NULL;
+
+    path = g_build_filename (policy_dir,
+                             dirname,
+                             "power",
+                             "energy_perf_bias",
+                             NULL);
+    if (!g_file_test (path, G_FILE_TEST_EXISTS))
+      continue;
+
+    pstate->epb_devices = g_list_prepend (pstate->epb_devices, g_steal_pointer (&path));
+    ret = PPD_PROBE_RESULT_SUCCESS;
+  }
+
+  pstate->logind_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+                                                        0,
+                                                        NULL,
+                                                        SYSTEMD_DBUS_NAME,
+                                                        SYSTEMD_DBUS_PATH,
+                                                        SYSTEMD_DBUS_INTERFACE,
+                                                        NULL,
+                                                        &error);
+  if (!pstate->logind_proxy) {
+    g_debug ("Could not create proxy for logind: %s",
+             error->message);
+  } else {
+    g_signal_connect (pstate->logind_proxy, "g-signal",
+                      G_CALLBACK (logind_proxy_signal_cb),
+                      pstate);
+  }
+
+  return ret;
+}
+
+static PpdProbeResult
+probe_epp (PpdDriverIntelPstate *pstate)
 {
-  PpdDriverIntelPstate *pstate = PPD_DRIVER_INTEL_PSTATE (driver);
   g_autoptr(GDir) dir = NULL;
   g_autofree char *policy_dir = NULL;
   g_autofree char *pstate_status_path = NULL;
@@ -140,18 +218,20 @@ ppd_driver_intel_pstate_probe (PpdDriver  *driver)
   /* Verify that Intel P-State is running in active mode */
   pstate_status_path = ppd_utils_get_sysfs_path (PSTATE_STATUS_PATH);
   if (!g_file_get_contents (pstate_status_path, &status, NULL, NULL))
-    goto out;
+    return ret;
   status = g_strchomp (status);
   if (g_strcmp0 (status, "active") != 0) {
     g_debug ("Intel P-State is running in passive mode");
-    goto out;
+    return ret;
   }
 
-  dir = open_policy_dir ();
-  if (!dir)
-    goto out;
-
   policy_dir = ppd_utils_get_sysfs_path (CPUFREQ_POLICY_DIR);
+  dir = g_dir_open (policy_dir, 0, NULL);
+  if (!dir) {
+    g_debug ("Could not open %s", policy_dir);
+    return ret;
+  }
+
   while ((dirname = g_dir_read_name (dir)) != NULL) {
     g_autofree char *path = NULL;
     g_autofree char *gov_path = NULL;
@@ -174,10 +254,25 @@ ppd_driver_intel_pstate_probe (PpdDriver  *driver)
       continue;
     }
 
-    pstate->devices = g_list_prepend (pstate->devices, g_steal_pointer (&path));
+    pstate->epp_devices = g_list_prepend (pstate->epp_devices, g_steal_pointer (&path));
     ret = PPD_PROBE_RESULT_SUCCESS;
   }
 
+  return ret;
+}
+
+static PpdProbeResult
+ppd_driver_intel_pstate_probe (PpdDriver  *driver)
+{
+  PpdDriverIntelPstate *pstate = PPD_DRIVER_INTEL_PSTATE (driver);
+  PpdProbeResult ret = PPD_PROBE_RESULT_FAIL;
+
+  ret = probe_epp (pstate);
+  if (ret == PPD_PROBE_RESULT_SUCCESS)
+    probe_epb (pstate);
+  else
+    ret = probe_epb (pstate);
+
   if (ret != PPD_PROBE_RESULT_SUCCESS)
     goto out;
 
@@ -199,7 +294,7 @@ out:
 }
 
 static const char *
-profile_to_pref (PpdProfile profile)
+profile_to_epp_pref (PpdProfile profile)
 {
   /* Note that we don't check "energy_performance_available_preferences"
    * as all the values are always available */
@@ -215,6 +310,42 @@ profile_to_pref (PpdProfile profile)
   g_assert_not_reached ();
 }
 
+static const char *
+profile_to_epb_pref (PpdProfile profile)
+{
+  /* From arch/x86/include/asm/msr-index.h
+   * See ENERGY_PERF_BIAS_* */
+  switch (profile) {
+  case PPD_PROFILE_POWER_SAVER:
+    return "15";
+  case PPD_PROFILE_BALANCED:
+    return "6";
+  case PPD_PROFILE_PERFORMANCE:
+    return "0";
+  }
+
+  g_assert_not_reached ();
+}
+
+static gboolean
+apply_pref_to_devices (GList       *devices,
+                       const char  *pref,
+                       GError     **error)
+{
+  gboolean ret = TRUE;
+  GList *l;
+
+  for (l = devices; l != NULL; l = l->next) {
+    const char *path = l->data;
+
+    ret = ppd_utils_write (path, pref, error);
+    if (!ret)
+      break;
+  }
+
+  return ret;
+}
+
 static gboolean
 ppd_driver_intel_pstate_activate_profile (PpdDriver                    *driver,
                                           PpdProfile                   profile,
@@ -222,20 +353,21 @@ ppd_driver_intel_pstate_activate_profile (PpdDriver                    *driver,
                                           GError                     **error)
 {
   PpdDriverIntelPstate *pstate = PPD_DRIVER_INTEL_PSTATE (driver);
-  gboolean ret = TRUE;
+  gboolean ret = FALSE;
   const char *pref;
-  GList *l;
-
-  g_return_val_if_fail (pstate->devices != NULL, FALSE);
 
-  pref = profile_to_pref (profile);
+  g_return_val_if_fail (pstate->epp_devices != NULL ||
+                        pstate->epb_devices, FALSE);
 
-  for (l = pstate->devices; l != NULL; l = l->next) {
-    const char *path = l->data;
-
-    ret = ppd_utils_write (path, pref, error);
+  if (pstate->epp_devices) {
+    pref = profile_to_epp_pref (profile);
+    ret = apply_pref_to_devices (pstate->epp_devices, pref, error);
     if (!ret)
-      break;
+      return ret;
+  }
+  if (pstate->epb_devices) {
+    pref = profile_to_epb_pref (profile);
+    ret = apply_pref_to_devices (pstate->epb_devices, pref, error);
   }
 
   if (ret)
@@ -250,9 +382,11 @@ ppd_driver_intel_pstate_finalize (GObject *object)
   PpdDriverIntelPstate *driver;
 
   driver = PPD_DRIVER_INTEL_PSTATE (object);
-  g_clear_list (&driver->devices, g_free);
+  g_clear_list (&driver->epp_devices, g_free);
+  g_clear_list (&driver->epb_devices, g_free);
   g_clear_pointer (&driver->no_turbo_path, g_free);
   g_clear_object (&driver->no_turbo_mon);
+  g_clear_object (&driver->logind_proxy);
   G_OBJECT_CLASS (ppd_driver_intel_pstate_parent_class)->finalize (object);
 }
 
diff --git a/src/ppd-driver.c b/src/ppd-driver.c
index 93abb34..9a1f369 100644
--- a/src/ppd-driver.c
+++ b/src/ppd-driver.c
@@ -315,6 +315,8 @@ ppd_profile_activation_reason_to_str (PpdProfileActivationReason reason)
     return "reset";
   case PPD_PROFILE_ACTIVATION_REASON_USER:
     return "user";
+  case PPD_PROFILE_ACTIVATION_REASON_RESUME:
+    return "resume";
   case PPD_PROFILE_ACTIVATION_REASON_PROGRAM_HOLD:
     return "program-hold";
   default:
diff --git a/src/ppd-driver.h b/src/ppd-driver.h
index 16977b5..f1e0f63 100644
--- a/src/ppd-driver.h
+++ b/src/ppd-driver.h
@@ -41,6 +41,8 @@ typedef enum {
  *   because drivers are getting reprobed.
  * @PPD_PROFILE_ACTIVATION_REASON_USER: setting profile because the user
  *   requested it.
+ * @PPD_PROFILE_ACTIVATION_REASON_RESUME: setting profile because preference
+ *   is lost during suspend.
  * @PPD_PROFILE_ACTIVATION_REASON_PROGRAM_HOLD: setting profile because a program
  *   requested it through the `HoldProfile` method.
  *
@@ -52,6 +54,7 @@ typedef enum{
   PPD_PROFILE_ACTIVATION_REASON_INTERNAL = 0,
   PPD_PROFILE_ACTIVATION_REASON_RESET,
   PPD_PROFILE_ACTIVATION_REASON_USER,
+  PPD_PROFILE_ACTIVATION_REASON_RESUME,
   PPD_PROFILE_ACTIVATION_REASON_PROGRAM_HOLD
 } PpdProfileActivationReason;
 
diff --git a/tests/integration-test.py b/tests/integration-test.py
index 2dd3677..77e05c0 100755
--- a/tests/integration-test.py
+++ b/tests/integration-test.py
@@ -116,6 +116,14 @@ class Tests(dbusmock.DBusTestCase):
         # Used for dytc devices
         self.tp_acpi = None
 
+    def run(self, result=None):
+        super(Tests, self).run(result)
+        if result and len(result.errors) + len(result.failures) > 0 and self.log:
+            with open(self.log.name) as f:
+                sys.stderr.write('\n-------------- daemon log: ----------------\n')
+                sys.stderr.write(f.read())
+                sys.stderr.write('------------------------------\n')
+
     def tearDown(self):
         del self.testbed
         self.stop_daemon()
@@ -131,17 +139,9 @@ class Tests(dbusmock.DBusTestCase):
 
         del self.tp_acpi
         try:
-          os.remove(self.testbed.get_root_dir() + '/' + 'ppd_test_conf.ini')
+            os.remove(self.testbed.get_root_dir() + '/' + 'ppd_test_conf.ini')
         except Exception:
-          pass
-
-        # on failures, print daemon log
-        errors = [x[1] for x in self._outcome.errors if x[1]]
-        if errors and self.log:
-            with open(self.log.name) as f:
-                sys.stderr.write('\n-------------- daemon log: ----------------\n')
-                sys.stderr.write(f.read())
-                sys.stderr.write('------------------------------\n')
+            pass
 
     #
     # Daemon control and D-BUS I/O
@@ -509,7 +509,7 @@ class Tests(dbusmock.DBusTestCase):
         subprocess.check_output(['chattr', '-i', pref_path])
 
     def test_intel_pstate_passive(self):
-      '''Intel P-State in passive mode -> pladeholder'''
+      '''Intel P-State in passive mode -> placeholder'''
 
       dir1 = os.path.join(self.testbed.get_root_dir(), "sys/devices/system/cpu/cpufreq/policy0/")
       os.makedirs(dir1)
@@ -549,6 +549,55 @@ class Tests(dbusmock.DBusTestCase):
 
       self.stop_daemon()
 
+    def test_intel_pstate_passive_with_epb(self):
+      '''Intel P-State in passive mode (no HWP) with energy_perf_bias'''
+
+      dir1 = os.path.join(self.testbed.get_root_dir(), "sys/devices/system/cpu/cpufreq/policy0/")
+      os.makedirs(dir1)
+      with open(os.path.join(dir1, 'scaling_governor'), 'w') as gov:
+        gov.write('powersave\n')
+      with open(os.path.join(dir1, "energy_performance_preference"),'w') as prefs:
+        prefs.write("performance\n")
+      dir2 = os.path.join(self.testbed.get_root_dir(), "sys/devices/system/cpu/cpu0/power/")
+      os.makedirs(dir2)
+      with open(os.path.join(dir2, 'energy_perf_bias'), 'w') as epb:
+        epb.write("6")
+
+      # Create Intel P-State configuration
+      pstate_dir = os.path.join(self.testbed.get_root_dir(), "sys/devices/system/cpu/intel_pstate")
+      os.makedirs(pstate_dir)
+      with open(os.path.join(pstate_dir, "no_turbo"),'w') as no_turbo:
+        no_turbo.write("0\n")
+      with open(os.path.join(pstate_dir, "status"),'w') as status:
+        status.write("passive\n")
+
+      self.start_daemon()
+
+      profiles = self.get_dbus_property('Profiles')
+      self.assertEqual(len(profiles), 3)
+      self.assertEqual(profiles[0]['Driver'], 'intel_pstate')
+      self.assertEqual(self.get_dbus_property('ActiveProfile'), 'balanced')
+
+      # Set power-saver mode
+      self.set_dbus_property('ActiveProfile', GLib.Variant.new_string('power-saver'))
+      self.assertEqual(self.get_dbus_property('ActiveProfile'), 'power-saver')
+
+      contents = None
+      with open(os.path.join(dir2, "energy_perf_bias"), 'rb') as f:
+        contents = f.read()
+      self.assertEqual(contents, b'15')
+
+      # Set performance mode
+      self.set_dbus_property('ActiveProfile', GLib.Variant.new_string('performance'))
+      self.assertEqual(self.get_dbus_property('ActiveProfile'), 'performance')
+
+      contents = None
+      with open(os.path.join(dir2, "energy_perf_bias"), 'rb') as f:
+        contents = f.read()
+      self.assertEqual(contents, b'0')
+
+      self.stop_daemon()
+
     def test_dytc_performance_driver(self):
       '''Lenovo DYTC performance driver'''
 



More information about the Neon-commits mailing list