From d7de0fdaab7bcffc2e201b3f868afd0886868e02 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Wed, 15 Jul 2015 14:17:34 +0200 Subject: [PATCH] fix #645: [Linux] psutil.cpu_times_percent() may produce negative results. --- HISTORY.rst | 9 +++++++++ psutil/__init__.py | 31 ++++++++++++++----------------- test/test_psutil.py | 15 +++++++++++++-- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 02c21421d..65fedf91d 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,5 +1,14 @@ Bug tracker at https://github.com/giampaolo/psutil/issues +3.1.1 - XXXX-XX-XX +================== + +**Bug fixes** + +- #645: [Linux] psutil.cpu_times_percent() may produce negative results. +- #656: 'from psutil import *' does not work. + + 3.1.0 - 2015-07-15 ================== diff --git a/psutil/__init__.py b/psutil/__init__.py index 3e4d0462d..baa74ae1c 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -1505,23 +1505,20 @@ def calculate(t1, t2): except ZeroDivisionError: field_perc = 0.0 field_perc = round(field_perc, 1) - if _WINDOWS: - # XXX - # Work around: - # https://github.com/giampaolo/psutil/issues/392 - # CPU times are always supposed to increase over time - # or at least remain the same and that's because time - # cannot go backwards. - # Surprisingly sometimes this might not be the case on - # Windows where 'system' CPU time can be smaller - # compared to the previous call, resulting in corrupted - # percentages (< 0 or > 100). - # I really don't know what to do about that except - # forcing the value to 0 or 100. - if field_perc > 100.0: - field_perc = 100.0 - elif field_perc < 0.0: - field_perc = 0.0 + # CPU times are always supposed to increase over time + # or at least remain the same and that's because time + # cannot go backwards. + # Surprisingly sometimes this might not be the case (at + # least on Windows and Linux), see: + # https://github.com/giampaolo/psutil/issues/392 + # https://github.com/giampaolo/psutil/issues/645 + # I really don't know what to do about that except + # forcing the value to 0 or 100. + if field_perc > 100.0: + field_perc = 100.0 + # `<=` because `-0.0 == 0.0` evaluates to True + elif field_perc <= 0.0: + field_perc = 0.0 nums.append(field_perc) return _psplatform.scputimes(*nums) diff --git a/test/test_psutil.py b/test/test_psutil.py index 73779cc3b..0ec756f65 100644 --- a/test/test_psutil.py +++ b/test/test_psutil.py @@ -807,7 +807,7 @@ def test_sys_per_cpu_times(self): # new_t, last_t, msg="%s %s" % (lastcpu, newcpu)) # last = new - def test_sys_per_cpu_times2(self): + def test_sys_per_cpu_times_2(self): tot1 = psutil.cpu_times(percpu=True) stop_at = time.time() + 0.1 while True: @@ -825,6 +825,7 @@ def _test_cpu_percent(self, percent, last_ret, new_ret): try: self.assertIsInstance(percent, float) self.assertGreaterEqual(percent, 0.0) + self.assertIsNot(percent, -0.0) self.assertLessEqual(percent, 100.0 * psutil.cpu_count()) except AssertionError as err: raise AssertionError("\n%s\nlast=%s\nnew=%s" % ( @@ -866,6 +867,16 @@ def test_sys_per_cpu_times_percent(self): self._test_cpu_percent(sum(cpu), last, new) last = new + def test_sys_per_cpu_times_percent_negative(self): + # see: https://github.com/giampaolo/psutil/issues/645 + psutil.cpu_times_percent(percpu=True) + zero_times = [x._make([0 for x in range(len(x._fields))]) + for x in psutil.cpu_times(percpu=True)] + with mock.patch('psutil.cpu_times', return_value=zero_times): + for cpu in psutil.cpu_times_percent(percpu=True): + for percent in cpu: + self._test_cpu_percent(percent, None, None) + @unittest.skipIf(POSIX and not hasattr(os, 'statvfs'), "os.statvfs() function not available on this platform") def test_disk_usage(self): @@ -2752,7 +2763,7 @@ def test__all__(self): if (fun.__doc__ is not None and 'deprecated' not in fun.__doc__.lower()): self.fail('%r not in psutil.__all__' % name) - # import 'start' will break if __all__ is inconsistent, see: + # import 'star' will break if __all__ is inconsistent, see: # https://github.com/giampaolo/psutil/issues/656 from psutil import * # NOQA