def assert_xml_equals(expected, actual): """ Assert that two ElementTree nodes are equal """ assert xmlutil.to_dict(xmlutil.strip_spaces(expected), True) == xmlutil.to_dict( xmlutil.strip_spaces(actual), True)
def test_strip_spaces(): xml_str = """<domain> <name>test01</name> <memory unit="MiB" >1024</memory> </domain> """ expected_str = ( b'<domain><name>test01</name><memory unit="MiB">1024</memory></domain>' ) node = ET.fromstring(xml_str) assert expected_str == ET.tostring(xml.strip_spaces(node))
def test_gen_xml_hostdev_pf(): """ Test the virt._gen_net_xml() function for a hostdev forward mode with physical function """ xml_data = virt._gen_net_xml("network", "virbr0", "hostdev", None, physical_function="eth0") root = ET.fromstring(xml_data) expected_forward = strip_xml(""" <forward mode='hostdev' managed='yes'> <pf dev='eth0'/> </forward> """) actual_forward = ET.tostring(xmlutil.strip_spaces(root.find("./forward"))) assert actual_forward == expected_forward
def test_gen_xml_nat(): """ Test virt._get_net_xml() in a nat setup """ xml_data = virt._gen_net_xml( "network", "main", "nat", None, ip_configs=[ { "cidr": "192.168.2.0/24", "dhcp_ranges": [ { "start": "192.168.2.10", "end": "192.168.2.25" }, { "start": "192.168.2.110", "end": "192.168.2.125" }, ], "hosts": { "192.168.2.10": { "mac": "00:16:3e:77:e2:ed", "name": "foo.example.com", }, }, "bootp": { "file": "pxeboot.img", "server": "192.168.2.1" }, "tftp": "/path/to/tftp", }, { "cidr": "2001:db8:ca2:2::/64", "hosts": { "2001:db8:ca2:2:3::1": { "name": "paul" }, "2001:db8:ca2:2:3::2": { "id": "0:3:0:1:0:16:3e:11:22:33", "name": "ralph", }, }, }, ], nat={ "address": { "start": "1.2.3.4", "end": "1.2.3.10" }, "port": { "start": 500, "end": 1000 }, }, domain={ "name": "acme.lab", "localOnly": True }, mtu=9000, ) root = ET.fromstring(xml_data) 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'> <dhcp> <range start='192.168.2.10' end='192.168.2.25'/> <range start='192.168.2.110' end='192.168.2.125'/> <host ip='192.168.2.10' mac='00:16:3e:77:e2:ed' name='foo.example.com'/> <bootp file='pxeboot.img' server='192.168.2.1'/> </dhcp> <tftp root='/path/to/tftp'/> </ip> """) assert_xml_equals(root.find("./ip[@address='192.168.2.1']"), expected_ipv4) expected_ipv6 = ET.fromstring(""" <ip family='ipv6' address='2001:db8:ca2:2::1' prefix='64'> <dhcp> <host ip='2001:db8:ca2:2:3::1' name='paul'/> <host ip='2001:db8:ca2:2:3::2' id='0:3:0:1:0:16:3e:11:22:33' name='ralph'/> </dhcp> </ip> """) 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(""" <nat> <address start='1.2.3.4' end='1.2.3.10'/> <port start='500' end='1000'/> </nat> """) assert actual_nat == expected_nat assert root.find("./domain").attrib == { "name": "acme.lab", "localOnly": "yes" } assert root.find("mtu").get("size") == "9000"
def strip_xml(xml_str): """ Remove all spaces and formatting from an XML string """ return ET.tostring(xmlutil.strip_spaces(ET.fromstring(xml_str)))
def test_update_hostdev_changes(running, live, make_mock_device, make_mock_vm, test): """ Test the virt.update function with host device changes """ xml_def = """ <domain type='kvm'> <name>my_vm</name> <memory unit='KiB'>524288</memory> <currentMemory unit='KiB'>524288</currentMemory> <vcpu placement='static'>1</vcpu> <os> <type arch='x86_64'>hvm</type> </os> <on_reboot>restart</on_reboot> <devices> <hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </hostdev> </devices> </domain>""" domain_mock = make_mock_vm(xml_def, running) make_mock_device(""" <device> <name>usb_3_1_3</name> <path>/sys/devices/pci0000:00/0000:00:1d.6/0000:06:00.0/0000:07:02.0/0000:3e:00.0/usb3/3-1/3-1.3</path> <devnode type='dev'>/dev/bus/usb/003/004</devnode> <parent>usb_3_1</parent> <driver> <name>usb</name> </driver> <capability type='usb_device'> <bus>3</bus> <device>4</device> <product id='0x6006'>AUKEY PC-LM1E Camera</product> <vendor id='0x0458'>KYE Systems Corp. (Mouse Systems)</vendor> </capability> </device> """) make_mock_device(""" <device> <name>pci_1002_71c4</name> <parent>pci_8086_27a1</parent> <capability type='pci'> <class>0xffffff</class> <domain>0</domain> <bus>1</bus> <slot>0</slot> <function>0</function> <product id='0x71c4'>M56GL [Mobility FireGL V5200]</product> <vendor id='0x1002'>ATI Technologies Inc</vendor> <numa node='1'/> </capability> </device> """) ret = virt.update("my_vm", host_devices=["usb_3_1_3"], test=test, live=live) define_mock = virt.libvirt.openAuth().defineXML assert_called(define_mock, not test) # Test that the XML is updated with the proper devices usb_device_xml = strip_xml(""" <hostdev mode="subsystem" type="usb"> <source> <vendor id="0x0458" /> <product id="0x6006" /> </source> </hostdev> """) if not test: set_xml = ET.fromstring(define_mock.call_args[0][0]) actual_hostdevs = [ ET.tostring(xmlutil.strip_spaces(node)) for node in set_xml.findall("./devices/hostdev") ] assert [usb_device_xml] == actual_hostdevs if not test and live: attach_xml = strip_xml(domain_mock.attachDevice.call_args[0][0]) assert usb_device_xml == attach_xml pci_device_xml = strip_xml(""" <hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </hostdev> """) detach_xml = strip_xml(domain_mock.detachDevice.call_args[0][0]) assert pci_device_xml == detach_xml else: domain_mock.attachDevice.assert_not_called() domain_mock.detachDevice.assert_not_called()