SHA256
1
0
forked from pool/salt
salt/virt-enhancements.patch

1603 lines
62 KiB
Diff

From 340570af70f48b2e97a2e0b863fd819f85e92cb7 Mon Sep 17 00:00:00 2001
From: Cedric Bosdonnat <cbosdonnat@suse.com>
Date: Mon, 8 Feb 2021 16:42:47 +0100
Subject: [PATCH] virt enhancements
3002.2 Xen spicevmc, DNS SRV records backports (#314)
* Fix virtual network generated DNS XML for SRV records
libvirt network's srv element doesn't take a `name` property but a
`service` one.
* Add missing property in virt.network_define dns srv doc
* virt: convert spice generation tests to pytests
* virt: don't add spicevmc channel to Xen VMs
Xen fully virtualized VMs with spicevmc channel fail to start, so better
not write it out in such cases.
* virt: inverse the remaining asserts in pytests
virt.network_update: handle missing ipv4 netmask attribute (#328)
In the libvirt definition, the IPv4 netmask XML attribute may be
replaced by the prefix one. Handle this situation gracefully rather than
miserably failing.
Handle volumes on stopped pools in virt.vm_info (#373)
For VMs having at least a disk on a stopped volume, we don't want the
user to get an exception when running virt.vm_info. Instead just provide
less information.
virt: use /dev/kvm to detect KVM (#383)
checking for kvm_* modules to be loaded is not robust enough since the
kernel could be compiled with builtin modules. /dev/kvm is much more
reliable.
virt: pass emulator when getting domain capabilities from libvirt (#394)
On aarch64, for some emulated architectures like armv6l libvirt needs to
have the emulator path to properly return the domain capabilities.
Passing it will avoid virt.all_capabilities to fail on such
architectures.
---
changelog/59416.fixed | 1 +
changelog/59692.fixed | 1 +
changelog/60132.fixed | 1 +
changelog/60419.fixed | 1 +
changelog/60491.fixed | 1 +
salt/modules/virt.py | 92 +++++----
salt/templates/virt/libvirt_domain.jinja | 2 +-
.../pytests/unit/modules/virt/test_domain.py | 185 +++++++++++++-----
.../pytests/unit/modules/virt/test_helpers.py | 6 +-
tests/pytests/unit/modules/virt/test_host.py | 23 ++-
.../pytests/unit/modules/virt/test_network.py | 70 ++++---
tests/pytests/unit/states/virt/test_domain.py | 144 +++++++-------
.../pytests/unit/states/virt/test_network.py | 88 ++++-----
tests/unit/modules/test_virt.py | 63 +-----
14 files changed, 371 insertions(+), 307 deletions(-)
create mode 100644 changelog/59416.fixed
create mode 100644 changelog/59692.fixed
create mode 100644 changelog/60132.fixed
create mode 100644 changelog/60419.fixed
create mode 100644 changelog/60491.fixed
diff --git a/changelog/59416.fixed b/changelog/59416.fixed
new file mode 100644
index 0000000000..820124e99a
--- /dev/null
+++ b/changelog/59416.fixed
@@ -0,0 +1 @@
+Don't create spicevmc channel for Xen virtual machines
diff --git a/changelog/59692.fixed b/changelog/59692.fixed
new file mode 100644
index 0000000000..b4f4533ccc
--- /dev/null
+++ b/changelog/59692.fixed
@@ -0,0 +1 @@
+Don't fail updating network without netmask ip attribute
diff --git a/changelog/60132.fixed b/changelog/60132.fixed
new file mode 100644
index 0000000000..1e3bc96b98
--- /dev/null
+++ b/changelog/60132.fixed
@@ -0,0 +1 @@
+Gracefuly handle errors in virt.vm_info
diff --git a/changelog/60419.fixed b/changelog/60419.fixed
new file mode 100644
index 0000000000..44c782da48
--- /dev/null
+++ b/changelog/60419.fixed
@@ -0,0 +1 @@
+Check for /dev/kvm to detect KVM hypervisor.
diff --git a/changelog/60491.fixed b/changelog/60491.fixed
new file mode 100644
index 0000000000..256d29b5fb
--- /dev/null
+++ b/changelog/60491.fixed
@@ -0,0 +1 @@
+Pass emulator path to get guest capabilities from libvirt
diff --git a/salt/modules/virt.py b/salt/modules/virt.py
index 17e3ba7b9b..8c0d743ba1 100644
--- a/salt/modules/virt.py
+++ b/salt/modules/virt.py
@@ -516,41 +516,50 @@ def _get_disks(conn, dom):
def _get_disk_volume_data(pool_name, volume_name):
qemu_target = "{}/{}".format(pool_name, volume_name)
pool = conn.storagePoolLookupByName(pool_name)
- vol = pool.storageVolLookupByName(volume_name)
- vol_info = vol.info()
- extra_properties = {
- "virtual size": vol_info[1],
- "disk size": vol_info[2],
- }
-
- backing_files = [
- {
- "file": node.find("source").get("file"),
- "file format": node.find("format").get("type"),
+ extra_properties = {}
+ try:
+ vol = pool.storageVolLookupByName(volume_name)
+ vol_info = vol.info()
+ extra_properties = {
+ "virtual size": vol_info[1],
+ "disk size": vol_info[2],
}
- for node in elem.findall(".//backingStore[source]")
- ]
- if backing_files:
- # We had the backing files in a flat list, nest them again.
- extra_properties["backing file"] = backing_files[0]
- parent = extra_properties["backing file"]
- for sub_backing_file in backing_files[1:]:
- parent["backing file"] = sub_backing_file
- parent = sub_backing_file
+ backing_files = [
+ {
+ "file": node.find("source").get("file"),
+ "file format": node.find("format").get("type"),
+ }
+ for node in elem.findall(".//backingStore[source]")
+ ]
- else:
- # In some cases the backing chain is not displayed by the domain definition
- # Try to see if we have some of it in the volume definition.
- vol_desc = ElementTree.fromstring(vol.XMLDesc())
- backing_path = vol_desc.find("./backingStore/path")
- backing_format = vol_desc.find("./backingStore/format")
- if backing_path is not None:
- extra_properties["backing file"] = {"file": backing_path.text}
- if backing_format is not None:
- extra_properties["backing file"][
- "file format"
- ] = backing_format.get("type")
+ if backing_files:
+ # We had the backing files in a flat list, nest them again.
+ extra_properties["backing file"] = backing_files[0]
+ parent = extra_properties["backing file"]
+ for sub_backing_file in backing_files[1:]:
+ parent["backing file"] = sub_backing_file
+ parent = sub_backing_file
+
+ else:
+ # In some cases the backing chain is not displayed by the domain definition
+ # Try to see if we have some of it in the volume definition.
+ vol_desc = ElementTree.fromstring(vol.XMLDesc())
+ backing_path = vol_desc.find("./backingStore/path")
+ backing_format = vol_desc.find("./backingStore/format")
+ if backing_path is not None:
+ extra_properties["backing file"] = {
+ "file": backing_path.text
+ }
+ if backing_format is not None:
+ extra_properties["backing file"][
+ "file format"
+ ] = backing_format.get("type")
+ except libvirt.libvirtError:
+ # The volume won't be found if the pool is not started, just output less infos
+ log.info(
+ "Couldn't extract all volume informations: pool is likely not running or refreshed"
+ )
return (qemu_target, extra_properties)
if disk_type == "file":
@@ -5908,12 +5917,7 @@ def _is_kvm_hyper():
"""
Returns a bool whether or not this node is a KVM hypervisor
"""
- try:
- with salt.utils.files.fopen("/proc/modules") as fp_:
- if "kvm_" not in salt.utils.stringutils.to_unicode(fp_.read()):
- return False
- except OSError:
- # No /proc/modules? Are we on Windows? Or Solaris?
+ if not os.path.exists("/dev/kvm"):
return False
return "libvirtd" in __salt__["cmd.run"](__grains__["ps"])
@@ -6936,7 +6940,11 @@ def all_capabilities(**kwargs):
host_caps = ElementTree.fromstring(conn.getCapabilities())
domains = [
[
- (guest.get("arch", {}).get("name", None), key)
+ (
+ guest.get("arch", {}).get("name", None),
+ key,
+ guest.get("arch", {}).get("emulator", None),
+ )
for key in guest.get("arch", {}).get("domains", {}).keys()
]
for guest in [
@@ -6954,10 +6962,10 @@ def all_capabilities(**kwargs):
"domains": [
_parse_domain_caps(
ElementTree.fromstring(
- conn.getDomainCapabilities(None, arch, None, domain)
+ conn.getDomainCapabilities(emulator, arch, None, domain)
)
)
- for (arch, domain) in flattened
+ for (arch, domain, emulator) in flattened
],
}
return result
@@ -7584,7 +7592,7 @@ def network_update(
if node.get("family", "ipv4") == "ipv4"
]
for ip_node in ipv4_nodes:
- netmask = ip_node.attrib.pop("netmask")
+ netmask = ip_node.attrib.pop("netmask", None)
if netmask:
address = ipaddress.ip_network(
"{}/{}".format(ip_node.get("address"), netmask), strict=False
diff --git a/salt/templates/virt/libvirt_domain.jinja b/salt/templates/virt/libvirt_domain.jinja
index 4603dfd8de..6772b0db56 100644
--- a/salt/templates/virt/libvirt_domain.jinja
+++ b/salt/templates/virt/libvirt_domain.jinja
@@ -285,7 +285,7 @@
autoport='{{ yesno(not graphics.port and not graphics.tls_port) }}'>
<listen type='{{ graphics.listen.type }}'{{ opt_attribute(graphics.listen, "address") }}/>
</graphics>
- {%- if graphics.type == "spice" %}
+ {%- if graphics.type == "spice" and hypervisor in ["qemu", "kvm"] %}
<channel type='spicevmc'>
<target type='virtio' name='com.redhat.spice.0'/>
</channel>
diff --git a/tests/pytests/unit/modules/virt/test_domain.py b/tests/pytests/unit/modules/virt/test_domain.py
index 3301b94d6d..9a1b2814f8 100644
--- a/tests/pytests/unit/modules/virt/test_domain.py
+++ b/tests/pytests/unit/modules/virt/test_domain.py
@@ -140,13 +140,14 @@ def test_update_xen_disk_volumes(make_mock_vm, make_mock_storage_pool):
assert ret["definition"]
virt.libvirt.openAuth().defineXML = virt.libvirt.openAuth().defineXML
setxml = ET.fromstring(virt.libvirt.openAuth().defineXML.call_args[0][0])
- assert "block" == setxml.find(".//disk[3]").get("type")
- assert "/path/to/vdb/vdb1" == setxml.find(".//disk[3]/source").get("dev")
+ assert setxml.find(".//disk[3]").get("type") == "block"
+ assert setxml.find(".//disk[3]/source").get("dev") == "/path/to/vdb/vdb1"
# Note that my_vm-file-data was not an existing volume before the update
- assert "file" == setxml.find(".//disk[4]").get("type")
- assert "/path/to/default/my_vm_file-data" == setxml.find(".//disk[4]/source").get(
- "file"
+ assert setxml.find(".//disk[4]").get("type") == "file"
+ assert (
+ setxml.find(".//disk[4]/source").get("file")
+ == "/path/to/default/my_vm_file-data"
)
@@ -191,6 +192,11 @@ def test_get_disks(make_mock_vm, make_mock_storage_pool):
<alias name='virtio-disk0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</disk>
+ <disk type='volume' device='disk'>
+ <driver name='qemu' type='qcow2' cache='none' io='native'/>
+ <source pool='stopped' volume='vm05_data'/>
+ <target dev='vdd' bus='virtio'/>
+ </disk>
<disk type='network' device='cdrom'>
<driver name='qemu' type='raw' cache='none' io='native'/>
<source protocol='http' name='/pub/iso/myimage.iso' query='foo=bar&amp;baz=flurb' index='1'>
@@ -204,11 +210,12 @@ def test_get_disks(make_mock_vm, make_mock_storage_pool):
</devices>
</domain>
"""
- domain_mock = make_mock_vm(vm_def)
+ make_mock_vm(vm_def)
pool_mock = make_mock_storage_pool(
"default", "dir", ["srv01_system", "srv01_data", "vm05_system"]
)
+ make_mock_storage_pool("stopped", "dir", [])
# Append backing store to srv01_data volume XML description
srv1data_mock = pool_mock.storageVolLookupByName("srv01_data")
@@ -255,6 +262,7 @@ def test_get_disks(make_mock_vm, make_mock_storage_pool):
},
},
},
+ "vdd": {"type": "disk", "file": "stopped/vm05_data", "file format": "qcow2"},
"hda": {
"type": "cdrom",
"file format": "raw",
@@ -322,7 +330,7 @@ def test_get_disk_convert_volumes(make_mock_vm, make_mock_storage_pool):
subprocess_mock.Popen = popen_mock
with patch.dict(virt.__dict__, {"subprocess": subprocess_mock}):
- assert {
+ assert virt.get_disks("srv01") == {
"vda": {
"type": "disk",
"file": "default/srv01_system",
@@ -345,7 +353,7 @@ def test_get_disk_convert_volumes(make_mock_vm, make_mock_storage_pool):
"disk size": 340525056,
"virtual size": 214748364800,
},
- } == virt.get_disks("srv01")
+ }
def test_update_approx_mem(make_mock_vm):
@@ -388,7 +396,7 @@ def test_gen_hypervisor_features():
hypervisor_features={"kvm-hint-dedicated": True},
)
root = ET.fromstring(xml_data)
- assert "on" == root.find("features/kvm/hint-dedicated").attrib["state"]
+ assert root.find("features/kvm/hint-dedicated").attrib["state"] == "on"
def test_update_hypervisor_features(make_mock_vm):
@@ -423,7 +431,7 @@ def test_update_hypervisor_features(make_mock_vm):
ret = virt.update("my_vm", hypervisor_features={"kvm-hint-dedicated": False})
assert ret["definition"]
setxml = ET.fromstring(virt.libvirt.openAuth().defineXML.call_args[0][0])
- assert "off" == setxml.find("features/kvm/hint-dedicated").get("state")
+ assert setxml.find("features/kvm/hint-dedicated").get("state") == "off"
# Add the features
xml_def = """
@@ -442,7 +450,7 @@ def test_update_hypervisor_features(make_mock_vm):
ret = virt.update("my_vm", hypervisor_features={"kvm-hint-dedicated": True})
assert ret["definition"]
setxml = ET.fromstring(virt.libvirt.openAuth().defineXML.call_args[0][0])
- assert "on" == setxml.find("features/kvm/hint-dedicated").get("state")
+ assert setxml.find("features/kvm/hint-dedicated").get("state") == "on"
def test_gen_clock():
@@ -463,8 +471,8 @@ def test_gen_clock():
clock={"adjustment": 3600, "utc": False},
)
root = ET.fromstring(xml_data)
- assert "localtime" == root.find("clock").get("offset")
- assert "3600" == root.find("clock").get("adjustment")
+ assert root.find("clock").get("offset") == "localtime"
+ assert root.find("clock").get("adjustment") == "3600"
# Specific timezone
xml_data = virt._gen_xml(
@@ -480,8 +488,8 @@ def test_gen_clock():
clock={"timezone": "CEST"},
)
root = ET.fromstring(xml_data)
- assert "timezone" == root.find("clock").get("offset")
- assert "CEST" == root.find("clock").get("timezone")
+ assert root.find("clock").get("offset") == "timezone"
+ assert root.find("clock").get("timezone") == "CEST"
# UTC
xml_data = virt._gen_xml(
@@ -497,7 +505,7 @@ def test_gen_clock():
clock={"utc": True},
)
root = ET.fromstring(xml_data)
- assert "utc" == root.find("clock").get("offset")
+ assert root.find("clock").get("offset") == "utc"
# Timers
xml_data = virt._gen_xml(
@@ -524,14 +532,16 @@ def test_gen_clock():
},
)
root = ET.fromstring(xml_data)
- assert "utc" == root.find("clock").get("offset")
- assert "3504000000" == root.find("clock/timer[@name='tsc']").get("frequency")
- assert "native" == root.find("clock/timer[@name='tsc']").get("mode")
- assert "catchup" == root.find("clock/timer[@name='rtc']").get("tickpolicy")
- assert {"slew": "4636", "threshold": "123", "limit": "2342"} == root.find(
- "clock/timer[@name='rtc']/catchup"
- ).attrib
- assert "no" == root.find("clock/timer[@name='hpet']").get("present")
+ assert root.find("clock").get("offset") == "utc"
+ assert root.find("clock/timer[@name='tsc']").get("frequency") == "3504000000"
+ assert root.find("clock/timer[@name='tsc']").get("mode") == "native"
+ assert root.find("clock/timer[@name='rtc']").get("tickpolicy") == "catchup"
+ assert root.find("clock/timer[@name='rtc']/catchup").attrib == {
+ "slew": "4636",
+ "threshold": "123",
+ "limit": "2342",
+ }
+ assert root.find("clock/timer[@name='hpet']").get("present") == "no"
def test_update_clock(make_mock_vm):
@@ -590,21 +600,23 @@ def test_update_clock(make_mock_vm):
)
assert ret["definition"]
setxml = ET.fromstring(virt.libvirt.openAuth().defineXML.call_args[0][0])
- assert "timezone" == setxml.find("clock").get("offset")
- assert "CEST" == setxml.find("clock").get("timezone")
- assert {"rtc", "hpet"} == {t.get("name") for t in setxml.findall("clock/timer")}
- assert "catchup" == setxml.find("clock/timer[@name='rtc']").get("tickpolicy")
- assert "wall" == setxml.find("clock/timer[@name='rtc']").get("track")
- assert {"slew": "4636", "threshold": "123", "limit": "2342"} == setxml.find(
- "clock/timer[@name='rtc']/catchup"
- ).attrib
- assert "yes" == setxml.find("clock/timer[@name='hpet']").get("present")
+ assert setxml.find("clock").get("offset") == "timezone"
+ assert setxml.find("clock").get("timezone") == "CEST"
+ assert {t.get("name") for t in setxml.findall("clock/timer")} == {"rtc", "hpet"}
+ assert setxml.find("clock/timer[@name='rtc']").get("tickpolicy") == "catchup"
+ assert setxml.find("clock/timer[@name='rtc']").get("track") == "wall"
+ assert setxml.find("clock/timer[@name='rtc']/catchup").attrib == {
+ "slew": "4636",
+ "threshold": "123",
+ "limit": "2342",
+ }
+ assert setxml.find("clock/timer[@name='hpet']").get("present") == "yes"
# Revert to UTC
ret = virt.update("my_vm", clock={"utc": True, "adjustment": None, "timers": None})
assert ret["definition"]
setxml = ET.fromstring(virt.libvirt.openAuth().defineXML.call_args[0][0])
- assert {"offset": "utc"} == setxml.find("clock").attrib
+ assert setxml.find("clock").attrib == {"offset": "utc"}
assert setxml.find("clock/timer") is None
@@ -630,7 +642,7 @@ def test_update_stop_on_reboot_reset(make_mock_vm):
assert ret["definition"]
virt.libvirt.openAuth().defineXML = virt.libvirt.openAuth().defineXML
setxml = ET.fromstring(virt.libvirt.openAuth().defineXML.call_args[0][0])
- assert "restart" == setxml.find("./on_reboot").text
+ assert setxml.find("./on_reboot").text == "restart"
def test_update_stop_on_reboot(make_mock_vm):
@@ -654,7 +666,7 @@ def test_update_stop_on_reboot(make_mock_vm):
assert ret["definition"]
virt.libvirt.openAuth().defineXML = virt.libvirt.openAuth().defineXML
setxml = ET.fromstring(virt.libvirt.openAuth().defineXML.call_args[0][0])
- assert "destroy" == setxml.find("./on_reboot").text
+ assert setxml.find("./on_reboot").text == "destroy"
def test_init_no_stop_on_reboot(make_capabilities):
@@ -667,7 +679,7 @@ def test_init_no_stop_on_reboot(make_capabilities):
virt.init("test_vm", 2, 2048, start=False)
virt.libvirt.openAuth().defineXML = virt.libvirt.openAuth().defineXML
setxml = ET.fromstring(virt.libvirt.openAuth().defineXML.call_args[0][0])
- assert "restart" == setxml.find("./on_reboot").text
+ assert setxml.find("./on_reboot").text == "restart"
def test_init_stop_on_reboot(make_capabilities):
@@ -680,7 +692,7 @@ def test_init_stop_on_reboot(make_capabilities):
virt.init("test_vm", 2, 2048, stop_on_reboot=True, start=False)
virt.libvirt.openAuth().defineXML = virt.libvirt.openAuth().defineXML
setxml = ET.fromstring(virt.libvirt.openAuth().defineXML.call_args[0][0])
- assert "destroy" == setxml.find("./on_reboot").text
+ assert setxml.find("./on_reboot").text == "destroy"
def test_init_hostdev_usb(make_capabilities, make_mock_device):
@@ -722,8 +734,8 @@ def test_init_hostdev_usb(make_capabilities, make_mock_device):
</hostdev>
"""
)
- assert expected_xml == strip_xml(
- ET.tostring(setxml.find("./devices/hostdev"))
+ assert (
+ strip_xml(ET.tostring(setxml.find("./devices/hostdev"))) == expected_xml
)
@@ -764,8 +776,8 @@ def test_init_hostdev_pci(make_capabilities, make_mock_device):
</hostdev>
"""
)
- assert expected_xml == strip_xml(
- ET.tostring(setxml.find("./devices/hostdev"))
+ assert (
+ strip_xml(ET.tostring(setxml.find("./devices/hostdev"))) == expected_xml
)
@@ -938,11 +950,11 @@ def test_update_hostdev_changes(running, live, make_mock_device, make_mock_vm, t
ET.tostring(xmlutil.strip_spaces(node))
for node in set_xml.findall("./devices/hostdev")
]
- assert [usb_device_xml] == actual_hostdevs
+ assert actual_hostdevs == [usb_device_xml]
if not test and live:
attach_xml = strip_xml(domain_mock.attachDevice.call_args[0][0])
- assert usb_device_xml == attach_xml
+ assert attach_xml == usb_device_xml
pci_device_xml = strip_xml(
"""
@@ -955,7 +967,7 @@ def test_update_hostdev_changes(running, live, make_mock_device, make_mock_vm, t
"""
)
detach_xml = strip_xml(domain_mock.detachDevice.call_args[0][0])
- assert pci_device_xml == detach_xml
+ assert detach_xml == pci_device_xml
else:
domain_mock.attachDevice.assert_not_called()
domain_mock.detachDevice.assert_not_called()
@@ -1012,14 +1024,16 @@ def test_diff_nics():
"""
).findall("interface")
ret = virt._diff_interface_lists(old_nics, new_nics)
- assert ["52:54:00:39:02:b1"] == [
- nic.find("mac").get("address") for nic in ret["unchanged"]
+ assert [nic.find("mac").get("address") for nic in ret["unchanged"]] == [
+ "52:54:00:39:02:b1"
]
- assert ["52:54:00:39:02:b2", "52:54:00:39:02:b4"] == [
- nic.find("mac").get("address") for nic in ret["new"]
+ assert [nic.find("mac").get("address") for nic in ret["new"]] == [
+ "52:54:00:39:02:b2",
+ "52:54:00:39:02:b4",
]
- assert ["52:54:00:39:02:b2", "52:54:00:39:02:b3"] == [
- nic.find("mac").get("address") for nic in ret["deleted"]
+ assert [nic.find("mac").get("address") for nic in ret["deleted"]] == [
+ "52:54:00:39:02:b2",
+ "52:54:00:39:02:b3",
]
@@ -1066,8 +1080,9 @@ def test_diff_nics_live_nochange():
"""
)
ret = virt._diff_interface_lists(old_nics, new_nics)
- assert ["52:54:00:03:02:15", "52:54:00:ea:2e:89"] == [
- nic.find("mac").get("address") for nic in ret["unchanged"]
+ assert [nic.find("mac").get("address") for nic in ret["unchanged"]] == [
+ "52:54:00:03:02:15",
+ "52:54:00:ea:2e:89",
]
@@ -1350,7 +1365,7 @@ def test_update_bootdev_unchanged(make_mock_vm, boot_dev):
"""
)
ret = virt.update("my_vm", boot_dev=boot_dev)
- assert (boot_dev != "hd") == ret["definition"]
+ assert ret["definition"] == (boot_dev != "hd")
if boot_dev == "hd":
virt.libvirt.openAuth().defineXML.assert_not_called()
else:
@@ -2128,3 +2143,65 @@ def test_update_failure(make_mock_vm):
"disk": {"attached": [], "detached": [], "updated": []},
"interface": {"attached": [], "detached": []},
}
+
+@pytest.mark.parametrize("hypervisor", ["kvm", "xen"])
+def test_gen_xml_spice_default(hypervisor):
+ """
+ Test virt._gen_xml() with default spice graphics device
+ """
+ xml_data = virt._gen_xml(
+ virt.libvirt.openAuth.return_value,
+ "hello",
+ 1,
+ 512,
+ {},
+ {},
+ hypervisor,
+ "hvm",
+ "x86_64",
+ graphics={"type": "spice"},
+ )
+ root = ET.fromstring(xml_data)
+ assert root.find("devices/graphics").attrib["type"] == "spice"
+ assert root.find("devices/graphics").attrib["autoport"] == "yes"
+ assert root.find("devices/graphics").attrib["listen"] == "0.0.0.0"
+ assert root.find("devices/graphics/listen").attrib["type"] == "address"
+ assert root.find("devices/graphics/listen").attrib["address"] == "0.0.0.0"
+ if hypervisor == "kvm":
+ assert (
+ root.find(".//channel[@type='spicevmc']/target").get("name")
+ == "com.redhat.spice.0"
+ )
+ else:
+ assert root.find(".//channel[@type='spicevmc']") is None
+
+
+def test_gen_xml_spice():
+ """
+ Test virt._gen_xml() with spice graphics device
+ """
+ xml_data = virt._gen_xml(
+ virt.libvirt.openAuth.return_value,
+ "hello",
+ 1,
+ 512,
+ {},
+ {},
+ "kvm",
+ "hvm",
+ "x86_64",
+ graphics={
+ "type": "spice",
+ "port": 1234,
+ "tls_port": 5678,
+ "listen": {"type": "none"},
+ },
+ )
+ root = ET.fromstring(xml_data)
+ assert root.find("devices/graphics").attrib["type"] == "spice"
+ assert root.find("devices/graphics").attrib["autoport"] == "no"
+ assert root.find("devices/graphics").attrib["port"] == "1234"
+ assert root.find("devices/graphics").attrib["tlsPort"] == "5678"
+ assert "listen" not in root.find("devices/graphics").attrib
+ assert root.find("devices/graphics/listen").attrib["type"] == "none"
+ assert "address" not in root.find("devices/graphics/listen").attrib
diff --git a/tests/pytests/unit/modules/virt/test_helpers.py b/tests/pytests/unit/modules/virt/test_helpers.py
index 4932d84ec4..e537b87aab 100644
--- a/tests/pytests/unit/modules/virt/test_helpers.py
+++ b/tests/pytests/unit/modules/virt/test_helpers.py
@@ -13,12 +13,12 @@ def append_to_XMLDesc(mocked, fragment):
mocked.XMLDesc.return_value = ET.tostring(xml_doc)
-def assert_xml_equals(expected, actual):
+def assert_xml_equals(actual, expected):
"""
Assert that two ElementTree nodes are equal
"""
- assert xmlutil.to_dict(xmlutil.strip_spaces(expected), True) == xmlutil.to_dict(
- xmlutil.strip_spaces(actual), True
+ assert xmlutil.to_dict(xmlutil.strip_spaces(actual), True) == xmlutil.to_dict(
+ xmlutil.strip_spaces(expected), True
)
diff --git a/tests/pytests/unit/modules/virt/test_host.py b/tests/pytests/unit/modules/virt/test_host.py
index 555deb23bb..c5cadb8aa0 100644
--- a/tests/pytests/unit/modules/virt/test_host.py
+++ b/tests/pytests/unit/modules/virt/test_host.py
@@ -1,5 +1,8 @@
+import os.path
+
import pytest
import salt.modules.virt as virt
+from tests.support.mock import MagicMock, patch
from .conftest import loader_modules_config
@@ -173,7 +176,7 @@ def test_node_devices(make_mock_device):
]
virt.libvirt.openAuth().listAllDevices.return_value = mock_devs
- assert [
+ assert virt.node_devices() == [
{
"name": "pci_1002_71c4",
"caps": "pci",
@@ -216,4 +219,20 @@ def test_node_devices(make_mock_device):
"state": "down",
"device name": "pci_0000_02_10_7",
},
- ] == virt.node_devices()
+ ]
+
+
+@pytest.mark.parametrize(
+ "dev_kvm, libvirtd", [(True, True), (False, False), (True, False)]
+)
+def test_is_kvm(dev_kvm, libvirtd):
+ """
+ Test the virt._is_kvm_hyper() function
+ """
+ with patch.dict(os.path.__dict__, {"exists": MagicMock(return_value=dev_kvm)}):
+ processes = ["libvirtd"] if libvirtd else []
+ with patch.dict(virt.__grains__, {"ps": MagicMock(return_value="foo")}):
+ with patch.dict(
+ virt.__salt__, {"cmd.run": MagicMock(return_value=processes)}
+ ):
+ assert virt._is_kvm_hyper() == (dev_kvm and libvirtd)
diff --git a/tests/pytests/unit/modules/virt/test_network.py b/tests/pytests/unit/modules/virt/test_network.py
index ba592694c0..5ab4e0a449 100644
--- a/tests/pytests/unit/modules/virt/test_network.py
+++ b/tests/pytests/unit/modules/virt/test_network.py
@@ -19,10 +19,10 @@ def test_gen_xml():
"""
xml_data = virt._gen_net_xml("network", "main", "bridge", "openvswitch")
root = ET.fromstring(xml_data)
- assert "network" == root.find("name").text
- assert "main" == root.find("bridge").attrib["name"]
- assert "bridge" == root.find("forward").attrib["mode"]
- assert "openvswitch" == root.find("virtualport").attrib["type"]
+ assert root.find("name").text == "network"
+ assert root.find("bridge").attrib["name"] == "main"
+ assert root.find("forward").attrib["mode"] == "bridge"
+ assert root.find("virtualport").attrib["type"] == "openvswitch"
def test_gen_xml_nat():
@@ -69,9 +69,9 @@ def test_gen_xml_nat():
mtu=9000,
)
root = ET.fromstring(xml_data)
- assert "network" == root.find("name").text
- assert "main" == root.find("bridge").attrib["name"]
- assert "nat" == root.find("forward").attrib["mode"]
+ assert root.find("name").text == "network"
+ assert root.find("bridge").attrib["name"] == "main"
+ assert root.find("forward").attrib["mode"] == "nat"
expected_ipv4 = ET.fromstring(
"""
<ip family='ipv4' address='192.168.2.1' prefix='24'>
@@ -85,7 +85,7 @@ def test_gen_xml_nat():
</ip>
"""
)
- assert_xml_equals(expected_ipv4, root.find("./ip[@address='192.168.2.1']"))
+ assert_xml_equals(root.find("./ip[@address='192.168.2.1']"), expected_ipv4)
expected_ipv6 = ET.fromstring(
"""
@@ -97,7 +97,7 @@ def test_gen_xml_nat():
</ip>
"""
)
- assert_xml_equals(expected_ipv6, root.find("./ip[@address='2001:db8:ca2:2::1']"))
+ assert_xml_equals(root.find("./ip[@address='2001:db8:ca2:2::1']"), expected_ipv6)
actual_nat = ET.tostring(xmlutil.strip_spaces(root.find("./forward/nat")))
expected_nat = strip_xml(
@@ -108,10 +108,10 @@ def test_gen_xml_nat():
</nat>
"""
)
- assert expected_nat == actual_nat
+ assert actual_nat == expected_nat
- assert {"name": "acme.lab", "localOnly": "yes"} == root.find("./domain").attrib
- assert "9000" == root.find("mtu").get("size")
+ assert root.find("./domain").attrib == {"name": "acme.lab", "localOnly": "yes"}
+ assert root.find("mtu").get("size") == "9000"
def test_gen_xml_dns():
@@ -172,7 +172,7 @@ def test_gen_xml_dns():
</dns>
"""
)
- assert_xml_equals(expected_xml, root.find("./dns"))
+ assert_xml_equals(root.find("./dns"), expected_xml)
def test_gen_xml_isolated():
@@ -191,9 +191,11 @@ def test_gen_xml_passthrough_interfaces():
"network", "virbr0", "passthrough", None, interfaces="eth10 eth11 eth12",
)
root = ET.fromstring(xml_data)
- assert "passthrough" == root.find("forward").get("mode")
- assert ["eth10", "eth11", "eth12"] == [
- n.get("dev") for n in root.findall("forward/interface")
+ assert root.find("forward").get("mode") == "passthrough"
+ assert [n.get("dev") for n in root.findall("forward/interface")] == [
+ "eth10",
+ "eth11",
+ "eth12",
]
@@ -213,7 +215,7 @@ def test_gen_xml_hostdev_addresses():
</forward>
"""
)
- assert_xml_equals(expected_forward, root.find("./forward"))
+ assert_xml_equals(root.find("./forward"), expected_forward)
def test_gen_xml_hostdev_pf():
@@ -232,7 +234,7 @@ def test_gen_xml_hostdev_pf():
"""
)
actual_forward = ET.tostring(xmlutil.strip_spaces(root.find("./forward")))
- assert expected_forward == actual_forward
+ assert actual_forward == expected_forward
def test_gen_xml_openvswitch():
@@ -268,7 +270,7 @@ def test_gen_xml_openvswitch():
</network>
"""
)
- assert_xml_equals(expected_xml, ET.fromstring(xml_data))
+ assert_xml_equals(ET.fromstring(xml_data), expected_xml)
@pytest.mark.parametrize(
@@ -308,7 +310,7 @@ def test_define(make_mock_network, autostart, start):
"""
)
define_mock = virt.libvirt.openAuth().networkDefineXML
- assert expected_xml == strip_xml(define_mock.call_args[0][0])
+ assert strip_xml(define_mock.call_args[0][0]) == expected_xml
if autostart:
mock_network.setAutostart.assert_called_with(1)
@@ -364,8 +366,11 @@ def test_update_nat_nochange(make_mock_network):
define_mock.assert_not_called()
-@pytest.mark.parametrize("test", [True, False])
-def test_update_nat_change(make_mock_network, test):
+@pytest.mark.parametrize(
+ "test, netmask",
+ [(True, "netmask='255.255.255.0'"), (True, "prefix='24'"), (False, "prefix='24'")],
+)
+def test_update_nat_change(make_mock_network, test, netmask):
"""
Test updating a NAT network with changes
"""
@@ -378,13 +383,15 @@ def test_update_nat_change(make_mock_network, test):
<bridge name='virbr0' stp='on' delay='0'/>
<mac address='52:54:00:cd:49:6b'/>
<domain name='my.lab' localOnly='yes'/>
- <ip address='192.168.122.1' netmask='255.255.255.0'>
+ <ip address='192.168.122.1' {}>
<dhcp>
<range start='192.168.122.2' end='192.168.122.254'/>
</dhcp>
</ip>
</network>
- """
+ """.format(
+ netmask
+ )
)
assert virt.network_update(
"default",
@@ -417,7 +424,7 @@ def test_update_nat_change(make_mock_network, test):
</network>
"""
)
- assert expected_xml == strip_xml(define_mock.call_args[0][0])
+ assert strip_xml(define_mock.call_args[0][0]) == expected_xml
@pytest.mark.parametrize("change", [True, False], ids=["changed", "unchanged"])
@@ -438,11 +445,14 @@ def test_update_hostdev_pf(make_mock_network, change):
</network>
"""
)
- assert change == virt.network_update(
- "test-hostdev",
- None,
- "hostdev",
- physical_function="eth0" if not change else "eth1",
+ assert (
+ virt.network_update(
+ "test-hostdev",
+ None,
+ "hostdev",
+ physical_function="eth0" if not change else "eth1",
+ )
+ == change
)
define_mock = virt.libvirt.openAuth().networkDefineXML
if change:
diff --git a/tests/pytests/unit/states/virt/test_domain.py b/tests/pytests/unit/states/virt/test_domain.py
index a4ae8c0694..c705785bf5 100644
--- a/tests/pytests/unit/states/virt/test_domain.py
+++ b/tests/pytests/unit/states/virt/test_domain.py
@@ -21,14 +21,14 @@ def test_defined_no_change(test):
"virt.init": init_mock,
},
):
- assert {
+ assert virt.defined("myvm") == {
"name": "myvm",
"changes": {"myvm": {"definition": False}},
"result": True,
"comment": "Domain myvm unchanged",
- } == virt.defined("myvm")
+ }
init_mock.assert_not_called()
- assert [domain_update_call("myvm", test=test)] == update_mock.call_args_list
+ assert update_mock.call_args_list == [domain_update_call("myvm", test=test)]
def test_defined_new_with_connection(test):
@@ -72,12 +72,7 @@ def test_defined_new_with_connection(test):
{"type": "tcp", "port": 22223, "protocol": "telnet"},
{"type": "pty"},
]
- assert {
- "name": "myvm",
- "result": True if not test else None,
- "changes": {"myvm": {"definition": True}},
- "comment": "Domain myvm defined",
- } == virt.defined(
+ assert virt.defined(
"myvm",
cpu=2,
mem=2048,
@@ -103,7 +98,12 @@ def test_defined_new_with_connection(test):
serials=serials,
consoles=consoles,
host_devices=["pci_0000_00_17_0"],
- )
+ ) == {
+ "name": "myvm",
+ "result": True if not test else None,
+ "changes": {"myvm": {"definition": True}},
+ "comment": "Domain myvm defined",
+ }
if not test:
init_mock.assert_called_with(
"myvm",
@@ -160,16 +160,16 @@ def test_defined_update(test):
"initrd": "/root/f8-i386-initrd",
"cmdline": "console=ttyS0 ks=http://example.com/f8-i386/os/",
}
- assert {
+ assert virt.defined("myvm", cpu=2, boot=boot,) == {
"name": "myvm",
"changes": {"myvm": {"definition": True, "cpu": True}},
"result": True if not test else None,
"comment": "Domain myvm updated",
- } == virt.defined("myvm", cpu=2, boot=boot,)
+ }
init_mock.assert_not_called()
- assert [
+ assert update_mock.call_args_list == [
domain_update_call("myvm", cpu=2, test=test, boot=boot)
- ] == update_mock.call_args_list
+ ]
def test_defined_update_error(test):
@@ -189,7 +189,7 @@ def test_defined_update_error(test):
"virt.init": init_mock,
},
):
- assert {
+ assert virt.defined("myvm", cpu=2, boot_dev="cdrom hd") == {
"name": "myvm",
"changes": {
"myvm": {
@@ -200,7 +200,7 @@ def test_defined_update_error(test):
},
"result": True if not test else None,
"comment": "Domain myvm updated with live update(s) failures",
- } == virt.defined("myvm", cpu=2, boot_dev="cdrom hd")
+ }
init_mock.assert_not_called()
update_mock.assert_called_with(
"myvm",
@@ -245,16 +245,16 @@ def test_defined_update_definition_error(test):
"virt.init": init_mock,
},
):
- assert {
+ assert virt.defined("myvm", cpu=2) == {
"name": "myvm",
"changes": {},
"result": False,
"comment": "error message",
- } == virt.defined("myvm", cpu=2)
+ }
init_mock.assert_not_called()
- assert [
+ assert update_mock.call_args_list == [
domain_update_call("myvm", cpu=2, test=test)
- ] == update_mock.call_args_list
+ ]
@pytest.mark.parametrize("running", ["running", "shutdown"])
@@ -279,12 +279,12 @@ def test_running_no_change(test, running):
if running == "shutdown":
changes["started"] = True
comment = "Domain myvm started"
- assert {
+ assert virt.running("myvm") == {
"name": "myvm",
"result": True,
"changes": {"myvm": changes},
"comment": comment,
- } == virt.running("myvm")
+ }
if running == "shutdown" and not test:
start_mock.assert_called()
else:
@@ -326,12 +326,7 @@ def test_running_define(test):
"listen": {"type": "address", "address": "192.168.0.1"},
}
- assert {
- "name": "myvm",
- "result": True if not test else None,
- "changes": {"myvm": {"definition": True, "started": True}},
- "comment": "Domain myvm defined and started",
- } == virt.running(
+ assert virt.running(
"myvm",
cpu=2,
mem=2048,
@@ -353,7 +348,12 @@ def test_running_define(test):
connection="someconnection",
username="libvirtuser",
password="supersecret",
- )
+ ) == {
+ "name": "myvm",
+ "result": True if not test else None,
+ "changes": {"myvm": {"definition": True, "started": True}},
+ "comment": "Domain myvm defined and started",
+ }
if not test:
init_mock.assert_called_with(
"myvm",
@@ -412,12 +412,12 @@ def test_running_start_error():
"virt.list_domains": MagicMock(return_value=["myvm"]),
},
):
- assert {
+ assert virt.running("myvm") == {
"name": "myvm",
"changes": {"myvm": {"definition": False}},
"result": False,
"comment": "libvirt error msg",
- } == virt.running("myvm")
+ }
@pytest.mark.parametrize("running", ["running", "shutdown"])
@@ -441,14 +441,14 @@ def test_running_update(test, running):
changes = {"myvm": {"definition": True, "cpu": True}}
if running == "shutdown":
changes["myvm"]["started"] = True
- assert {
+ assert virt.running("myvm", cpu=2) == {
"name": "myvm",
"changes": changes,
"result": True if not test else None,
"comment": "Domain myvm updated"
if running == "running"
else "Domain myvm updated and started",
- } == virt.running("myvm", cpu=2)
+ }
if running == "shutdown" and not test:
start_mock.assert_called()
else:
@@ -470,12 +470,12 @@ def test_running_definition_error():
"virt.list_domains": MagicMock(return_value=["myvm"]),
},
):
- assert {
+ assert virt.running("myvm", cpu=3) == {
"name": "myvm",
"changes": {},
"result": False,
"comment": "error message",
- } == virt.running("myvm", cpu=3)
+ }
def test_running_update_error():
@@ -494,7 +494,7 @@ def test_running_update_error():
"virt.list_domains": MagicMock(return_value=["myvm"]),
},
):
- assert {
+ assert virt.running("myvm", cpu=2) == {
"name": "myvm",
"changes": {
"myvm": {
@@ -505,7 +505,7 @@ def test_running_update_error():
},
"result": True,
"comment": "Domain myvm updated with live update(s) failures",
- } == virt.running("myvm", cpu=2)
+ }
update_mock.assert_called_with(
"myvm",
cpu=2,
@@ -552,14 +552,14 @@ def test_stopped(test, running):
if running == "running":
changes = {"stopped": [{"domain": "myvm", "shutdown": True}]}
comment = "Machine has been shut down"
- assert {
+ assert virt.stopped(
+ "myvm", connection="myconnection", username="user", password="secret",
+ ) == {
"name": "myvm",
"changes": changes,
"comment": comment,
"result": True if not test or running == "shutdown" else None,
- } == virt.stopped(
- "myvm", connection="myconnection", username="user", password="secret",
- )
+ }
if not test and running == "running":
shutdown_mock.assert_called_with(
"myvm",
@@ -586,12 +586,12 @@ def test_stopped_error():
),
},
):
- assert {
+ assert virt.stopped("myvm") == {
"name": "myvm",
"changes": {"ignored": [{"domain": "myvm", "issue": "Some error"}]},
"result": False,
"comment": "No changes had happened",
- } == virt.stopped("myvm")
+ }
def test_stopped_not_existing(test):
@@ -603,12 +603,12 @@ def test_stopped_not_existing(test):
with patch.dict(
virt.__salt__, {"virt.list_domains": MagicMock(return_value=[])},
):
- assert {
+ assert virt.stopped("myvm") == {
"name": "myvm",
"changes": {},
"comment": "No changes had happened",
"result": False,
- } == virt.stopped("myvm")
+ }
@pytest.mark.parametrize("running", ["running", "shutdown"])
@@ -631,14 +631,14 @@ def test_powered_off(test, running):
if running == "running":
changes = {"unpowered": [{"domain": "myvm", "stop": True}]}
comment = "Machine has been powered off"
- assert {
+ assert virt.powered_off(
+ "myvm", connection="myconnection", username="user", password="secret",
+ ) == {
"name": "myvm",
"result": True if not test or running == "shutdown" else None,
"changes": changes,
"comment": comment,
- } == virt.powered_off(
- "myvm", connection="myconnection", username="user", password="secret",
- )
+ }
if not test and running == "running":
stop_mock.assert_called_with(
"myvm",
@@ -666,12 +666,12 @@ def test_powered_off_error():
),
},
):
- assert {
+ assert virt.powered_off("myvm") == {
"name": "myvm",
"result": False,
"changes": {"ignored": [{"domain": "myvm", "issue": "Some error"}]},
"comment": "No changes had happened",
- } == virt.powered_off("myvm")
+ }
def test_powered_off_not_existing():
@@ -686,12 +686,12 @@ def test_powered_off_not_existing():
ret.update(
{"changes": {}, "result": False, "comment": "No changes had happened"}
)
- assert {
+ assert virt.powered_off("myvm") == {
"name": "myvm",
"changes": {},
"result": False,
"comment": "No changes had happened",
- } == virt.powered_off("myvm")
+ }
def test_snapshot(test):
@@ -707,18 +707,18 @@ def test_snapshot(test):
"virt.snapshot": snapshot_mock,
},
):
- assert {
- "name": "myvm",
- "result": True if not test else None,
- "changes": {"saved": [{"domain": "myvm", "snapshot": True}]},
- "comment": "Snapshot has been taken",
- } == virt.snapshot(
+ assert virt.snapshot(
"myvm",
suffix="snap",
connection="myconnection",
username="user",
password="secret",
- )
+ ) == {
+ "name": "myvm",
+ "result": True if not test else None,
+ "changes": {"saved": [{"domain": "myvm", "snapshot": True}]},
+ "comment": "Snapshot has been taken",
+ }
if not test:
snapshot_mock.assert_called_with(
"myvm",
@@ -745,12 +745,12 @@ def test_snapshot_error():
),
},
):
- assert {
+ assert virt.snapshot("myvm") == {
"name": "myvm",
"result": False,
"changes": {"ignored": [{"domain": "myvm", "issue": "Some error"}]},
"comment": "No changes had happened",
- } == virt.snapshot("myvm")
+ }
def test_snapshot_not_existing(test):
@@ -761,12 +761,12 @@ def test_snapshot_not_existing(test):
with patch.dict(
virt.__salt__, {"virt.list_domains": MagicMock(return_value=[])}
):
- assert {
+ assert virt.snapshot("myvm") == {
"name": "myvm",
"changes": {},
"result": False,
"comment": "No changes had happened",
- } == virt.snapshot("myvm")
+ }
def test_rebooted(test):
@@ -782,14 +782,14 @@ def test_rebooted(test):
"virt.reboot": reboot_mock,
},
):
- assert {
+ assert virt.rebooted(
+ "myvm", connection="myconnection", username="user", password="secret",
+ ) == {
"name": "myvm",
"result": True if not test else None,
"changes": {"rebooted": [{"domain": "myvm", "reboot": True}]},
"comment": "Machine has been rebooted",
- } == virt.rebooted(
- "myvm", connection="myconnection", username="user", password="secret",
- )
+ }
if not test:
reboot_mock.assert_called_with(
"myvm",
@@ -816,12 +816,12 @@ def test_rebooted_error():
),
},
):
- assert {
+ assert virt.rebooted("myvm") == {
"name": "myvm",
"result": False,
"changes": {"ignored": [{"domain": "myvm", "issue": "Some error"}]},
"comment": "No changes had happened",
- } == virt.rebooted("myvm")
+ }
def test_rebooted_not_existing(test):
@@ -832,9 +832,9 @@ def test_rebooted_not_existing(test):
with patch.dict(
virt.__salt__, {"virt.list_domains": MagicMock(return_value=[])}
):
- assert {
+ assert virt.rebooted("myvm") == {
"name": "myvm",
"changes": {},
"result": False,
"comment": "No changes had happened",
- } == virt.rebooted("myvm")
+ }
diff --git a/tests/pytests/unit/states/virt/test_network.py b/tests/pytests/unit/states/virt/test_network.py
index 668eee0c64..a68acfa236 100644
--- a/tests/pytests/unit/states/virt/test_network.py
+++ b/tests/pytests/unit/states/virt/test_network.py
@@ -19,12 +19,7 @@ def test_network_defined_not_existing(test):
"virt.network_define": define_mock,
},
):
- assert {
- "name": "mynet",
- "changes": {"mynet": "Network defined"},
- "result": None if test else True,
- "comment": "Network mynet defined",
- } == virt.network_defined(
+ assert virt.network_defined(
"mynet",
"br2",
"bridge",
@@ -58,7 +53,12 @@ def test_network_defined_not_existing(test):
connection="myconnection",
username="user",
password="secret",
- )
+ ) == {
+ "name": "mynet",
+ "changes": {"mynet": "Network defined"},
+ "result": None if test else True,
+ "comment": "Network mynet defined",
+ }
if not test:
define_mock.assert_called_with(
"mynet",
@@ -117,16 +117,16 @@ def test_network_defined_no_change(test):
"virt.network_update": update_mock,
},
):
- assert {
+ assert virt.network_defined("mynet", "br2", "bridge") == {
"name": "mynet",
"changes": {},
"result": True,
"comment": "Network mynet unchanged",
- } == virt.network_defined("mynet", "br2", "bridge")
+ }
define_mock.assert_not_called()
- assert [
+ assert update_mock.call_args_list == [
network_update_call("mynet", "br2", "bridge", test=True)
- ] == update_mock.call_args_list
+ ]
def test_network_defined_change(test):
@@ -148,12 +148,7 @@ def test_network_defined_change(test):
"virt.network_set_autostart": autostart_mock,
},
):
- assert {
- "name": "mynet",
- "changes": {"mynet": "Network updated, autostart flag changed"},
- "result": None if test else True,
- "comment": "Network mynet updated, autostart flag changed",
- } == virt.network_defined(
+ assert virt.network_defined(
"mynet",
"br2",
"bridge",
@@ -187,7 +182,12 @@ def test_network_defined_change(test):
connection="myconnection",
username="user",
password="secret",
- )
+ ) == {
+ "name": "mynet",
+ "changes": {"mynet": "Network updated, autostart flag changed"},
+ "result": None if test else True,
+ "comment": "Network mynet updated, autostart flag changed",
+ }
define_mock.assert_not_called()
expected_update_kwargs = {
"vport": "openvswitch",
@@ -226,7 +226,7 @@ def test_network_defined_change(test):
)
]
if test:
- assert calls == update_mock.call_args_list
+ assert update_mock.call_args_list == calls
autostart_mock.assert_not_called()
else:
calls.append(
@@ -234,7 +234,7 @@ def test_network_defined_change(test):
"mynet", "br2", "bridge", **expected_update_kwargs, test=False
)
)
- assert calls == update_mock.call_args_list
+ assert update_mock.call_args_list == calls
autostart_mock.assert_called_with(
"mynet",
state="off",
@@ -258,12 +258,12 @@ def test_network_defined_error(test):
)
},
):
- assert {
+ assert virt.network_defined("mynet", "br2", "bridge") == {
"name": "mynet",
"changes": {},
"result": False,
"comment": "Some error",
- } == virt.network_defined("mynet", "br2", "bridge")
+ }
define_mock.assert_not_called()
@@ -285,12 +285,7 @@ def test_network_running_not_existing(test):
"virt.network_start": start_mock,
},
):
- assert {
- "name": "mynet",
- "changes": {"mynet": "Network defined and started"},
- "comment": "Network mynet defined and started",
- "result": None if test else True,
- } == virt.network_running(
+ assert virt.network_running(
"mynet",
"br2",
"bridge",
@@ -324,7 +319,12 @@ def test_network_running_not_existing(test):
connection="myconnection",
username="user",
password="secret",
- )
+ ) == {
+ "name": "mynet",
+ "changes": {"mynet": "Network defined and started"},
+ "comment": "Network mynet defined and started",
+ "result": None if test else True,
+ }
if not test:
define_mock.assert_called_with(
"mynet",
@@ -390,15 +390,15 @@ def test_network_running_nochange(test):
"virt.network_update": update_mock,
},
):
- assert {
+ assert virt.network_running("mynet", "br2", "bridge") == {
"name": "mynet",
"changes": {},
"comment": "Network mynet unchanged and is running",
"result": None if test else True,
- } == virt.network_running("mynet", "br2", "bridge")
- assert [
+ }
+ assert update_mock.call_args_list == [
network_update_call("mynet", "br2", "bridge", test=True)
- ] == update_mock.call_args_list
+ ]
def test_network_running_stopped(test):
@@ -420,20 +420,20 @@ def test_network_running_stopped(test):
"virt.network_update": update_mock,
},
):
- assert {
- "name": "mynet",
- "changes": {"mynet": "Network started"},
- "comment": "Network mynet unchanged and started",
- "result": None if test else True,
- } == virt.network_running(
+ assert virt.network_running(
"mynet",
"br2",
"bridge",
connection="myconnection",
username="user",
password="secret",
- )
- assert [
+ ) == {
+ "name": "mynet",
+ "changes": {"mynet": "Network started"},
+ "comment": "Network mynet unchanged and started",
+ "result": None if test else True,
+ }
+ assert update_mock.call_args_list == [
network_update_call(
"mynet",
"br2",
@@ -443,7 +443,7 @@ def test_network_running_stopped(test):
password="secret",
test=True,
)
- ] == update_mock.call_args_list
+ ]
if not test:
start_mock.assert_called_with(
"mynet",
@@ -468,9 +468,9 @@ def test_network_running_error(test):
),
},
):
- assert {
+ assert virt.network_running("mynet", "br2", "bridge") == {
"name": "mynet",
"changes": {},
"comment": "Some error",
"result": False,
- } == virt.network_running("mynet", "br2", "bridge")
+ }
diff --git a/tests/unit/modules/test_virt.py b/tests/unit/modules/test_virt.py
index dd42ce4441..ec11b56d98 100644
--- a/tests/unit/modules/test_virt.py
+++ b/tests/unit/modules/test_virt.py
@@ -520,65 +520,6 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
root.find("devices/graphics/listen").attrib["address"], "myhost"
)
- def test_gen_xml_spice_default(self):
- """
- Test virt._gen_xml() with default spice graphics device
- """
- diskp = virt._disk_profile(self.mock_conn, "default", "kvm", [], "hello")
- nicp = virt._nic_profile("default", "kvm")
- xml_data = virt._gen_xml(
- self.mock_conn,
- "hello",
- 1,
- 512,
- diskp,
- nicp,
- "kvm",
- "hvm",
- "x86_64",
- graphics={"type": "spice"},
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find("devices/graphics").attrib["type"], "spice")
- self.assertEqual(root.find("devices/graphics").attrib["autoport"], "yes")
- self.assertEqual(root.find("devices/graphics").attrib["listen"], "0.0.0.0")
- self.assertEqual(root.find("devices/graphics/listen").attrib["type"], "address")
- self.assertEqual(
- root.find("devices/graphics/listen").attrib["address"], "0.0.0.0"
- )
-
- def test_gen_xml_spice(self):
- """
- Test virt._gen_xml() with spice graphics device
- """
- diskp = virt._disk_profile(self.mock_conn, "default", "kvm", [], "hello")
- nicp = virt._nic_profile("default", "kvm")
- xml_data = virt._gen_xml(
- self.mock_conn,
- "hello",
- 1,
- 512,
- diskp,
- nicp,
- "kvm",
- "hvm",
- "x86_64",
- graphics={
- "type": "spice",
- "port": 1234,
- "tls_port": 5678,
- "listen": {"type": "none"},
- },
- )
- root = ET.fromstring(xml_data)
- self.assertEqual(root.find("devices/graphics").attrib["type"], "spice")
- self.assertEqual(root.find("devices/graphics").attrib["autoport"], "no")
- self.assertEqual(root.find("devices/graphics").attrib["port"], "1234")
- self.assertEqual(root.find("devices/graphics").attrib["tlsPort"], "5678")
- self.assertFalse("listen" in root.find("devices/graphics").attrib)
- self.assertEqual(root.find("devices/graphics/listen").attrib["type"], "none")
- self.assertFalse("address" in root.find("devices/graphics/listen").attrib)
-
def test_gen_xml_memory(self):
"""
Test virt._gen_xml() with advanced memory settings
@@ -5140,6 +5081,10 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
{"qemu", "kvm"}, {domainCaps["domain"] for domainCaps in caps["domains"]},
)
+ self.mock_conn.getDomainCapabilities.assert_called_with(
+ "/usr/bin/qemu-system-x86_64", "x86_64", None, "kvm"
+ )
+
def test_network_tag(self):
"""
Test virt._get_net_xml() with VLAN tag
--
2.33.0