mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
Measured on a VM with two disks, a CD-ROM and a NIC: 70 libvirt calls per page, now 43. Within the page's cached_reads block the VM's state, the host's info and domain capabilities, and each disk path's volume are read once; the running and the persistent disk lists share a path's volume. The ISO list takes the active pools in one call instead of looking each up by name; it still refreshes them, so an image copied in by hand shows up. The opt-in DRBD status waits at most 10 s for the compute's ssh, then leaves the status unknown instead of holding the page.
99 lines
3.4 KiB
Python
99 lines
3.4 KiB
Python
import unittest
|
|
from unittest.mock import MagicMock
|
|
|
|
from django.conf import settings
|
|
|
|
if not settings.configured:
|
|
settings.configure(MAC_OUI="52:54:10")
|
|
|
|
from libvirt import (
|
|
VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE,
|
|
VIR_DOMAIN_AFFECT_CONFIG,
|
|
VIR_DOMAIN_AFFECT_LIVE,
|
|
libvirtError,
|
|
)
|
|
from lxml import etree
|
|
from vrtManager.instance import wvmInstance
|
|
|
|
DOMAIN = """<domain><devices>
|
|
<disk type='file' device='cdrom'><driver name='qemu' type='raw'/><target dev='sda' bus='sata'/></disk>
|
|
<disk type='file' device='cdrom'><driver name='qemu' type='raw'/><target dev='sdb' bus='sata'/></disk>
|
|
</devices></domain>"""
|
|
|
|
|
|
def vm(active):
|
|
inst = wvmInstance.__new__(wvmInstance)
|
|
inst.instance = MagicMock()
|
|
inst.instance.isActive.return_value = active
|
|
inst._XMLDesc = MagicMock(return_value=DOMAIN)
|
|
return inst
|
|
|
|
|
|
class IsoMediaTestCase(unittest.TestCase):
|
|
"""Media change goes through updateDeviceFlags for the right CD-ROM."""
|
|
|
|
def updates(self, inst):
|
|
return [
|
|
(etree.fromstring(c.args[0]).find("target").get("dev"), etree.fromstring(c.args[0]).xpath("string(source/@file)"), c.args[1])
|
|
for c in inst.instance.updateDeviceFlags.call_args_list
|
|
]
|
|
|
|
def test_stopped_vm_changes_only_the_persistent_definition(self):
|
|
inst = vm(active=False)
|
|
inst._set_cdrom_media("sdb", "/iso/a.iso")
|
|
self.assertEqual(self.updates(inst), [("sdb", "/iso/a.iso", VIR_DOMAIN_AFFECT_CONFIG)])
|
|
|
|
def test_running_vm_changes_live_then_persistent(self):
|
|
inst = vm(active=True)
|
|
inst._set_cdrom_media("sdb", None)
|
|
self.assertEqual(
|
|
self.updates(inst), [("sdb", "", VIR_DOMAIN_AFFECT_LIVE), ("sdb", "", VIR_DOMAIN_AFFECT_CONFIG)]
|
|
)
|
|
|
|
def test_unknown_cdrom_changes_nothing(self):
|
|
inst = vm(active=True)
|
|
with self.assertRaises(libvirtError):
|
|
inst._set_cdrom_media("sdz", "/iso/a.iso")
|
|
inst.instance.updateDeviceFlags.assert_not_called()
|
|
|
|
|
|
def pool(volumes, refresh_error=False, list_error=False):
|
|
p = MagicMock()
|
|
if refresh_error:
|
|
p.refresh.side_effect = libvirtError("refresh failed")
|
|
if list_error:
|
|
p.listVolumes.side_effect = libvirtError("pool is not active")
|
|
else:
|
|
p.listVolumes.return_value = volumes
|
|
return p
|
|
|
|
|
|
class IsoListTestCase(unittest.TestCase):
|
|
"""The CD-ROM choices are the .iso volumes of the active pools, refreshed
|
|
so that an image copied in by hand shows up."""
|
|
|
|
def iso(self, *pools):
|
|
inst = wvmInstance.__new__(wvmInstance)
|
|
inst.wvm = MagicMock()
|
|
inst.wvm.listAllStoragePools.return_value = list(pools)
|
|
return inst, inst.get_iso_media()
|
|
|
|
def test_iso_volumes_of_the_active_pools(self):
|
|
a, b = pool(["a.iso", "disk.qcow2"]), pool(["B.ISO"])
|
|
inst, iso = self.iso(a, b)
|
|
self.assertEqual(iso, ["a.iso", "B.ISO"])
|
|
inst.wvm.listAllStoragePools.assert_called_once_with(VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE)
|
|
a.refresh.assert_called_once_with(0)
|
|
b.refresh.assert_called_once_with(0)
|
|
|
|
def test_a_failed_refresh_still_lists_the_pool(self):
|
|
_, iso = self.iso(pool(["a.iso"], refresh_error=True))
|
|
self.assertEqual(iso, ["a.iso"])
|
|
|
|
def test_a_pool_stopped_meanwhile_is_skipped(self):
|
|
_, iso = self.iso(pool([], list_error=True), pool(["b.iso"]))
|
|
self.assertEqual(iso, ["b.iso"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|