summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2017-05-19 20:03:29 +0200
committerGiampaolo Rodola <g.rodola@gmail.com>2017-05-19 20:03:29 +0200
commite5a081128e85d229af6499bb39b708ae15720358 (patch)
tree6b2516634bb89511bdce96410a0a28a1d91c6d8d
parente20b3473da81d1c4aca3919a895bc940c52ea333 (diff)
downloadpsutil-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.rst4
-rw-r--r--psutil/__init__.py7
-rwxr-xr-xpsutil/tests/test_process.py6
-rwxr-xr-xpsutil/tests/test_system.py12
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