Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package power-profiles-daemon for 
openSUSE:Factory checked in at 2022-05-02 16:25:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/power-profiles-daemon (Old)
 and      /work/SRC/openSUSE:Factory/.power-profiles-daemon.new.1538 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "power-profiles-daemon"

Mon May  2 16:25:37 2022 rev:4 rq:974300 version:0.11

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/power-profiles-daemon/power-profiles-daemon.changes  
    2021-11-21 23:52:36.782169577 +0100
+++ 
/work/SRC/openSUSE:Factory/.power-profiles-daemon.new.1538/power-profiles-daemon.changes
    2022-05-02 16:25:43.820848934 +0200
@@ -1,0 +2,14 @@
+Sun May  1 17:32:18 UTC 2022 - Atri Bhattacharya <[email protected]>
+
+- Update to version 0.11:
+  * Fixes problems on Intel machines when the CPUs didn't support
+    turbo at all, or the performance scaling governor was built as
+    default in the kernel.
+  * Add better end-user documentation.
+  * Fixes in the command-line tool to not cause bug report tools
+    to popup on not-uncommon errors.
+  * Bug fix for running on some systems with controllable charge
+    speeds.
+- Drop fd1664dfe26f13f8c8cd7b44483cd872dfdede36.patch: upstreamed.
+
+-------------------------------------------------------------------

Old:
----
  fd1664dfe26f13f8c8cd7b44483cd872dfdede36.patch
  power-profiles-daemon-0.10.1.tar.bz2

New:
----
  power-profiles-daemon-0.11.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ power-profiles-daemon.spec ++++++
--- /var/tmp/diff_new_pack.mz6KJJ/_old  2022-05-02 16:25:44.344849516 +0200
+++ /var/tmp/diff_new_pack.mz6KJJ/_new  2022-05-02 16:25:44.348849521 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package power-profiles-daemon
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           power-profiles-daemon
-Version:        0.10.1
+Version:        0.11
 Release:        0
 Summary:        Power profiles handling over D-Bus
 License:        GPL-3.0-or-later
@@ -25,8 +25,6 @@
 Source:         %{url}/-/archive/%{version}/%{name}-%{version}.tar.bz2
 # PATCH-FEATURE-OPENSUSE hold-profile-hardening.patch boo#1189900 -- Hardening 
of HoldProfile D-Bus method
 Patch0:         hold-profile-hardening.patch
-# PATCH-FIX-UPSTREAM fd1664dfe26f13f8c8cd7b44483cd872dfdede36.patch -- main: 
Error out on D-Bus communication errors
-Patch1:         
https://gitlab.freedesktop.org/hadess/power-profiles-daemon/-/commit/fd1664dfe26f13f8c8cd7b44483cd872dfdede36.patch
 
 BuildRequires:  c_compiler
 BuildRequires:  gtk-doc

++++++ hold-profile-hardening.patch ++++++
--- /var/tmp/diff_new_pack.mz6KJJ/_old  2022-05-02 16:25:44.372849547 +0200
+++ /var/tmp/diff_new_pack.mz6KJJ/_new  2022-05-02 16:25:44.376849552 +0200
@@ -1,8 +1,8 @@
-Index: power-profiles-daemon-0.10.1/src/power-profiles-daemon.c
+Index: power-profiles-daemon-0.11/src/power-profiles-daemon.c
 ===================================================================
