1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-11 12:46:49 +00:00

perf(instances): a VM list reads only the VMs it shows

#394 read each host's states in one call and every domain's XML once,
for the title, memory and vCPUs. A user's list shows only their own VMs,
but it read the XML of every VM on those hosts: a user with two VMs on a
host of 300 made about 301 libvirt calls a list load, where the old
per-VM reads made 6.

get_domain_rows takes the UUIDs the list shows and reads only their XML;
the states still come in one call. The capacity reads every domain, as
before.
This commit is contained in:
catborise 2026-11-04 23:58:36 +03:00
parent 02d4d02757
commit 337063bf7b
5 changed files with 28 additions and 11 deletions

View file

@ -65,8 +65,8 @@ class ListReadTests(TestCase):
def assert_read_once_a_host(self, url):
response, calls = self.get(url)
# every domain of the host once (the test driver's own, and other tests', too)
self.assertEqual(calls, {"XMLDesc": len(self.conn.listAllDomains())})
# each VM the list shows once; the host's other domains (the test driver's own) not at all
self.assertEqual(calls, {"XMLDesc": len(VMS)})
self.assertContains(response, "2048 MiB", count=len(VMS))
self.assertContains(response, "Active")
self.assertContains(response, "vm-a title")
@ -81,3 +81,15 @@ class ListReadTests(TestCase):
def test_compute_instances(self):
self.assert_read_once_a_host(reverse("instances", args=[self.compute.id]))
def test_a_user_s_list_reads_only_their_vms(self):
from accounts.models import UserInstance
user = get_user_model().objects.create_user("rpc-user", password="pwd")
UserInstance.objects.create(user=user, instance=Instance.objects.get(name="vm-a"))
self.client.force_login(user)
response, calls = self.get(reverse("instances:index"))
# the other VMs of the host, the test driver's own and other tests' included, are not read
self.assertEqual(calls, {"XMLDesc": 1})
self.assertContains(response, "vm-a title")
self.assertNotContains(response, "vm-b")

View file

@ -31,7 +31,7 @@ class UnreachableListTests(TestCase):
or up with the error its listing raises."""
up = rows is not None
def domain_rows():
def domain_rows(uuids=None):
if isinstance(rows, Exception):
raise rows
return rows

View file

@ -58,7 +58,7 @@ class StateTests(TestCase):
self.client.force_login(user)
props = {"status": True, "connection_error": None, "cpu_count": 1, "ram_size": 1, "ram_usage": 0,
"proxy": SimpleNamespace(get_domain_rows=lambda: rows)}
"proxy": SimpleNamespace(get_domain_rows=lambda uuids=None: rows)}
patches = [patch.object(Compute, k, new_callable=PropertyMock, return_value=v) for k, v in props.items()]
patches += [patch("instances.views.utils.refr"), patch("computes.views.utils.refresh_instance_database")]
for p in patches: