mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 11:16:47 +00:00
A pool whose refresh failed, one busy with a volume copy for example, was skipped without a word, so a hand-copied image stayed missing with no reason given. The other pools are still refreshed; each failure is shown with libvirt's error. The API comment no longer says listing the ISO images refreshes pools.
111 lines
4 KiB
Python
111 lines
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 libvirt knows in the active
|
|
pools; the pools are read again only when asked."""
|
|
|
|
def wvm(self, *pools):
|
|
inst = wvmInstance.__new__(wvmInstance)
|
|
inst.wvm = MagicMock()
|
|
inst.wvm.listAllStoragePools.return_value = list(pools)
|
|
return inst
|
|
|
|
def test_iso_volumes_of_the_active_pools_without_a_refresh(self):
|
|
a, b = pool(["a.iso", "disk.qcow2"]), pool(["B.ISO"])
|
|
inst = self.wvm(a, b)
|
|
self.assertEqual(inst.get_iso_media(), ["a.iso", "B.ISO"])
|
|
inst.wvm.listAllStoragePools.assert_called_once_with(VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE)
|
|
a.refresh.assert_not_called()
|
|
b.refresh.assert_not_called()
|
|
|
|
def test_a_pool_stopped_meanwhile_is_skipped(self):
|
|
inst = self.wvm(pool([], list_error=True), pool(["b.iso"]))
|
|
self.assertEqual(inst.get_iso_media(), ["b.iso"])
|
|
|
|
def test_refresh_reads_every_active_pool_again(self):
|
|
a, b = pool([]), pool([])
|
|
inst = self.wvm(a, b)
|
|
self.assertEqual(inst.refresh_iso_pools(), {})
|
|
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_is_returned_and_the_others_still_run(self):
|
|
a, b = pool([], refresh_error=True), pool([])
|
|
a.name.return_value = "busy"
|
|
failed = self.wvm(a, b).refresh_iso_pools()
|
|
self.assertEqual(list(failed), ["busy"])
|
|
self.assertIsInstance(failed["busy"], libvirtError)
|
|
b.refresh.assert_called_once_with(0)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|