Fix broken ps.top

This fixes two problems:

1. Poorly-designed handling of unpacking selective items from a
   `psutil.Process` instance, leading to ValueError. This is fixed by
   slicing.

2. `psutil.Process` objects are not sortable on Python 3. Fixed by using
   a key lambda to sort on the `pid` attribute.
This commit is contained in:
Erik Johnson 2020-04-28 10:08:31 -05:00 committed by Daniel Wozniak
parent 90dd22c3b3
commit 92fc17115b
2 changed files with 15 additions and 10 deletions

View file

@ -147,26 +147,22 @@ def top(num_processes=5, interval=3):
for pid in psutil.pids():
try:
process = psutil.Process(pid)
user, system = process.cpu_times()
except ValueError:
user, system, _, _ = process.cpu_times()
except psutil.NoSuchProcess:
continue
else:
user, system = process.cpu_times()[:2]
start_usage[process] = user + system
time.sleep(interval)
usage = set()
for process, start in six.iteritems(start_usage):
try:
user, system = process.cpu_times()
except ValueError:
user, system, _, _ = process.cpu_times()
except psutil.NoSuchProcess:
continue
user, system = process.cpu_times()[:2]
now = user + system
diff = now - start
usage.add((diff, process))
for idx, (diff, process) in enumerate(reversed(sorted(usage))):
for idx, (diff, process) in enumerate(
sorted(usage, key=lambda x: x[1].pid, reverse=True)
):
if num_processes and idx >= num_processes:
break
if len(_get_proc_cmdline(process)) == 0:

View file

@ -310,6 +310,15 @@ class PsTestCase(TestCase):
ps.get_users()[0],
)
def test_top(self):
"""
There's no need to do any asserts here. Merely running the function
should not raise a traceback. See the following issue:
https://github.com/saltstack/salt/issues/56942
"""
ps.top()
## This is commented out pending discussion on https://github.com/saltstack/salt/commit/2e5c3162ef87cca8a2c7b12ade7c7e1b32028f0a
# @skipIf(not HAS_UTMP, "The utmp module must be installed to run test_get_users_utmp()")
# @patch('salt.utils.psutil_compat.get_users', new=MagicMock(return_value=None)) # This will force the function to use utmp