1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 11:16:47 +00:00
webvirtcloud/instances/tests/test_duplicate_devices.py
catborise be68009432 fix(instances): an ISO already in a CD-ROM of the VM is not added again
A CD-ROM form sent twice (a double click, a resent request) added a
second drive with the same ISO. The form is refused when the ISO is in a
CD-ROM of the VM's running or persistent definition; an empty drive may
still be added more than once. tr and zh too.
2026-11-05 18:58:13 +03:00

75 lines
3.9 KiB
Python

"""A device form sent twice (a double click, a resent request) adds the
device once: libvirt takes the same disk file or MAC twice in the
persistent definition."""
from unittest.mock import MagicMock, patch
from django.contrib.auth import get_user_model
from django.contrib.messages import get_messages
from django.test import TestCase
from django.urls import reverse
from computes.models import Compute
from instances.models import Instance
PATH = "/var/lib/libvirt/images/data.qcow2"
MAC = "52:54:00:aa:bb:cc"
class DuplicateDeviceTests(TestCase):
def setUp(self):
self.client.force_login(get_user_model().objects.create_superuser("dup-admin", "d@example.com", "pw"))
compute = Compute.objects.create(name="dup-c", hostname="192.0.2.40", login="root", password="", type=1)
self.vm = Instance.objects.create(compute=compute, name="dup-vm", uuid="12121212-0000-1111-2222-333333333333")
self.proxy = MagicMock()
self.proxy.get_disk_devices.return_value = []
self.proxy.get_media_devices.return_value = []
self.proxy.get_net_devices.return_value = []
self.proxy.get_disk_bus_types.return_value = ["virtio"]
self.proxy.get_cache_modes.return_value = {"default": "Default"}
patcher = patch("instances.models.wvmInstance", return_value=self.proxy)
patcher.start()
self.addCleanup(patcher.stop)
def post(self, name, data):
response = self.client.post(reverse(f"instances:{name}", args=[self.vm.pk]), data)
return [str(m) for m in get_messages(response.wsgi_request)]
@patch("instances.views.wvmStorage")
def test_a_disk_of_the_vm_is_not_attached_again(self, storage):
pool = storage.return_value
pool.get_volumes.return_value = ["data.qcow2"]
pool.get_type.return_value = "dir"
pool.get_volume_format_type.return_value = "qcow2"
pool.get_volume_type.return_value = "file"
pool.get_volume.return_value.path.return_value = PATH
form = {"selected_storage": "default", "vols": "data.qcow2", "bus": "virtio", "cache": "default"}
self.post("add_existing_vol", form)
self.proxy.attach_disk.assert_called_once()
# the first attach is in the persistent definition only (a shut-off VM)
self.proxy.get_disk_devices.side_effect = lambda config=False: [{"path": PATH, "dev": "vdb"}] if config else []
self.assertEqual(self.post("add_existing_vol", form), ["data.qcow2 is already a disk of this VM"])
self.proxy.attach_disk.assert_called_once()
def test_a_nic_with_the_mac_of_another_is_not_added(self):
form = {"add-net-network": "net:default", "add-net-mac": MAC, "add-net-model": "virtio"}
self.post("add_network", form)
self.proxy.add_network.assert_called_once()
self.proxy.get_net_devices.side_effect = lambda config=False: [{"mac": MAC}] if config else []
form["add-net-mac"] = MAC.upper()
self.assertEqual(self.post("add_network", form),
[f"The VM already has a network device with MAC {MAC.upper()}"])
self.proxy.add_network.assert_called_once()
def test_an_iso_in_a_cdrom_of_the_vm_is_not_added_again(self):
iso = "/var/lib/libvirt/isos/alma.iso"
self.proxy.get_iso_path.return_value = iso
with patch("instances.views.cdrom_bus_choices", return_value=["sata"]):
form = {"bus": "sata", "media": "alma.iso"}
self.post("add_cdrom", form)
self.proxy.attach_disk.assert_called_once()
self.proxy.get_media_devices.side_effect = lambda config=False: [{"path": iso, "dev": "sdb"}] if config else []
self.assertEqual(self.post("add_cdrom", form), ["alma.iso is already in a CD-ROM of this VM"])
# an empty drive may be added more than once
self.post("add_cdrom", {"bus": "sata", "media": ""})
self.assertEqual(self.proxy.attach_disk.call_count, 2)