Files
glances/tests/test_plugin_processcount_render_curses_v5.py
2026-05-30 10:59:57 +02:00

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