1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 19:26:48 +00:00
webvirtcloud/instances/tests/test_stats_tab.py
catborise 5e93920d78 feat(instances): a VM's stats in one grid, its logs a switch away
The Stats tab stacked one large card per chart, so a VM with a few
devices made a long page, and its "Real Time" and "Logs" sub-tabs were
shown to every user although only a superuser may read the logs. The
owner chose the layout from rendered options: a state line, CPU and
memory side by side, one chart per NIC and disk below, each with its
latest reading next to its title, and a small Graphs/Logs switch for
superusers.

Codex reviewed the tab; this is fixed:

- Memory is shown in MiB (it was labelled MB), and its axis grows to
  the RSS when the RSS passes the balloon size instead of clipping it.
- The CPU reading says it is of the host's CPUs.
- A NIC is titled by its MAC, not an invented "eth0", and its readings
  are matched to its chart by the MAC: they were matched by position, so
  removing a NIC while the page was open moved the next one's readings
  into its chart.
- A VM that is not running says nothing is measured.
- The logs load whenever the Logs view is shown, by keyboard too; an
  empty answer says "None" and a failed one says so, instead of an
  empty table. The tab shows the latest 50 rows, with a link to all of
  the VM's rows on the Logs page.
- The VM's header shows memory in MiB; it said MB.
2026-10-30 23:41:17 +03:00

47 lines
2.1 KiB
Python

"""The Stats tab: a chart for the CPU, the memory and each NIC and disk, and
the VM's log rows for superusers only, whose log view is the only one."""
from types import SimpleNamespace
from django.template.loader import render_to_string
from django.test import RequestFactory, SimpleTestCase
from lxml import html
UUID = "abcdabcd-0000-0000-0000-000000000000"
def tab(status=1, superuser=True):
request = RequestFactory().get("/")
request.user = SimpleNamespace(is_superuser=superuser)
instance = SimpleNamespace(
id=1, uuid=UUID, status=status,
networks=[{"mac": "52:54:00:00:00:01"}], disks=[{"dev": "vda"}, {"dev": "vdb"}],
)
return html.fromstring(render_to_string("instances/stats_tab.html", {"instance": instance}, request))
class StatsTabTests(SimpleTestCase):
def test_every_device_has_a_chart_and_a_reading(self):
doc = tab()
for name in ("cpu", "mem", "net52:54:00:00:00:01", "blkvda", "blkvdb"):
with self.subTest(name=name):
self.assertTrue(doc.xpath(f"//canvas[@id='{name}Chart']"))
self.assertTrue(doc.xpath(f"//*[@id='{name}Now']"))
self.assertIn("52:54:00:00:00:01", doc.text_content())
def test_only_a_superuser_gets_the_logs(self):
for superuser in (True, False):
with self.subTest(superuser=superuser):
doc = tab(superuser=superuser)
self.assertEqual(bool(doc.xpath("//button[@data-bs-target='#logs']")), superuser)
self.assertEqual(bool(doc.xpath("//table[@id='logs_table']")), superuser)
def test_the_logs_link_to_all_of_the_vm_s_rows(self):
self.assertEqual(tab().xpath("//a[text()=\"All of this VM's logs\"]/@href"), [f"/admin/logs/?q={UUID}"])
def test_a_vm_that_is_not_running_says_nothing_is_measured(self):
for status, measured in ((1, True), (3, False), (5, False)):
with self.subTest(status=status):
text = tab(status=status).text_content()
self.assertEqual("Updates every 5 seconds." in text, measured)
self.assertEqual("nothing is measured" in text, not measured)