Mark Wu has uploaded a new change for review.
Change subject: test: Add test cases for domxml generation ......................................................................
test: Add test cases for domxml generation
Change-Id: I1b0f9956084df8cec81f93a1a95944437e00c3e4 Signed-off-by: Mark Wu wudxw@linux.vnet.ibm.com --- M tests/Makefile.am A tests/libvirtvmTests.py 2 files changed, 380 insertions(+), 0 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/44/8544/1
diff --git a/tests/Makefile.am b/tests/Makefile.am index a5e4c64..2b61dde 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -31,6 +31,7 @@ gluster_cli_tests.py \ guestIFTests.py \ hooksTests.py \ + libvirtvmTests.py \ lsblkTests.py \ main.py \ md_utils_tests.py \ diff --git a/tests/libvirtvmTests.py b/tests/libvirtvmTests.py new file mode 100644 index 0000000..d224ce6 --- /dev/null +++ b/tests/libvirtvmTests.py @@ -0,0 +1,379 @@ +# +# Copyright IBM Corp. 2012 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Refer to the README and COPYING files for full details of the license +# +import re +import libvirtvm +from vdsm import constants +from testrunner import VdsmTestCase as TestCaseBase + + +class TestLibvirtvm(TestCaseBase): + + PCI_ADDR = \ + 'bus="0x00" domain="0x0000" function="0x0" slot="0x03" type="pci"' + PCI_ADDR_DICT = {'slot': '0x03', 'bus': '0x00', 'domain': '0x0000', + 'function': '0x0', 'type': 'pci'} + + def __init__(self, *args, **kwargs): + TestCaseBase.__init__(self, *args, **kwargs) + self.conf = {'vmName': 'testVm', + 'vmId': '9ffe28b6-6134-4b1e-8804-1185f49c436f', + 'smp': '8', 'memSize': '1024'} + + def assertXML(self, element, expectedXML, tagName=None, attrName=None): + if tagName is None: + converted = element.toprettyxml() + else: + for node in element.getElementsByTagName(tagName): + # Use attribute to tell a specific elements from others + # with the same tag name. + if not attrName or attrName and node.hasAttribute(attrName): + converted = node.toprettyxml() + self.assertEqual(re.sub('\n\s*', ' ', converted).strip(' '), + re.sub('\n\s*', ' ', expectedXML).strip(' ')) + + def testDomXML(self): + expectedXML = """ + <domain type="kvm"> + <name>testVm</name> + <uuid>9ffe28b6-6134-4b1e-8804-1185f49c436f</uuid> + <memory>1048576</memory> + <currentMemory>1048576</currentMemory> + <vcpu>8</vcpu> + <devices/> + </domain>""" + + domxml = libvirtvm._DomXML(self.conf, self.log) + self.assertXML(domxml.dom, expectedXML) + + def testOSXML(self): + OSXML = """ + <os> + <type arch="x86_64" machine="pc">hvm</type> + <boot dev="%s"/> + <smbios mode="sysinfo"/> + </os>""" + + qemu2libvirtBoot = {'a': 'fd', 'c': 'hd', 'd': 'cdrom', 'n': 'network'} + for k, v in qemu2libvirtBoot.iteritems(): + self.conf['boot'] = k + expectedXML = OSXML % v + domxml = libvirtvm._DomXML(self.conf, self.log) + domxml.appendOs() + self.assertXML(domxml.dom, expectedXML, 'os') + + OSXML = """ + <os> + <type arch="x86_64" machine="pc">hvm</type> + <initrd>/tmp/initrd-2.6.18.img</initrd> + <kernel>/tmp/vmlinuz-2.6.18</kernel> + <cmdline>console=ttyS0 1</cmdline> + <smbios mode="sysinfo"/> + </os>""" + del self.conf['boot'] + self.conf['kernel'] = '/tmp/vmlinuz-2.6.18' + self.conf['initrd'] = '/tmp/initrd-2.6.18.img' + self.conf['kernelArgs'] = 'console=ttyS0 1' + domxml = libvirtvm._DomXML(self.conf, self.log) + domxml.appendOs() + self.assertXML(domxml.dom, OSXML, 'os') + + def testFeaturesXML(self): + featuresXML = """ + <features> + <acpi/> + </features>""" + domxml = libvirtvm._DomXML(self.conf, self.log) + domxml.appendFeatures() + self.assertXML(domxml.dom, featuresXML, 'features') + + def testSysinfoXML(self): + sysinfoXML = """ + <sysinfo type="smbios"> + <system> + <entry name="manufacturer">%s</entry> + <entry name="product">%s</entry> + <entry name="version">%s</entry> + <entry name="serial">%s</entry> + <entry name="uuid">%s</entry> + </system> + </sysinfo>""" + product = 'oVirt Node' + version = '17-1' + serial = 'A5955881-519B-11CB-8352-E78A528C28D8_00:21:cc:68:d7:38' + sysinfoXML = sysinfoXML % (constants.SMBIOS_MANUFACTURER, + product, version, serial, self.conf['vmId']) + domxml = libvirtvm._DomXML(self.conf, self.log) + domxml.appendSysinfo(product, version, serial) + self.assertXML(domxml.dom, sysinfoXML, 'sysinfo') + + def testConsoleXML(self): + consoleXML = """ + <console type="pty"> + <target port="0" type="virtio"/> + </console>""" + domxml = libvirtvm._DomXML(self.conf, self.log) + domxml.appendConsole() + self.assertXML(domxml.dom, consoleXML, 'console') + + def testClockXML(self): + clockXML = """ + <clock adjustment="-3600" offset="variable"> + <timer name="rtc" tickpolicy="catchup"/> + </clock>""" + self.conf['timeOffset'] = '-3600' + domxml = libvirtvm._DomXML(self.conf, self.log) + domxml.appendClock() + self.assertXML(domxml.dom, clockXML, 'clock') + + def testCpuXML(self): + cpuXML = """ + <cpu match="exact"> + <model>Opteron_G4</model> + <topology cores="2" sockets="2" threads="2"/> + <feature name="sse4.1" policy="require"/> + <feature name="sse4.2" policy="require"/> + <feature name="svm" policy="disable"/> + </cpu> """ + cputuneXML = """ + <cputune> + <vcpupin cpuset="2-3" vcpu="1"/> + <vcpupin cpuset="0-1" vcpu="0"/> + </cputune> """ + + self.conf['cpuType'] = "Opteron_G4,+sse4_1,+sse4_2,-svm" + self.conf['smpCoresPerSocket'] = 2 + self.conf['smpThreadsPerCore'] = 2 + self.conf['cpuPinning'] = {'0': '0-1', '1': '2-3'} + domxml = libvirtvm._DomXML(self.conf, self.log) + domxml.appendCpu() + self.assertXML(domxml.dom, cpuXML, 'cpu') + self.assertXML(domxml.dom, cputuneXML, 'cputune') + + def testChannelXML(self): + channelXML = """ + <channel type="unix"> + <target name="%s" type="virtio"/> + <source mode="bind" path="%s"/> + </channel>""" + path = '/tmp/channel-socket' + name = 'org.linux-kvm.port.0' + channelXML = channelXML % (name, path) + domxml = libvirtvm._DomXML(self.conf, self.log) + domxml._appendAgentDevice(path, name) + self.assertXML(domxml.dom, channelXML, 'channel') + + def testInputXML(self): + mouseXML = """ + <input bus="ps2" type="mouse"/>""" + domxml = libvirtvm._DomXML(self.conf, self.log) + domxml.appendInput() + self.assertXML(domxml.dom, mouseXML, 'input') + + tabletXML = """ + <input bus="usb" type="tablet"/>""" + self.conf['tabletEnable'] = 'true' + domxml = libvirtvm._DomXML(self.conf, self.log) + domxml.appendInput() + self.assertXML(domxml.dom, tabletXML, 'input') + + def testGraphicsXML(self): + vncXML = """ + <graphics autoport="yes" keymap="en-us" passwd="*****" + passwdValidTo="1970-01-01T00:00:01" port="-1" type="vnc"> + <listen network="vdsm-vmDisplay" type="network"/> + </graphics>""" + + self.conf['display'] = 'vnc' + self.conf['displayPort'] = '-1' + self.conf['displayNetwork'] = 'vmDisplay' + self.conf['keyboardLayout'] = 'en-us' + domxml = libvirtvm._DomXML(self.conf, self.log) + domxml.appendGraphics() + self.assertXML(domxml.dom, vncXML, 'graphics') + + spiceChannelXML = """ + <channel type="spicevmc"> + <target name="com.redhat.spice.0" type="virtio"/> + </channel>""" + spiceXML = """ + <graphics autoport="yes" keymap="en-us" passwd="*****" + passwdValidTo="1970-01-01T00:00:01" port="-1" + tlsPort="-1" type="spice"> + <channel mode="secure" name="main"/> + <channel mode="secure" name="inputs"/> + <channel mode="secure" name="cursor"/> + <channel mode="secure" name="playback"/> + <channel mode="secure" name="record"/> + <channel mode="secure" name="display"/> + <listen network="vdsm-vmDisplay" type="network"/> + </graphics>""" + + self.conf['spiceSecureChannels'] = \ + "smain,sinputs,scursor,splayback,srecord,sdisplay" + self.conf['display'] = 'qxl' + self.conf['displaySecurePort'] = '-1' + domxml = libvirtvm._DomXML(self.conf, self.log) + domxml.appendGraphics() + self.assertXML(domxml.dom, spiceChannelXML, 'channel', 'type') + self.assertXML(domxml.dom, spiceXML, 'graphics') + + def testBalloonXML(self): + balloonXML = '<memballoon model="virtio"/>' + dev = {'device': 'memballoon', 'type': 'balloon', + 'specParams': {'model': 'virtio'}} + balloon = libvirtvm.BalloonDevice(self.conf, self.log, **dev) + self.assertXML(balloon.getXML(), balloonXML) + + def testSoundXML(self): + soundXML = '<sound model="ac97"/>' + dev = {'device': 'ac97'} + sound = libvirtvm.SoundDevice(self.conf, self.log, **dev) + self.assertXML(sound.getXML(), soundXML) + + def testVideoXML(self): + videoXML = """ + <video> + <model heads="1" type="vga" vram="8192"/> + </video>""" + + dev = {'device': 'vga', 'specParams': {'vram': '8192'}} + video = libvirtvm.VideoDevice(self.conf, self.log, **dev) + self.assertXML(video.getXML(), videoXML) + + def testInterfaceXML(self): + interfaceXML = """ + <interface type="bridge"> <address %s/> + <mac address="52:54:00:59:F5:3F"/> + <model type="virtio"/> + <source bridge="ovirtmgmt"/> + <filterref filter="no-mac-spoofing"/> + <boot order="1"/> + <driver name="vhost"/> + <tune> + <sndbuf>0</sndbuf> + </tune> + </interface>""" % self.PCI_ADDR + + dev = {'nicModel': 'virtio', 'macAddr': '52:54:00:59:F5:3F', + 'network': 'ovirtmgmt', 'address': self.PCI_ADDR_DICT, + 'device': 'bridge', 'type': 'interface', + 'bootOrder': '1', 'filter': 'no-mac-spoofing'} + + self.conf['custom'] = {'vhost': 'ovirtmgmt:true', 'sndbuf': '0'} + iface = libvirtvm.NetworkInterfaceDevice(self.conf, self.log, **dev) + self.assertXML(iface.getXML(), interfaceXML) + + def testControllerXML(self): + ideXML = """ + <controller index="0" type="ide"> + <address %s/> + </controller>""" % self.PCI_ADDR + dev = {'device': 'ide', 'index': '0', 'address': self.PCI_ADDR_DICT} + ide = libvirtvm.ControllerDevice(self.conf, self.log, **dev) + self.assertXML(ide.getXML(), ideXML) + + virtioSerialXML = """ + <controller index="0" ports="16" type="virtio-serial"> + <address %s/> + </controller>""" % self.PCI_ADDR + + dev = {'device': 'virtio-serial', 'address': self.PCI_ADDR_DICT} + virtioSerial = libvirtvm.ControllerDevice(self.conf, self.log, **dev) + self.assertXML(virtioSerial.getXML(), virtioSerialXML) + + usbXML = """ + <controller index="0" model="ich9-ehci1" type="usb"> + <master startport="0"/> + <address %s/> + </controller>""" % self.PCI_ADDR + + dev = {'device': 'usb', 'model': 'ich9-ehci1', 'index': '0', + 'master': {'startport': '0'}, 'address': self.PCI_ADDR_DICT} + usb = libvirtvm.ControllerDevice(self.conf, self.log, **dev) + self.assertXML(usb.getXML(), usbXML) + + def testRedirXML(self): + redirXML = """ + <redirdev type="spicevmc"> + <address %s/> + </redirdev>""" % self.PCI_ADDR + + dev = {'device': 'spicevmc', 'address': self.PCI_ADDR_DICT} + + redir = libvirtvm.RedirDevice(self.conf, self.log, **dev) + self.assertXML(redir.getXML(), redirXML) + + def testDriveXML(self): + SERIAL = '54-a672-23e5b495a9ea' + cdromXML = """ + <disk device="cdrom" snapshot="no" type="file"> + <source file="/tmp/fedora.iso" startupPolicy="optional"/> + <target bus="ide" dev="hdc"/> + <readonly/> + <serial>%s</serial> + </disk>""" % SERIAL + + dev = {'index': '2', 'propagateErrors': 'off', 'iface': 'ide', + 'name': 'hdc', 'format': 'raw', 'device': 'cdrom', + 'path': '/tmp/fedora.iso', 'type': 'disk', 'readonly': 'True', + 'shared': 'False', 'serial': SERIAL} + + cdrom = libvirtvm.Drive(self.conf, self.log, **dev) + self.assertXML(cdrom.getXML(), cdromXML) + + rawBlockXML = """ + <disk device="disk" snapshot="no" type="block"> + <source dev="/dev/mapper/lun1"/> + <target bus="virtio" dev="vda"/> + <serial>%s</serial> + <driver cache="none" error_policy="stop" + io="native" name="qemu" type="raw"/> + </disk>""" % SERIAL + + dev = {'index': '0', 'propagateErrors': 'off', 'iface': 'virtio', + 'name': 'vda', 'format': 'raw', 'device': 'disk', + 'path': '/dev/mapper/lun1', 'type': 'disk', 'readonly': 'False', + 'shared': 'False', 'serial': SERIAL} + + rawBlock = libvirtvm.Drive(self.conf, self.log, **dev) + # Patch Drive.blockDev to skip the block device checking. + rawBlock._blockDev = True + self.assertXML(rawBlock.getXML(), rawBlockXML) + + qcow2VirtioXML = """ + <disk device="disk" snapshot="no" type="file"> + <source file="/tmp/disk1.img"/> + <target bus="virtio" dev="vda"/> + <shareable/> + <serial>%s</serial> + <driver cache="writethrough" error_policy="enospace" + io="threads" name="qemu" type="qcow2"/> + </disk>""" % SERIAL + + dev = {'index': '0', 'propagateErrors': 'on', 'iface': 'virtio', + 'name': 'vda', 'format': 'cow', 'device': 'disk', + 'path': '/tmp/disk1.img', 'type': 'disk', 'readonly': 'False', + 'shared': 'True', 'serial': SERIAL} + + self.conf['custom'] = {'viodiskcache': 'writethrough'} + qcow2Virtio = libvirtvm.Drive(self.conf, self.log, **dev) + # Patch Drive.blockDev to skip the block device checking. + qcow2Virtio._blockDev = False + self.assertXML(qcow2Virtio.getXML(), qcow2VirtioXML)
-- To view, visit http://gerrit.ovirt.org/8544 To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange Gerrit-Change-Id: I1b0f9956084df8cec81f93a1a95944437e00c3e4 Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Mark Wu wudxw@linux.vnet.ibm.com
Mark Wu has posted comments on this change.
Change subject: test: Add test cases for domxml generation ......................................................................
Patch Set 1: Verified
-- To view, visit http://gerrit.ovirt.org/8544 To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: comment Gerrit-Change-Id: I1b0f9956084df8cec81f93a1a95944437e00c3e4 Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Mark Wu wudxw@linux.vnet.ibm.com Gerrit-Reviewer: Mark Wu wudxw@linux.vnet.ibm.com
Dan Kenigsberg has posted comments on this change.
Change subject: test: Add test cases for domxml generation ......................................................................
Patch Set 1: I would prefer that you didn't submit this
(2 inline comments)
Wow, thanks for this much-awaited tests. I feel bad about these untestable appendXXX functions that you somehow managed to test...
I think that a cleaner approach would have been to have a list of [(conf, expectedXML)...] instead, and call testDomXML(conf, xml) to iterate over them.
What is your opinion? Except for the side-effects, I think this test can be taken as it is, even while it digs into the ugly implementation of libvirtvm._DomXML().
.................................................... File tests/libvirtvmTests.py Line 39: def assertXML(self, element, expectedXML, tagName=None, attrName=None): Line 40: if tagName is None: Line 41: converted = element.toprettyxml() Line 42: else: Line 43: for node in element.getElementsByTagName(tagName): just an idea - how about using xpath instead? Line 44: # Use attribute to tell a specific elements from others Line 45: # with the same tag name. Line 46: if not attrName or attrName and node.hasAttribute(attrName): Line 47: converted = node.toprettyxml()
Line 371: 'name': 'vda', 'format': 'cow', 'device': 'disk', Line 372: 'path': '/tmp/disk1.img', 'type': 'disk', 'readonly': 'False', Line 373: 'shared': 'True', 'serial': SERIAL} Line 374: Line 375: self.conf['custom'] = {'viodiskcache': 'writethrough'} I think it is bad practice to have a test case with side-effects. We should never assume a specific order in which they run. Line 376: qcow2Virtio = libvirtvm.Drive(self.conf, self.log, **dev) Line 377: # Patch Drive.blockDev to skip the block device checking. Line 378: qcow2Virtio._blockDev = False
-- To view, visit http://gerrit.ovirt.org/8544 To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: comment Gerrit-Change-Id: I1b0f9956084df8cec81f93a1a95944437e00c3e4 Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Mark Wu wudxw@linux.vnet.ibm.com Gerrit-Reviewer: Dan Kenigsberg danken@redhat.com Gerrit-Reviewer: Mark Wu wudxw@linux.vnet.ibm.com
Mark Wu has posted comments on this change.
Change subject: test: Add test cases for domxml generation ......................................................................
Patch Set 2:
I think it's more clear to preserve one test case for each kind of device.
-- To view, visit http://gerrit.ovirt.org/8544 To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: comment Gerrit-Change-Id: I1b0f9956084df8cec81f93a1a95944437e00c3e4 Gerrit-PatchSet: 2 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Mark Wu wudxw@linux.vnet.ibm.com Gerrit-Reviewer: Dan Kenigsberg danken@redhat.com Gerrit-Reviewer: Mark Wu wudxw@linux.vnet.ibm.com Gerrit-Reviewer: Zhou Zheng Sheng zhshzhou@linux.vnet.ibm.com
Dan Kenigsberg has posted comments on this change.
Change subject: test: Add test cases for domxml generation ......................................................................
Patch Set 2: Looks good to me, approved
I still feel that the test is tailored too tightly to the code of these appendXXX(). But I'm happy to take this as it is.
-- To view, visit http://gerrit.ovirt.org/8544 To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: comment Gerrit-Change-Id: I1b0f9956084df8cec81f93a1a95944437e00c3e4 Gerrit-PatchSet: 2 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Mark Wu wudxw@linux.vnet.ibm.com Gerrit-Reviewer: Dan Kenigsberg danken@redhat.com Gerrit-Reviewer: Mark Wu wudxw@linux.vnet.ibm.com Gerrit-Reviewer: Zhou Zheng Sheng zhshzhou@linux.vnet.ibm.com
Mark Wu has posted comments on this change.
Change subject: test: Add test cases for domxml generation ......................................................................
Patch Set 2: Verified
-- To view, visit http://gerrit.ovirt.org/8544 To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: comment Gerrit-Change-Id: I1b0f9956084df8cec81f93a1a95944437e00c3e4 Gerrit-PatchSet: 2 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Mark Wu wudxw@linux.vnet.ibm.com Gerrit-Reviewer: Dan Kenigsberg danken@redhat.com Gerrit-Reviewer: Mark Wu wudxw@linux.vnet.ibm.com Gerrit-Reviewer: Vinzenz Feenstra vfeenstr@redhat.com Gerrit-Reviewer: Zhou Zheng Sheng zhshzhou@linux.vnet.ibm.com
Dan Kenigsberg has submitted this change and it was merged.
Change subject: test: Add test cases for domxml generation ......................................................................
test: Add test cases for domxml generation
Change-Id: I1b0f9956084df8cec81f93a1a95944437e00c3e4 Signed-off-by: Mark Wu wudxw@linux.vnet.ibm.com --- M tests/Makefile.am A tests/libvirtvmTests.py 2 files changed, 371 insertions(+), 0 deletions(-)
Approvals: Mark Wu: Verified Dan Kenigsberg: Looks good to me, approved
-- To view, visit http://gerrit.ovirt.org/8544 To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: merged Gerrit-Change-Id: I1b0f9956084df8cec81f93a1a95944437e00c3e4 Gerrit-PatchSet: 2 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Mark Wu wudxw@linux.vnet.ibm.com Gerrit-Reviewer: Dan Kenigsberg danken@redhat.com Gerrit-Reviewer: Mark Wu wudxw@linux.vnet.ibm.com Gerrit-Reviewer: Vinzenz Feenstra vfeenstr@redhat.com Gerrit-Reviewer: Zhou Zheng Sheng zhshzhou@linux.vnet.ibm.com
vdsm-patches@lists.fedorahosted.org