import unittest from unittest.mock import MagicMock from django.conf import settings if not settings.configured: settings.configure(MAC_OUI="52:54:10") from vrtManager.instance import PERSISTENT_XML, wvmInstance DOMAIN = """vm131072131072 1hvm """ class PersistentEditsTestCase(unittest.TestCase): """Edits read the persistent definition with secrets.""" def test_edits_read_the_persistent_secure_definition(self): edits = { "set_bootmenu": lambda vm: vm.set_bootmenu(1), "set_console_keymap": lambda vm: vm.set_console_keymap("de"), "set_video_model": lambda vm: vm.set_video_model("virtio"), "resize_cpu": lambda vm: vm.resize_cpu("1", "2"), "set_options": lambda vm: vm.set_options({"title": "t"}), "set_qos": lambda vm: vm.set_qos("52:54:00:00:00:01", "inbound", 1, 2, 3), } for name, edit in edits.items(): with self.subTest(name): vm = wvmInstance.__new__(wvmInstance) vm.instance = MagicMock() vm.wvm = MagicMock() vm._XMLDesc = MagicMock(return_value=DOMAIN) vm.get_vcpus = MagicMock(return_value=None) vm.get_status = MagicMock(return_value=5) edit(vm) flags = {call.args[0] for call in vm._XMLDesc.call_args_list} self.assertIn(PERSISTENT_XML, flags) defined = (vm.wvm.defineXML.call_args or vm._XMLDesc.call_args)[0][0] self.assertIn("secret", str(defined)) class XmlFidelityTestCase(unittest.TestCase): def test_edits_keep_metadata_namespace_prefixes(self): xml = ( "v" "hvm" "" ) edits = { "set_bootmenu": lambda vm: vm.set_bootmenu(1), "set_bootorder": lambda vm: vm.set_bootorder({0: {"type": "disk", "dev": "vda"}}), "set_console_keymap": lambda vm: vm.set_console_keymap("de"), "set_console_passwd": lambda vm: vm.set_console_passwd("x"), "set_console_listener_addr": lambda vm: vm.set_console_listener_addr("127.0.0.1"), } for name, edit in edits.items(): with self.subTest(name): vm = wvmInstance.__new__(wvmInstance) vm.wvm = MagicMock() vm._XMLDesc = MagicMock(return_value=xml) edit(vm) self.assertIn("vm """ class DeviceEditsByStateTestCase(unittest.TestCase): """Disk, NIC and agent channel changes reach the running definition whenever the VM is active, paused included, and the persistent one always. An attach is one call for both; a removal is one per definition, from that definition's own XML.""" EDITS = { "attach_disk": ("attachDeviceFlags", lambda vm: vm.attach_disk("vdb", "/var/lib/libvirt/images/d.qcow2")), "add_network": ("attachDeviceFlags", lambda vm: vm.add_network("52:54:00:00:00:09", "default")), "add_guest_agent": ("attachDeviceFlags", lambda vm: vm.add_guest_agent()), "remove_guest_agent": ("detachDeviceFlags", lambda vm: vm.remove_guest_agent()), } ATTACHES = ("attach_disk", "add_network", "add_guest_agent") def affected(self, state, active): from libvirt import VIR_DOMAIN_AFFECT_CONFIG, VIR_DOMAIN_AFFECT_LIVE names = {VIR_DOMAIN_AFFECT_LIVE: "live", VIR_DOMAIN_AFFECT_CONFIG: "config", VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG: "live+config"} result = {} for name, (method, edit) in self.EDITS.items(): vm = wvmInstance.__new__(wvmInstance) vm.instance = MagicMock() vm.instance.isActive.return_value = active vm.get_status = MagicMock(return_value=state) vm._XMLDesc = MagicMock(return_value=AGENT_DOMAIN) edit(vm) result[name] = [names[c.args[1]] for c in getattr(vm.instance, method).call_args_list] return result def test_paused_vm(self): for name, affected in self.affected(state=3, active=True).items(): self.assertEqual(affected, ["live+config"] if name in self.ATTACHES else ["live", "config"], name) def test_running_vm(self): for name, affected in self.affected(state=1, active=True).items(): self.assertEqual(affected, ["live+config"] if name in self.ATTACHES else ["live", "config"], name) def test_stopped_vm(self): for name, affected in self.affected(state=5, active=False).items(): self.assertEqual(affected, ["config"], name) def test_a_refused_attach_is_not_tried_again(self): from libvirt import libvirtError for name in self.ATTACHES: with self.subTest(name): vm = wvmInstance.__new__(wvmInstance) vm.instance = MagicMock() vm.instance.isActive.return_value = True vm.instance.attachDeviceFlags.side_effect = libvirtError("target sda already exists") with self.assertRaises(libvirtError): self.EDITS[name][1](vm) vm.instance.attachDeviceFlags.assert_called_once() if __name__ == "__main__": unittest.main()