1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 19:26:48 +00:00
webvirtcloud/vrtManager/tests/test_iso_media.py
catborise b89672169f fix(instances): Refresh ISO list says which pools it could not read
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.
2026-11-02 16:11:15 +03:00

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()