mirror of
https://github.com/nicolargo/glances.git
synced 2026-06-03 03:15:09 -04:00
129 lines
4.1 KiB
Python
129 lines
4.1 KiB
Python
"""Glances v5 — tests for the processcount plugin's curses renderer."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from glances.outputs.curses_renderer_v5 import ColorRole
|
|
from glances.plugins.processcount.render_curses_v5 import render
|
|
|
|
|
|
@pytest.fixture
|
|
def fields():
|
|
return {
|
|
"total": {"unit": "number"},
|
|
"running": {"unit": "number"},
|
|
"sleeping": {"unit": "number"},
|
|
"thread": {"unit": "number"},
|
|
"pid_max": {"unit": "number"},
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def payload():
|
|
return {
|
|
"total": 215,
|
|
"running": 3,
|
|
"sleeping": 195,
|
|
"thread": 1452,
|
|
"pid_max": 32768,
|
|
}
|
|
|
|
|
|
# ---------------------------------------------------------- structure
|
|
|
|
|
|
def test_render_produces_one_row(payload, fields):
|
|
rows = render(payload, fields)
|
|
assert len(rows) == 1
|
|
|
|
|
|
def test_render_title_is_tasks_header(payload, fields):
|
|
rows = render(payload, fields)
|
|
first = rows[0].cells[0]
|
|
assert first.text == "TASKS"
|
|
assert first.color == ColorRole.HEADER
|
|
assert first.bold is True
|
|
|
|
|
|
def test_render_contains_aggregate_counts(payload, fields):
|
|
rows = render(payload, fields)
|
|
flat = "".join(c.text for c in rows[0].cells)
|
|
assert "215" in flat
|
|
assert "(1452 thr)" in flat
|
|
assert "3 run" in flat
|
|
assert "195 slp" in flat
|
|
# Other = 215 - 3 - 195 = 17.
|
|
assert "17 oth" in flat
|
|
|
|
|
|
def test_render_handles_missing_thread(fields):
|
|
"""psutil on macOS may not return ``thread`` — render skips the parenthesis."""
|
|
payload = {"total": 10, "running": 1, "sleeping": 8, "thread": None, "pid_max": None}
|
|
rows = render(payload, fields)
|
|
flat = "".join(c.text for c in rows[0].cells)
|
|
assert "thr" not in flat
|
|
|
|
|
|
def test_render_handles_missing_running_sleeping(fields):
|
|
"""If neither running nor sleeping is known, the renderer degrades but does not crash."""
|
|
payload = {"total": 5, "running": None, "sleeping": None, "thread": 5, "pid_max": None}
|
|
rows = render(payload, fields)
|
|
flat = "".join(c.text for c in rows[0].cells)
|
|
assert "TASKS" in flat
|
|
assert "5 oth" in flat # everything counts as "other" when run/slp are missing.
|
|
|
|
|
|
# ---------------------------------------------------------- edge cases
|
|
|
|
|
|
def test_render_empty_payload_shows_title_only(fields):
|
|
rows = render({}, fields)
|
|
assert len(rows) == 1
|
|
assert rows[0].cells[0].text == "TASKS"
|
|
# No counts surfaced.
|
|
flat = "".join(c.text for c in rows[0].cells)
|
|
assert "0 oth" not in flat
|
|
|
|
|
|
def test_render_none_payload_shows_title_only(fields):
|
|
rows = render(None, fields)
|
|
assert len(rows) == 1
|
|
assert rows[0].cells[0].text == "TASKS"
|
|
|
|
|
|
def test_render_no_total_skips_aggregate(fields):
|
|
"""An engine that never ran (no `total`) → just the title."""
|
|
payload = {"running": None, "sleeping": None, "thread": None, "pid_max": None}
|
|
rows = render(payload, fields)
|
|
flat = "".join(c.text for c in rows[0].cells)
|
|
assert flat == "TASKS"
|
|
|
|
|
|
# ---------------------------------------------------------- sort indicator (view)
|
|
|
|
|
|
def test_render_no_view_omits_sort_indicator(payload, fields):
|
|
"""Without a view (export / no TUI), the TASKS line carries no sort text."""
|
|
rows = render(payload, fields)
|
|
flat = " ".join(c.text for c in rows[0].cells)
|
|
assert "sorted" not in flat
|
|
|
|
|
|
def test_render_threads_auto_sort_indicator(payload, fields):
|
|
rows = render(payload, fields, view={"programs": False, "auto_sort": True, "sort_key": "cpu_percent"})
|
|
flat = " ".join(c.text for c in rows[0].cells)
|
|
assert "Threads sorted automatically by CPU consumption" in flat
|
|
|
|
|
|
def test_render_programs_manual_sort_indicator(payload, fields):
|
|
rows = render(payload, fields, view={"programs": True, "auto_sort": False, "sort_key": "memory_percent"})
|
|
flat = " ".join(c.text for c in rows[0].cells)
|
|
assert "Programs sorted by memory consumption" in flat
|
|
|
|
|
|
def test_render_sort_indicator_unknown_key_falls_back_to_raw(payload, fields):
|
|
rows = render(payload, fields, view={"programs": False, "auto_sort": False, "sort_key": "weird_key"})
|
|
flat = " ".join(c.text for c in rows[0].cells)
|
|
assert "Threads sorted by weird_key" in flat
|