---- power-profiles-daemon-0.10.1.orig/src/power-profiles-daemon.c
-+++ power-profiles-daemon-0.10.1/src/power-profiles-daemon.c
-@@ -531,6 +531,29 @@ holder_disappeared (GDBusConnection *con
+--- power-profiles-daemon-0.11.orig/src/power-profiles-daemon.c
++++ power-profiles-daemon-0.11/src/power-profiles-daemon.c
+@@ -537,6 +537,29 @@ holder_disappeared (GDBusConnection *con
    g_ptr_array_free (cookies, TRUE);
  }
  
@@ -32,7 +32,7 @@
  static void
  hold_profile (PpdApp                *data,
                GVariant              *parameters,
-@@ -553,6 +576,18 @@ hold_profile (PpdApp                *dat
+@@ -559,6 +582,18 @@ hold_profile (PpdApp                *dat
      return;
    }
  

++++++ power-profiles-daemon-0.10.1.tar.bz2 -> 
power-profiles-daemon-0.11.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/power-profiles-daemon-0.10.1/.ci/fail_skipped_tests.py 
new/power-profiles-daemon-0.11/.ci/fail_skipped_tests.py
--- old/power-profiles-daemon-0.10.1/.ci/fail_skipped_tests.py  1970-01-01 
01:00:00.000000000 +0100
+++ new/power-profiles-daemon-0.11/.ci/fail_skipped_tests.py    2022-04-29 
14:29:31.000000000 +0200
@@ -0,0 +1,25 @@
+#!/usr/bin/python3
+
+from lxml import etree
+import sys
+
+def format_title(title):
+    """Put title in a box"""
+    box = {
+        'tl': '???', 'tr': '???', 'bl': '???', 'br': '???', 'h': '???', 'v': 
'???',
+    }
+    hline = box['h'] * (len(title) + 2)
+
+    return '\n'.join([
+        f"{box['tl']}{hline}{box['tr']}",
+        f"{box['v']} {title} {box['v']}",
+        f"{box['bl']}{hline}{box['br']}",
+    ])
+
+tree = etree.parse(sys.argv[1])
+for suite in tree.xpath('/testsuites/testsuite'):
+    skipped = suite.get('skipped')
+    if int(skipped) != 0:
+        print(format_title('Tests were skipped when they should not have been. 
All the tests must be run in the CI'),
+                end='\n\n', flush=True)
+        sys.exit(1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/power-profiles-daemon-0.10.1/.gitlab-ci.yml 
new/power-profiles-daemon-0.11/.gitlab-ci.yml
--- old/power-profiles-daemon-0.10.1/.gitlab-ci.yml     2021-10-28 
11:25:13.000000000 +0200
+++ new/power-profiles-daemon-0.11/.gitlab-ci.yml       2022-04-29 
14:29:31.000000000 +0200
@@ -16,18 +16,21 @@
                 python3-dbusmock
                 python3-pylint
                 umockdev
+                e2fsprogs
 
 build_stable:
   before_script:
     - dnf upgrade -y --nogpgcheck fedora-release fedora-repos*
     - dnf update -y && dnf install -y $DEPENDENCIES
+    - mkdir tmpdir/
   script:
     - meson -Dgtk_doc=true -Dpylint=true _build
     - ninja -v -C _build
     - ninja -v -C _build install
     - ninja -v -C _build uninstall
-    - ninja -v -C _build dist
-    - meson test -C _build
+    - TMPDIR=$(pwd)/tmpdir meson test -C _build
+    - .ci/fail_skipped_tests.py _build/meson-logs/testlog.junit.xml
+    - TMPDIR=$(pwd)/tmpdir ninja -v -C _build dist
   artifacts:
     when: always
     paths:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/power-profiles-daemon-0.10.1/NEWS 
new/power-profiles-daemon-0.11/NEWS
--- old/power-profiles-daemon-0.10.1/NEWS       2021-10-28 11:25:13.000000000 
+0200
+++ new/power-profiles-daemon-0.11/NEWS 2022-04-29 14:29:31.000000000 +0200
@@ -1,3 +1,13 @@
+0.11
+----
+
+This release fixes problems on Intel machines when the CPUs didn't support 
turbo at
+all, or the performance scaling governor was built as default in the kernel.
+
+It also adds better end-user documentation, fixes in the command-line tool to 
not
+cause bug report tools to popup on not-uncommon errors, and a bug fix for 
running
+on some systems with controllable charge speeds.
+
 0.10.1
 ------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/power-profiles-daemon-0.10.1/README.md 
new/power-profiles-daemon-0.11/README.md
--- old/power-profiles-daemon-0.10.1/README.md  2021-10-28 11:25:13.000000000 
+0200
+++ new/power-profiles-daemon-0.11/README.md    2022-04-29 14:29:31.000000000 
+0200
@@ -30,6 +30,41 @@
 such as turning the screen off after inaction more aggressively when in 
power-saver
 mode.
 
+How to use
+----------
+
+There are interfaces to switch profiles in the latest versions of KDE and 
GNOME. Those
+desktops also include more thorough integration with its low-power mode. 
Please check
+the user guides for each of them for details.
+
+power-profiles-daemon also ships with a command-line utility called 
`powerprofilesctl`
+which can be used for scripting, as it allows getting and setting the active 
profile,
+listing the available profiles, and launching commands while holding the 
performance
+or the power-saver profile.
+
+For example, this will be useful to avoid manual switching profiles while 
compiling
+large projects:
+```sh
+powerprofilesctl launch make
+```
+
+If you're a developer, you might also want to use GLib's 
[`GPowerProfileMonitor`](https://docs.gtk.org/gio/iface.PowerProfileMonitor.html)
+through C, or one of its bindings, so your application can react to the user 
requesting
+a low-power mode.
+
+Conflicts
+---------
+
+If `power-profiles-daemon` refuses to start, it's likely that you have [a 
conflicting
+service installed and running](data/power-profiles-daemon.service.in#L3), or 
your
+distribution ships [a version of tlp that actively breaks 
power-profiles-daemon](https://bugzilla.redhat.com/show_bug.cgi?id=2028701#c11),
+or you use the [upstream 
package](https://github.com/linrunner/TLP/commit/6a9388e1af95051a90a33b4014af1158dfa241f6).
+
+```sh
+systemctl unmask power-profiles-daemon.service
+systemctl start power-profiles-daemon.service
+```
+
 Debugging
 ---------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/power-profiles-daemon-0.10.1/meson.build 
new/power-profiles-daemon-0.11/meson.build
--- old/power-profiles-daemon-0.10.1/meson.build        2021-10-28 
11:25:13.000000000 +0200
+++ new/power-profiles-daemon-0.11/meson.build  2022-04-29 14:29:31.000000000 
+0200
@@ -1,5 +1,5 @@
 project('power-profiles-daemon', [ 'c' ],
-        version: '0.10.1',
+        version: '0.11',
         license: 'GPLv3+',
         default_options: [
           'buildtype=debugoptimized',
@@ -34,7 +34,7 @@
 gio_dep = dependency('gio-2.0')
 gudev_dep = dependency('gudev-1.0', version: '>= 234')
 upower_dep = dependency('upower-glib')
-polkit_gobject_dep = dependency('polkit-gobject-1', version: '>= 0.91')
+polkit_gobject_dep = dependency('polkit-gobject-1', version: '>= 0.114')
 polkit_policy_directory = 
polkit_gobject_dep.get_pkgconfig_variable('policydir')
 
 gnome = import('gnome')
@@ -44,7 +44,7 @@
 
 if get_option('pylint')
     pylint = find_program('pylint-3', 'pylint3', 'pylint', required: true)
-    pylint_flags = ['-d', 'C0116', '-d', 'C0114', '-d', 'W0707']
+    pylint_flags = ['-d', 'C0116', '-d', 'C0114', '-d', 'W0707', '-d', 'W0706' 
]
 endif
 xmllint = find_program('xmllint', required: false)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/power-profiles-daemon-0.10.1/src/power-profiles-daemon.c 
new/power-profiles-daemon-0.11/src/power-profiles-daemon.c
--- old/power-profiles-daemon-0.10.1/src/power-profiles-daemon.c        
2021-10-28 11:25:13.000000000 +0200
+++ new/power-profiles-daemon-0.11/src/power-profiles-daemon.c  2022-04-29 
14:29:31.000000000 +0200
@@ -321,22 +321,25 @@
   }
 }
 
-static void
-activate_target_profile (PpdApp                     *data,
-                         PpdProfile                  target_profile,
-                         PpdProfileActivationReason  reason)
+static gboolean
+activate_target_profile (PpdApp                      *data,
+                         PpdProfile                   target_profile,
+                         PpdProfileActivationReason   reason,
+                         GError                     **error)
 {
-  g_autoptr(GError) error = NULL;
+  GError *internal_error = NULL;
 
   g_debug ("Setting active profile '%s' for reason '%s' (current: '%s')",
            ppd_profile_to_str (target_profile),
            ppd_profile_activation_reason_to_str (reason),
            ppd_profile_to_str (data->active_profile));
 
-  if (!ppd_driver_activate_profile (data->driver, target_profile, reason, 
&error)) {
+  if (!ppd_driver_activate_profile (data->driver, target_profile, reason, 
&internal_error)) {
     g_warning ("Failed to activate driver '%s': %s",
                ppd_driver_get_driver_name (data->driver),
-               error->message);
+               internal_error->message);
+    g_propagate_error (error, internal_error);
+    return FALSE;
   }
 
   actions_activate_profile (data->actions, target_profile);
@@ -346,6 +349,8 @@
   if (reason == PPD_PROFILE_ACTIVATION_REASON_USER ||
       reason == PPD_PROFILE_ACTIVATION_REASON_INTERNAL)
     save_configuration (data);
+
+  return TRUE;
 }
 
 static void
@@ -394,7 +399,8 @@
     mask |= PROP_ACTIVE_PROFILE_HOLDS;
   }
 
-  activate_target_profile (data, target_profile, 
PPD_PROFILE_ACTIVATION_REASON_USER);
+  if (!activate_target_profile (data, target_profile, 
PPD_PROFILE_ACTIVATION_REASON_USER, error))
+    return FALSE;
   data->selected_profile = target_profile;
   send_dbus_event (data, mask);
 
@@ -459,7 +465,7 @@
   if (new_profile == data->active_profile)
     return;
 
-  activate_target_profile (data, new_profile, 
PPD_PROFILE_ACTIVATION_REASON_INTERNAL);
+  activate_target_profile (data, new_profile, 
PPD_PROFILE_ACTIVATION_REASON_INTERNAL, NULL);
   send_dbus_event (data, PROP_ACTIVE_PROFILE);
 }
 
@@ -484,14 +490,14 @@
   if (g_hash_table_size (data->profile_holds) == 0 &&
       hold_profile != data->selected_profile) {
     g_debug ("No profile holds anymore going back to last manually activated 
profile");
-    activate_target_profile (data, data->selected_profile, 
PPD_PROFILE_ACTIVATION_REASON_PROGRAM_HOLD);
+    activate_target_profile (data, data->selected_profile, 
PPD_PROFILE_ACTIVATION_REASON_PROGRAM_HOLD, NULL);
     mask |= PROP_ACTIVE_PROFILE;
   } else if (hold_profile == data->active_profile) {
     next_profile = effective_hold_profile (data);
     if (next_profile != PPD_PROFILE_UNSET &&
         next_profile != data->active_profile) {
       g_debug ("Next profile is %s", ppd_profile_to_str (next_profile));
-      activate_target_profile (data, next_profile, 
PPD_PROFILE_ACTIVATION_REASON_PROGRAM_HOLD);
+      activate_target_profile (data, next_profile, 
PPD_PROFILE_ACTIVATION_REASON_PROGRAM_HOLD, NULL);
       mask |= PROP_ACTIVE_PROFILE;
     }
   }
@@ -572,7 +578,7 @@
     PpdProfile target_profile = effective_hold_profile (data);
     if (target_profile != PPD_PROFILE_UNSET &&
         target_profile != data->active_profile) {
-      activate_target_profile (data, target_profile, 
PPD_PROFILE_ACTIVATION_REASON_PROGRAM_HOLD);
+      activate_target_profile (data, target_profile, 
PPD_PROFILE_ACTIVATION_REASON_PROGRAM_HOLD, NULL);
       mask |= PROP_ACTIVE_PROFILE;
     }
   }
@@ -867,7 +873,7 @@
 
   /* Set initial state either from configuration, or using the currently 
selected profile */
   apply_configuration (data);
-  activate_target_profile (data, data->active_profile, 
PPD_PROFILE_ACTIVATION_REASON_RESET);
+  activate_target_profile (data, data->active_profile, 
PPD_PROFILE_ACTIVATION_REASON_RESET, NULL);
 
   send_dbus_event (data, PROP_ALL);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/power-profiles-daemon-0.10.1/src/powerprofilesctl.in 
new/power-profiles-daemon-0.11/src/powerprofilesctl.in
--- old/power-profiles-daemon-0.10.1/src/powerprofilesctl.in    2021-10-28 
11:25:13.000000000 +0200
+++ new/power-profiles-daemon-0.11/src/powerprofilesctl.in      2022-04-29 
14:29:31.000000000 +0200
@@ -98,7 +98,7 @@
                                        '/net/hadess/PowerProfiles',
                                        'org.freedesktop.DBus.Properties', None)
     except:
-        raise SystemError
+        raise
     return proxy
 
 def _get():
@@ -107,23 +107,26 @@
     print(profile)
 
 def _set(profile):
-    proxy = get_proxy()
-    proxy.Set('(ssv)',
-        'net.hadess.PowerProfiles',
-        'ActiveProfile',
-        GLib.Variant.new_string(profile))
+    try:
+        proxy = get_proxy()
+        proxy.Set('(ssv)',
+            'net.hadess.PowerProfiles',
+            'ActiveProfile',
+            GLib.Variant.new_string(profile))
+    except:
+        raise
 
 def get_profiles_property(prop):
     try:
         proxy = get_proxy()
     except:
-        raise SystemError
+        raise
 
     profiles = None
     try:
         profiles = proxy.Get('(ss)', 'net.hadess.PowerProfiles', prop)
     except:
-        raise ReferenceError
+        raise
     else:
         return profiles
 
@@ -134,8 +137,7 @@
         degraded = (reason != '')
         active = get_proxy().Get('(ss)', 'net.hadess.PowerProfiles', 
'ActiveProfile')
     except:
-        print("Couldn\'t get Profiles: ", sys.exc_info()[0])
-        raise SystemError
+        raise
     else:
         index = 0
         for profile in reversed(profiles):
@@ -152,8 +154,7 @@
     try:
         holds = get_profiles_property('ActiveProfileHolds')
     except:
-        # print("Couldn\'t get ActiveProfileHolds: ", sys.exc_info()[0])
-        raise SystemError
+        raise
     else:
         index = 0
         for hold in holds:
@@ -173,7 +174,7 @@
                                        '/net/hadess/PowerProfiles',
                                        'net.hadess.PowerProfiles', None)
     except:
-        raise SystemError
+        raise
 
     cookie = proxy.HoldProfile('(sss)', profile, reason, appid)
 
@@ -208,16 +209,32 @@
     elif command == 'version':
         version()
     elif command == 'get':
-        _get()
+        try:
+            _get()
+        except GLib.Error as error:
+            sys.stderr.write(f'Failed to communicate with 
power-profiles-daemon: {format(error)}\n')
+            sys.exit(1)
     elif command == 'set':
         if len(args) != 1:
             usage_set()
             sys.exit(1)
-        _set(args[0])
+        try:
+            _set(args[0])
+        except GLib.Error as error:
+            sys.stderr.write(f'Failed to communicate with 
power-profiles-daemon: {format(error)}\n')
+            sys.exit(1)
     elif command == 'list':
-        _list()
+        try:
+            _list()
+        except GLib.Error as error:
+            sys.stderr.write(f'Failed to communicate with 
power-profiles-daemon: {format(error)}\n')
+            sys.exit(1)
     elif command == 'list-holds':
-        _list_holds()
+        try:
+            _list_holds()
+        except GLib.Error as error:
+            sys.stderr.write(f'Failed to communicate with 
power-profiles-daemon: {format(error)}\n')
+            sys.exit(1)
     elif command == 'launch':
         if len(args) == 0:
             sys.exit(0)
@@ -256,7 +273,11 @@
             reason = 'Running ' + appid
         if not profile:
             profile = 'performance'
-        _launch(args, profile, appid, reason)
+        try:
+            _launch(args, profile, appid, reason)
+        except GLib.Error as error:
+            sys.stderr.write(f'Failed to communicate with 
power-profiles-daemon: {format(error)}\n')
+            sys.exit(1)
 
 if __name__ == '__main__':
     main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/power-profiles-daemon-0.10.1/src/ppd-action-trickle-charge.c 
new/power-profiles-daemon-0.11/src/ppd-action-trickle-charge.c
--- old/power-profiles-daemon-0.10.1/src/ppd-action-trickle-charge.c    
2021-10-28 11:25:13.000000000 +0200
+++ new/power-profiles-daemon-0.11/src/ppd-action-trickle-charge.c      
2022-04-29 14:29:31.000000000 +0200
@@ -54,8 +54,16 @@
 
   for (l = devices; l != NULL; l = l->next) {
     GUdevDevice *dev = l->data;
+    const char *value;
 
-    if (!g_udev_device_has_sysfs_attr (dev, CHARGE_TYPE_SYSFS_NAME))
+    if (g_strcmp0 (g_udev_device_get_sysfs_attr (dev, "scope"), "Device") != 0)
+      continue;
+
+    value = g_udev_device_get_sysfs_attr_uncached (dev, 
CHARGE_TYPE_SYSFS_NAME);
+    if (!value)
+      continue;
+
+    if (g_strcmp0 (charge_type, value) == 0)
       continue;
 
     ppd_utils_write_sysfs (dev, CHARGE_TYPE_SYSFS_NAME, charge_type, NULL);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/power-profiles-daemon-0.10.1/src/ppd-driver-intel-pstate.c 
new/power-profiles-daemon-0.11/src/ppd-driver-intel-pstate.c
--- old/power-profiles-daemon-0.10.1/src/ppd-driver-intel-pstate.c      
2021-10-28 11:25:13.000000000 +0200
+++ new/power-profiles-daemon-0.11/src/ppd-driver-intel-pstate.c        
2022-04-29 14:29:31.000000000 +0200
@@ -13,7 +13,9 @@
 #include "ppd-driver-intel-pstate.h"
 
 #define CPUFREQ_POLICY_DIR "/sys/devices/system/cpu/cpufreq/"
+#define DEFAULT_CPU_FREQ_SCALING_GOV "powersave"
 #define NO_TURBO_PATH "/sys/devices/system/cpu/intel_pstate/no_turbo"
+#define TURBO_PCT_PATH "/sys/devices/system/cpu/intel_pstate/turbo_pct"
 
 struct _PpdDriverIntelPstate
 {
@@ -107,6 +109,23 @@
 }
 
 static gboolean
+has_turbo (void)
+{
+  g_autofree char *turbo_pct_path = NULL;
+  g_autofree char *contents = NULL;
+  gboolean has_turbo = TRUE;
+
+  turbo_pct_path = ppd_utils_get_sysfs_path (TURBO_PCT_PATH);
+  if (g_file_get_contents (turbo_pct_path, &contents, NULL, NULL)) {
+    contents = g_strchomp (contents);
+    if (g_strcmp0 (contents, "0") == 0)
+      has_turbo = FALSE;
+  }
+
+  return has_turbo;
+}
+
+static gboolean
 ppd_driver_intel_pstate_probe (PpdDriver  *driver)
 {
   PpdDriverIntelPstate *pstate = PPD_DRIVER_INTEL_PSTATE (driver);
@@ -122,6 +141,8 @@
   policy_dir = ppd_utils_get_sysfs_path (CPUFREQ_POLICY_DIR);
   while ((dirname = g_dir_read_name (dir)) != NULL) {
     g_autofree char *path = NULL;
+    g_autofree char *gov_path = NULL;
+    g_autoptr(GError) error = NULL;
 
     path = g_build_filename (policy_dir,
                              dirname,
@@ -130,6 +151,16 @@
     if (!g_file_test (path, G_FILE_TEST_EXISTS))
       continue;
 
+    /* Force a scaling_governor where the preference can be written */
+    gov_path = g_build_filename (policy_dir,
+                                 dirname,
+                                 "scaling_governor",
+                                 NULL);
+    if (!ppd_utils_write (gov_path, DEFAULT_CPU_FREQ_SCALING_GOV, &error)) {
+      g_warning ("Could not change scaling governor %s to '%s'", dirname, 
DEFAULT_CPU_FREQ_SCALING_GOV);
+      continue;
+    }
+
     pstate->devices = g_list_prepend (pstate->devices, g_steal_pointer 
(&path));
     ret = PPD_PROBE_RESULT_SUCCESS;
   }
@@ -137,14 +168,16 @@
   if (ret != PPD_PROBE_RESULT_SUCCESS)
     goto out;
 
-  /* Monitor the first "no_turbo" */
-  pstate->no_turbo_path = ppd_utils_get_sysfs_path (NO_TURBO_PATH);
-  pstate->no_turbo_mon = monitor_no_turbo_prop (pstate->no_turbo_path);
-  if (pstate->no_turbo_mon) {
-    g_signal_connect (G_OBJECT (pstate->no_turbo_mon), "changed",
-                      G_CALLBACK (no_turbo_changed), pstate);
+  if (has_turbo ()) {
+    /* Monitor the first "no_turbo" */
+    pstate->no_turbo_path = ppd_utils_get_sysfs_path (NO_TURBO_PATH);
+    pstate->no_turbo_mon = monitor_no_turbo_prop (pstate->no_turbo_path);
+    if (pstate->no_turbo_mon) {
+      g_signal_connect (G_OBJECT (pstate->no_turbo_mon), "changed",
+                        G_CALLBACK (no_turbo_changed), pstate);
+    }
+    update_no_turbo (pstate);
   }
-  update_no_turbo (pstate);
 
 out:
   g_debug ("%s p-state settings",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/power-profiles-daemon-0.10.1/src/ppd-utils.c 
new/power-profiles-daemon-0.11/src/ppd-utils.c
--- old/power-profiles-daemon-0.10.1/src/ppd-utils.c    2021-10-28 
11:25:13.000000000 +0200
+++ new/power-profiles-daemon-0.11/src/ppd-utils.c      2022-04-29 
14:29:31.000000000 +0200
@@ -34,6 +34,8 @@
   g_return_val_if_fail (filename, FALSE);
   g_return_val_if_fail (value, FALSE);
 
+  g_debug ("Writing '%s' to '%s'", value, filename);
+
   sysfsfp = fopen (filename, "w");
   if (sysfsfp == NULL) {
     g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
@@ -41,14 +43,20 @@
     g_debug ("Could not open for writing '%s'", filename);
     return FALSE;
   }
+  setbuf(sysfsfp, NULL);
   ret = fprintf (sysfsfp, "%s", value);
-  if (ret < 0) {
+  if (ret <= 0) {
+    g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
+                 "Error writing '%s': %s", filename, g_strerror (errno));
+    g_debug ("Error writing '%s': %s", filename, g_strerror (errno));
+    return FALSE;
+  }
+  if (fclose (sysfsfp) != 0) {
     g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
-                 "Error writing '%s'", filename);
-    g_debug ("Error writing '%s'", filename);
+                 "Error closing '%s': %s", filename, g_strerror (errno));
+    g_debug ("Error closing '%s': %s", filename, g_strerror (errno));
     return FALSE;
   }
-  fclose (sysfsfp);
   return TRUE;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/power-profiles-daemon-0.10.1/tests/integration-test.py 
new/power-profiles-daemon-0.11/tests/integration-test.py
--- old/power-profiles-daemon-0.10.1/tests/integration-test.py  2021-10-28 
11:25:13.000000000 +0200
+++ new/power-profiles-daemon-0.11/tests/integration-test.py    2022-04-29 
14:29:31.000000000 +0200
@@ -33,20 +33,20 @@
     from gi.repository import Gio
 except ImportError as e:
     sys.stderr.write('Skipping tests, PyGobject not available for Python 3, or 
missing GI typelibs: %s\n' % str(e))
-    sys.exit(0)
+    sys.exit(77)
 
 try:
     gi.require_version('UMockdev', '1.0')
     from gi.repository import UMockdev
 except ImportError:
     sys.stderr.write('Skipping tests, umockdev not available 
(https://github.com/martinpitt/umockdev)\n')
-    sys.exit(0)
+    sys.exit(77)
 
 try:
     import dbusmock
 except ImportError:
     sys.stderr.write('Skipping tests, python-dbusmock not available 
(http://pypi.python.org/pypi/python-dbusmock).\n')
-    sys.exit(0)
+    sys.exit(77)
 
 
 PP = 'net.hadess.PowerProfiles'
@@ -239,6 +239,9 @@
     def read_sysfs_attr(self, device, attribute):
         return self.read_sysfs_file(device + '/' + attribute)
 
+    def get_mtime(self, device, attribute):
+        return os.path.getmtime(self.testbed.get_root_dir() + '/' + device + 
'/' + attribute)
+
     def read_file(self, path):
         with open(path, 'rb') as f:
             return f.read()
@@ -363,10 +366,14 @@
       # Create 2 CPUs with preferences
       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/cpufreq/policy1/")
       os.makedirs(dir2)
+      with open(os.path.join(dir2, 'scaling_governor'), 'w') as gov:
+        gov.write('powersave\n')
       with open(os.path.join(dir2, "energy_performance_preference"),'w') as 
prefs:
         prefs.write("performance\n")
 
@@ -421,6 +428,9 @@
       # Create CPU with preference
       dir1 = os.path.join(self.testbed.get_root_dir(), 
"sys/devices/system/cpu/cpufreq/policy0/")
       os.makedirs(dir1)
+      gov_path = os.path.join(dir1, 'scaling_governor')
+      with open(gov_path, 'w') as gov:
+        gov.write('performance\n')
       with open(os.path.join(dir1, "energy_performance_preference"),'w') as 
prefs:
         prefs.write("performance\n")
 
@@ -429,6 +439,10 @@
 
       self.start_daemon()
 
+      with open(gov_path, 'rb') as f:
+        contents = f.read()
+        self.assertEqual(contents, b'powersave')
+
       profiles = self.get_dbus_property('Profiles')
       self.assertEqual(len(profiles), 3)
       self.assertEqual(profiles[0]['Driver'], 'intel_pstate')
@@ -446,6 +460,43 @@
       upowerd.wait()
       upowerd.stdout.close()
 
+    def test_intel_pstate_error(self):
+      '''Intel P-State driver in error state'''
+
+      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')
+      pref_path = os.path.join(dir1, "energy_performance_preference")
+      old_umask = os.umask(0o333)
+      with open(pref_path,'w') as prefs:
+        prefs.write("balance_performance\n")
+      os.umask(old_umask)
+      # Make file non-writable to root
+      if os.geteuid() == 0:
+        if not GLib.find_program_in_path('chattr'):
+          os._exit(77)
+        subprocess.check_output(['chattr', '+i', pref_path])
+
+      self.start_daemon()
+
+      self.assertEqual(self.get_dbus_property('ActiveProfile'), 'balanced')
+
+      # Error when setting performance mode
+      with self.assertRaises(gi.repository.GLib.GError):
+        self.set_dbus_property('ActiveProfile', 
GLib.Variant.new_string('performance'))
+      self.assertEqual(self.get_dbus_property('ActiveProfile'), 'balanced')
+
+      contents = None
+      with open(os.path.join(dir1, "energy_performance_preference"), 'rb') as 
f:
+        contents = f.read()
+      self.assertEqual(contents, b'balance_performance\n')
+
+      self.stop_daemon()
+
+      if os.geteuid() == 0:
+        subprocess.check_output(['chattr', '-i', pref_path])
+
     def test_dytc_performance_driver(self):
       '''Lenovo DYTC performance driver'''
 
@@ -498,6 +549,41 @@
       profiles = self.get_dbus_property('Profiles')
       self.assertEqual(len(profiles), 2)
 
+    def test_trickle_charge_system(self):
+      '''Trickle power_supply charge type'''
+
+      fastcharge = self.testbed.add_device('power_supply', 'bq24190-charger', 
None,
+          [ 'charge_type', 'Trickle', 'scope', 'System' ],
+          []
+      )
+
+      self.start_daemon()
+
+      self.assertIn('trickle_charge', self.get_dbus_property('Actions'))
+
+      # Verify that charge-type stays untouched
+      self.assertEqual(self.read_sysfs_attr(fastcharge, 'charge_type'), 
b'Trickle')
+
+      self.set_dbus_property('ActiveProfile', 
GLib.Variant.new_string('power-saver'))
+      self.assertEqual(self.read_sysfs_attr(fastcharge, 'charge_type'), 
b'Trickle')
+
+    def test_trickle_charge_mode_no_change(self):
+      '''Trickle power_supply charge type'''
+
+      fastcharge = self.testbed.add_device('power_supply', 'MFi Fastcharge', 
None,
+          [ 'charge_type', 'Fast', 'scope', 'Device' ],
+          []
+      )
+
+      mtime = self.get_mtime(fastcharge, 'charge_type')
+      self.start_daemon()
+
+      self.assertIn('trickle_charge', self.get_dbus_property('Actions'))
+
+      # Verify that charge-type didn't get touched
+      self.assertEqual(self.read_sysfs_attr(fastcharge, 'charge_type'), 
b'Fast')
+      self.assertEqual(self.get_mtime(fastcharge, 'charge_type'), mtime)
+
     def test_trickle_charge_mode(self):
       '''Trickle power_supply charge type'''
 
@@ -794,6 +880,77 @@
 
       self.stop_daemon()
 
+    def test_intel_pstate_noturbo(self):
+      '''Intel P-State driver (balance)'''
+
+      # Create CPU with preference
+      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")
+
+      # Create no_turbo pref with turbo_pct
+      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("1\n")
+      with open(os.path.join(pstate_dir, "turbo_pct"),'w') as no_turbo:
+        no_turbo.write("0\n")
+
+      self.start_daemon()
+
+      profiles = self.get_dbus_property('Profiles')
+      self.assertEqual(len(profiles), 3)
+      self.assertEqual(self.get_dbus_property('PerformanceDegraded'), '')
+
+      self.stop_daemon()
+
+    def test_powerprofilesctl_error(self):
+      '''Check that powerprofilesctl returns 1 rather than an exception on 
error'''
+
+      builddir = os.getenv('top_builddir', '.')
+      tool_path = os.path.join(builddir, 'src', 'powerprofilesctl')
+
+      with self.assertRaises(subprocess.CalledProcessError) as cm:
+          subprocess.check_output([tool_path, 'list'],
+                                  stderr=subprocess.PIPE,
+                                  universal_newlines=True)
+      self.assertNotIn('Traceback', cm.exception.stderr)
+
+      with self.assertRaises(subprocess.CalledProcessError) as cm:
+          subprocess.check_output([tool_path, 'get'],
+                                  stderr=subprocess.PIPE,
+                                  universal_newlines=True)
+      self.assertNotIn('Traceback', cm.exception.stderr)
+
+      with self.assertRaises(subprocess.CalledProcessError) as cm:
+          subprocess.check_output([tool_path, 'set', 'not-a-profile'],
+                                  stderr=subprocess.PIPE,
+                                  universal_newlines=True)
+      self.assertNotIn('Traceback', cm.exception.stderr)
+
+      with self.assertRaises(subprocess.CalledProcessError) as cm:
+          subprocess.check_output([tool_path, 'list-holds'],
+                                  stderr=subprocess.PIPE,
+                                  universal_newlines=True)
+      self.assertNotIn('Traceback', cm.exception.stderr)
+
+      with self.assertRaises(subprocess.CalledProcessError) as cm:
+          subprocess.check_output([tool_path, 'launch', '-p', 'power-saver', 
'sleep', '1'],
+                                  stderr=subprocess.PIPE,
+                                  universal_newlines=True)
+      self.assertNotIn('Traceback', cm.exception.stderr)
+
+      self.start_daemon()
+      with self.assertRaises(subprocess.CalledProcessError) as cm:
+          subprocess.check_output([tool_path, 'set', 'not-a-profile'],
+                                  stderr=subprocess.PIPE,
+                                  universal_newlines=True)
+      self.assertNotIn('Traceback', cm.exception.stderr)
+      self.stop_daemon()
+
     #
     # Helper methods
     #
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/power-profiles-daemon-0.10.1/tests/meson.build 
new/power-profiles-daemon-0.11/tests/meson.build
--- old/power-profiles-daemon-0.10.1/tests/meson.build  2021-10-28 
11:25:13.000000000 +0200
+++ new/power-profiles-daemon-0.11/tests/meson.build    2022-04-29 
14:29:31.000000000 +0200
@@ -4,7 +4,7 @@
 
 python3 = find_program('python3')
 unittest_inspector = find_program('unittest_inspector.py')
-r = run_command(unittest_inspector, files('integration-test.py'))
+r = run_command(unittest_inspector, files('integration-test.py'), check: true)
 unit_tests = r.stdout().strip().split('\n')
 
 foreach ut: unit_tests

Reply via email to