diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2017-05-19 20:03:29 +0200 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2017-05-19 20:03:29 +0200 |
commit | e5a081128e85d229af6499bb39b708ae15720358 (patch) | |
tree | 6b2516634bb89511bdce96410a0a28a1d91c6d8d | |
parent | e20b3473da81d1c4aca3919a895bc940c52ea333 (diff) | |
download | psutil-e5a081128e85d229af6499bb39b708ae15720358.tar.gz |
Fix #1055, fix #1085, fix #1087.
- no longer cache cpu_count() return value in Process.cpu_percent()
- in Process.cpu_percent(), guard against cpu_count() returning None and
assume 1 instead
- add test cases
-rw-r--r-- | HISTORY.rst | 4 | ||||
-rw-r--r-- | psutil/__init__.py | 7 | ||||
-rwxr-xr-x | psutil/tests/test_process.py | 6 | ||||
-rwxr-xr-x | psutil/tests/test_system.py | 12 |
4 files changed, 22 insertions, 7 deletions
diff --git a/HISTORY.rst b/HISTORY.rst index a85aacb5..d540ae69 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -50,7 +50,9 @@ - 1047_: [Windows] Process username(): memory leak in case exception is thrown. - 1048_: [Windows] users()'s host field report an invalid IP address. - 1050_: [Windows] Process.memory_maps memory() leaks memory. -- 1055_: cpu_count() is no longer cached. +- 1055_: cpu_count() is no longer cached; this is useful on systems such as + Linux where CPUs can be disabled at runtime. This also reflects on + Process.cpu_percent() which no longer uses the cache. - 1058_: fixed Python warnings. - 1062_: disk_io_counters() and net_io_counters() raise TypeError if no disks or NICs are installed on the system. diff --git a/psutil/__init__.py b/psutil/__init__.py index c393ecc3..fc45abf1 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -209,7 +209,6 @@ AF_LINK = _psplatform.AF_LINK POWER_TIME_UNLIMITED = _common.POWER_TIME_UNLIMITED POWER_TIME_UNKNOWN = _common.POWER_TIME_UNKNOWN _TOTAL_PHYMEM = None -_NUM_CPUS = None _timer = getattr(time, 'monotonic', time.time) @@ -1043,9 +1042,7 @@ class Process(object): blocking = interval is not None and interval > 0.0 if interval is not None and interval < 0: raise ValueError("interval is not positive (got %r)" % interval) - # TODO: rarely cpu_count() may return None, meaning this will - # break. It's probably wise to fall back to 1. - num_cpus = _NUM_CPUS or cpu_count() + num_cpus = cpu_count() or 1 def timer(): return _timer() * num_cpus @@ -1645,10 +1642,8 @@ def cpu_count(logical=True): >>> psutil.cpu_count.cache_clear() """ - global _NUM_CPUS if logical: ret = _psplatform.cpu_count_logical() - _NUM_CPUS = ret else: ret = _psplatform.cpu_count_physical() return ret if ret >= 1 else None diff --git a/psutil/tests/test_process.py b/psutil/tests/test_process.py index 3410ec0b..cab5a2fe 100755 --- a/psutil/tests/test_process.py +++ b/psutil/tests/test_process.py @@ -246,6 +246,12 @@ class TestProcess(unittest.TestCase): with self.assertRaises(ValueError): p.cpu_percent(interval=-1) + def test_cpu_percent_numcpus_none(self): + # See: https://github.com/giampaolo/psutil/issues/1087 + with mock.patch('psutil.cpu_count', return_value=None) as m: + psutil.Process().cpu_percent() + assert m.called + def test_cpu_times(self): times = psutil.Process().cpu_times() assert (times.user > 0.0) or (times.system > 0.0), times diff --git a/psutil/tests/test_system.py b/psutil/tests/test_system.py index fed7a222..e93bb6b5 100755 --- a/psutil/tests/test_system.py +++ b/psutil/tests/test_system.py @@ -270,6 +270,18 @@ class TestSystemAPIs(unittest.TestCase): self.assertGreaterEqual(physical, 1) self.assertGreaterEqual(logical, physical) + def test_cpu_count_none(self): + # https://github.com/giampaolo/psutil/issues/1085 + for val in (-1, 0, None): + with mock.patch('psutil._psplatform.cpu_count_logical', + return_value=val) as m: + self.assertIsNone(psutil.cpu_count()) + assert m.called + with mock.patch('psutil._psplatform.cpu_count_physical', + return_value=val) as m: + self.assertIsNone(psutil.cpu_count(logical=False)) + assert m.called + def test_cpu_times(self): # Check type, value >= 0, str(). total = 0 |