[Openstack] [OpenStack][Nova] Help with libvirt unit-test - get_diagnostics command

Leander Bessa Beernaert leanderbb at gmail.com
Fri Jul 6 13:33:30 UTC 2012


Daniel, thank you very much for your help!

However, i'm running into my infamous  "import libvirt" problem again when
running the tests (see output below), i really though i'd fixed that one
for sure -.-'.

>
> ======================================================================
> ERROR: test_diagnostic_full (nova.tests.test_libvirt.LibvirtConnTestCase)
> ----------------------------------------------------------------------
> Traceback (most recent call last):
>   File "/home/gsd/nova/nova/tests/test_libvirt.py", line 1923, in
> test_diagnostic_full
>     actual = conn.get_diagnostics({"name": "testvirt"})
>   File "/home/gsd/nova/nova/virt/libvirt/driver.py", line 2678, in
> get_diagnostics
>     return diagnostics.get_diagnostics(dom)
>   File "/home/gsd/nova/nova/virt/libvirt/diagnostics.py", line 97, in
> get_diagnostics
>     import libvirt
> ImportError: No module named libvirt




On Fri, Jul 6, 2012 at 1:11 PM, Daniel P. Berrange <berrange at redhat.com>wrote:

> On Fri, Jul 06, 2012 at 11:59:51AM +0100, Leander Bessa Beernaert wrote:
> > Hello,
> >
> > I've been working on implementing the "diagnostics" command for libvirt -
> > https://review.openstack.org/#/c/8839/ . Now i need to create the unit
> test
> > for this new operation. I've been looking at the code to try and figure
> out
> > an easy way to replicate this, but i'm a bit lost.
> >
> > What i need to do is simulate a connection to libvirt, create a fake
> > instance with a predefined characteristics, retrieve the virtdomain and
> > then verify the results from the get_diagnostics command. I'm more at
> loss
> > as to how exactly do i setup a fake connection a create a fake instance?
> I
> > thought about creating a dummy implementation as i've seen being used
> > around the tests, however that doesn't give me any access to real method.
> > Do note that I'm relatively new to python world, so there's a lot of
> things
> > i can't grasp yes :s.
>
> As you say, figuring out the libvirt Nova test framework is not entirely
> easy, particularly if you're new to Python / Nova. So to help you get
> your patch through review, here is one suitable test case you can add to
> test_libvirt.py for exercising the get_diagnostics API:
>
> diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py
> index eed43b8..f3fa5ff 100644
> --- a/nova/tests/test_libvirt.py
> +++ b/nova/tests/test_libvirt.py
> @@ -1938,6 +1938,91 @@ class LibvirtConnTestCase(test.TestCase):
>          got = jsonutils.loads(conn.get_cpu_info())
>          self.assertEqual(want, got)
>
> +    def test_diagnostic_full(self):
> +        xml = """
> +                <domain type='kvm'>
> +                    <devices>
> +                        <disk type='file'>
> +                            <source file='filename'/>
> +                            <target dev='vda' bus='virtio'/>
> +                        </disk>
> +                        <disk type='block'>
> +                            <source dev='/path/to/dev/1'/>
> +                            <target dev='vdb' bus='virtio'/>
> +                        </disk>
> +                        <interface type='network'>
> +                            <mac address='52:54:00:a4:38:38'/>
> +                            <source network='default'/>
> +                            <target dev='vnet0'/>
> +                        </interface>
> +                    </devices>
> +                </domain>
> +            """
> +
> +        class DiagFakeDomain(FakeVirtDomain):
> +
> +            def __init__(self):
> +                super(DiagFakeDomain, self).__init__(fake_xml=xml)
> +
> +            def vcpus(self):
> +                return ([(0, 1, 15340000000L, 0),
> +                         (1, 1, 1640000000L, 0),
> +                         (2, 1, 3040000000L, 0),
> +                         (3, 1, 1420000000L, 0)],
> +                        [(True, False),
> +                         (True, False),
> +                         (True, False),
> +                         (True, False)])
> +
> +            def blockStats(self, path):
> +                return (169L, 688640L, 0L, 0L, -1L)
> +
> +            def interfaceStats(self, path):
> +                return (4408L, 82L, 0L, 0L, 0L, 0L, 0L, 0L)
> +
> +            def memoryStats(self):
> +                return {'actual': 220160L, 'rss': 200164L}
> +
> +            def maxMemory(self):
> +                return 280160L
> +
> +        def fake_lookup_name(name):
> +            return DiagFakeDomain()
> +
> +        self.mox.StubOutWithMock(libvirt_driver.LibvirtDriver, '_conn')
> +        libvirt_driver.LibvirtDriver._conn.lookupByName = fake_lookup_name
> +
> +        conn = libvirt_driver.LibvirtDriver(False)
> +        actual = conn.get_diagnostics( { "name": "testvirt" })
> +        expect = {'cpu0_time': 15340000000L,
> +                  'cpu1_time': 1640000000L,
> +                  'cpu2_time': 3040000000L,
> +                  'cpu3_time': 1420000000L,
> +                  'vda_read': 688640L,
> +                  'vda_read_req': 169L,
> +                  'vda_write': 0L,
> +                  'vda_write_req': 0L,
> +                  'vda_errors': -1L,
> +                  'vdb_read': 688640L,
> +                  'vdb_read_req': 169L,
> +                  'vdb_write': 0L,
> +                  'vdb_write_req': 0L,
> +                  'vdb_errors': -1L,
> +                  'memory': 280160L,
> +                  'memory-actual': 220160L,
> +                  'memory-rss': 200164L,
> +                  'vnet0_rx': 4408L,
> +                  'vnet0_rx_drop': 0L,
> +                  'vnet0_rx_errors': 0L,
> +                  'vnet0_rx_packets': 82L,
> +                  'vnet0_tx': 0L,
> +                  'vnet0_tx_drop': 0L,
> +                  'vnet0_tx_errors': 0L,
> +                  'vnet0_tx_packets': 0L,
> +                  }
> +
> +        self.assertEqual(actual, expect)
> +
>
>  class HostStateTestCase(test.TestCase):
>
>
> A description of what I'm doing here:
>
>  * First we mock up an XML document that describes our test
>    guest, with 2 disks and 1 NIC.
>
>  * We create the FakeVirtDomain() class which provides a stub
>    implementation of the various libvirt APIs that the
>    get_diagnostics method will call.
>
>  * The fake APIs will return a hardcoded set of statistics
>
>  * We use StubOutWithMock() to make sure that the libvirt connection
>    returns an instance of our FakeVirtDomain class
>
>  * Finally we can call the get_diagnostics() method, and compare
>    the data it returns against what we want.
>
>
> Now this test case only tests the "normal" operation of the API. As noted
> in the review comments, it is possible for the methods like 'vcpus',
> 'intefaceStats', 'blockStats', etc to raise libvirt exceptions. So in
> addition to what I've shown here, you will also want to add some more
> test cases, which verify that exception handling works correctly.
>
> To do this, just copy my example test case above, and make some small
> changes.  eg change the impl of 'vcpus' to be this:
>
>    def vcps():
>       raise libvirtException("fake failure")
>
> and then remove the 'cpuN_time' elements from the 'expected' data hash
>
> and similarly for the interfaceStats/blockStats/memoryStats methods
> which can also raise errors.
>
> Regards,
> Daniel
> --
> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/:|
> |: http://libvirt.org              -o-             http://virt-manager.org:|
> |: http://autobuild.org       -o-         http://search.cpan.org/~danberr/:|
> |: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc:|
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openstack.org/pipermail/openstack/attachments/20120706/48390bfe/attachment.html>


More information about the Openstack mailing list