mirror of
https://github.com/nicolargo/glances.git
synced 2026-09-15 06:40:25 -04:00
sort_stats wraps the specific sort helpers in try/except and falls back to
cpu_percent for the whole list. _sort_cpu_times indexed cpu_times['user'] and
_sort_io_counters indexed io_counters[0..3], so one row with an empty value
raised and silently reordered every other row while the header still read TIME
or IOR/IOW.
Those empty values are expected rather than corrupt: programs.py builds a
program with p['cpu_times'] or {} and list(p['io_counters'] or NO_IO_COUNTERS),
and its own comment says some values can be None on macOS system processes.
Each helper now reads a missing value as zero, so the degenerate row sorts last
and the rest keep their order.
66 lines
2.7 KiB
Python
66 lines
2.7 KiB
Python
"""Sorting must not be discarded because one row has nothing to sort on.
|
|
|
|
`sort_stats` wraps the specific sort helpers in a try/except and falls back to
|
|
`cpu_percent` for the whole list. So a single row whose `cpu_times` is `{}` or whose
|
|
`io_counters` is empty does not fail loudly — it silently reorders every other row while
|
|
the header still reads TIME or IOR/IOW.
|
|
|
|
Those empty values are expected, not corrupt: `glances/programs.py` builds a program with
|
|
`p['cpu_times'] or {}` and `list(p['io_counters'] or NO_IO_COUNTERS)`, and its own comment
|
|
says "some values can be None, e.g. macOS system processes".
|
|
"""
|
|
|
|
from glances.processes import _sort_cpu_times, _sort_io_counters, sort_stats
|
|
|
|
|
|
def _row(name, cpu_times, io_counters, cpu_percent):
|
|
return {
|
|
'name': name,
|
|
'cpu_times': cpu_times,
|
|
'io_counters': io_counters,
|
|
'cpu_percent': cpu_percent,
|
|
'memory_percent': 1.0,
|
|
}
|
|
|
|
|
|
def test_sort_cpu_times_reads_a_missing_value_as_zero():
|
|
assert _sort_cpu_times({'cpu_times': {}}) == 0
|
|
assert _sort_cpu_times({'cpu_times': None}) == 0
|
|
assert _sort_cpu_times({}) == 0
|
|
assert _sort_cpu_times({'cpu_times': {'user': 5.0, 'system': 1.0}}) == 6.0
|
|
|
|
|
|
def test_sort_io_counters_reads_a_missing_value_as_zero():
|
|
assert _sort_io_counters({'io_counters': []}) == 0
|
|
assert _sort_io_counters({'io_counters': None}) == 0
|
|
assert _sort_io_counters({}) == 0
|
|
# A tuple is what programs.NO_IO_COUNTERS is, and a short list must not raise either.
|
|
assert _sort_io_counters({'io_counters': (900, 90, 100, 10, 1)}) == 880
|
|
assert _sort_io_counters({'io_counters': [900, 90]}) == 990
|
|
|
|
|
|
def test_one_row_without_cpu_times_does_not_reorder_the_others():
|
|
# 'idle' has no cpu_times and the highest cpu_percent, so a fallback to cpu_percent
|
|
# puts it first — which is exactly what used to happen.
|
|
rows = [
|
|
_row('editor', {'user': 5.0, 'system': 1.0}, [0, 0, 0, 0, 0], 1.0),
|
|
_row('idle', {}, [0, 0, 0, 0, 0], 99.0),
|
|
_row('compiler', {'user': 50.0, 'system': 9.0}, [0, 0, 0, 0, 0], 2.0),
|
|
]
|
|
|
|
ordered = sort_stats(rows, sorted_by='cpu_times', sorted_by_secondary='memory_percent')
|
|
|
|
assert [row['name'] for row in ordered] == ['compiler', 'editor', 'idle']
|
|
|
|
|
|
def test_one_row_without_io_counters_does_not_reorder_the_others():
|
|
rows = [
|
|
_row('editor', {'user': 0.0, 'system': 0.0}, [900, 90, 100, 10, 1], 1.0),
|
|
_row('idle', {'user': 0.0, 'system': 0.0}, [], 99.0),
|
|
_row('compiler', {'user': 0.0, 'system': 0.0}, [9000, 900, 1000, 100, 1], 2.0),
|
|
]
|
|
|
|
ordered = sort_stats(rows, sorted_by='io_counters', sorted_by_secondary='memory_percent')
|
|
|
|
assert [row['name'] for row in ordered] == ['compiler', 'editor', 'idle']
|