Change in vdsm[master]: tests: add more tests for custom error responses

fromani at redhat.com fromani at redhat.com
Thu Mar 12 11:24:13 UTC 2015


Francesco Romani has uploaded a new change for review.

Change subject: tests: add more tests for custom error responses
......................................................................

tests: add more tests for custom error responses

An upcoming patchset wants to introduce and leverage
the response module.

This patch prepares the soil by adding unit tests.
We start from the error paths, since they are (hopefully?)
less often tested.

Moreover, to test error path is often clumsy due to the need
to trigger faults or inject them in the code, so this
is a useful safety net to have.

Change-Id: Icf3d03f125f9c53339d9ad7fef8c31482bab0bfb
Signed-off-by: Francesco Romani <fromani at redhat.com>
---
M tests/vmTests.py
M tests/vmfakelib.py
2 files changed, 133 insertions(+), 13 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/65/38665/1

diff --git a/tests/vmTests.py b/tests/vmTests.py
index 26c39ef..4adea76 100644
--- a/tests/vmTests.py
+++ b/tests/vmTests.py
@@ -51,6 +51,7 @@
 from vmTestsData import CONF_TO_DOMXML_PPC64
 from vmTestsData import CONF_TO_DOMXML_NO_VDSM
 import vmfakelib as fake
+from vmStorageTests import drive_config
 
 from testValidation import slowtest
 
@@ -873,6 +874,10 @@
     GRAPHIC_DEVICES = [{'type': 'graphics', 'device': 'spice', 'port': '-1'},
                        {'type': 'graphics', 'device': 'vnc', 'port': '-1'}]
 
+    TICKET_PARAMS = {
+        'userName': 'admin',
+        'userId': 'fdfc627c-d875-11e0-90f0-83df133b58cc'}
+
     @MonkeyPatch(libvirtconnection, 'get', lambda x: fake.Connection())
     @permutations([[define.NORMAL], [define.ERROR]])
     def testTimeOffsetNotPresentByDefault(self, exitCode):
@@ -951,25 +956,27 @@
             self._verifyDeviceUpdate(
                 device, self.GRAPHIC_DEVICES, domXml, devXml)
 
-    def _verifyDeviceUpdate(self, device, allDevices, domXml, devXml):
-        TICKET_PARAMS = {
-            'userName': 'admin',
-            'userId': 'fdfc627c-d875-11e0-90f0-83df133b58cc'}
+    def _getGraphicsDeviceParams(self, graphicsType):
+        return {
+            'deviceType': hwclass.GRAPHICS,
+            'graphicsType': graphicsType,
+            'password': '***',
+            'ttl': 0,
+            'existingConnAction': 'disconnect',
+            'params': self.TICKET_PARAMS}
 
+    def _verifyDeviceUpdate(self, device, allDevices, domXml, devXml):
         def _check_ticket_params(domXML, conf, params):
-            self.assertEqual(params, TICKET_PARAMS)
+            self.assertEqual(params, self.TICKET_PARAMS)
 
         with MonkeyPatchScope([(hooks, 'before_vm_set_ticket',
                                 _check_ticket_params)]):
             with fake.VM(devices=allDevices) as testvm:
                 testvm._dom = fake.Domain(domXml)
-                testvm.updateDevice({
-                    'deviceType': 'graphics',
-                    'graphicsType': device['device'],
-                    'password': '***',
-                    'ttl': 0,
-                    'existingConnAction': 'disconnect',
-                    'params': TICKET_PARAMS})
+
+                testvm.updateDevice(
+                    self._getGraphicsDeviceParams(device['device']))
+
                 self.assertEquals(testvm._dom.devXml, devXml)
 
     def testDomainNotRunningWithoutDomain(self):
@@ -1018,6 +1025,45 @@
                                'hdc': libvirt.VIR_DOMAIN_DISK_ERROR_UNSPEC})
             testvm._dom = dom
             self.assertEqual(testvm._readPauseCode(), 'EOTHER')
+
+    @permutations([[libvirt.VIR_ERR_OPERATION_DENIED, 'setNumberOfCpusErr'],
+                   [libvirt.VIR_ERR_NO_DOMAIN, 'noVM']])
+    def testSetNumberOfVcpusFailed(self, virtError, vdsmError):
+        # caveat emptor: in this test we DON't
+        # overwrite the message, thus will be the default one; but for
+        # errors != 'noVM', it can change.
+        with MonkeyPatchScope([(hooks, 'before_set_num_of_cpus',
+                                lambda: None)]):
+            with fake.VM() as testvm:
+                testvm._dom = fake.Domain(virtError=virtError)
+
+                res = testvm.setNumberOfCpus(4)  # random value
+
+                self.assertEqual(res, define.errCode[vdsmError])
+
+    def testUpdateDeviceGraphicsFailed(self):
+        def _check_ticket_params(domXML, conf, params):
+            pass
+
+        with MonkeyPatchScope([(hooks, 'before_vm_set_ticket',
+                                _check_ticket_params)]):
+            with fake.VM(devices=self.GRAPHIC_DEVICES) as testvm:
+                # caveat: we intentionally recycle the very same
+                # error message to simplify assert() down under
+                expected_status = define.errCode['ticketErr']
+                message = expected_status['status']['message']
+                device = 'spice'
+                domXml = '''
+                    <devices>
+                        <graphics type="%s" port="5900" />
+                    </devices>''' % device
+
+                testvm._dom = fake.Domain(domXml, timeoutError=message)
+
+                res = testvm.updateDevice(
+                    self._getGraphicsDeviceParams(device))
+
+                self.assertEqual(res, expected_status)
 
 
 VM_EXITS = tuple(product((define.NORMAL, define.ERROR),
@@ -1298,6 +1344,7 @@
             self.assertEqual(int(testvm.conf['smp']), cpus)
 
 
+ at expandPermutations
 class ChangeBlockDevTests(TestCaseBase):
 
     def test_change_cd_failure(self):
@@ -1315,3 +1362,65 @@
 
                 expected_status = define.errCode['changeDisk']['status']
                 self.assertEqual(res['status'], expected_status)
+
+    @permutations([[libvirt.VIR_ERR_OPERATION_DENIED, 'hotplugDisk'],
+                   [libvirt.VIR_ERR_NO_DOMAIN, 'noVM']])
+    def test_hotplug_disk_failure(self, virtError, vdsmError):
+        # caveat emptor: in this test we DON't
+        # overwrite the message, thus will be the default one; but for
+        # errors != 'noVM', it can change.
+        PATH = '/this/path/does/not/exists'
+
+        def _fake_hook(driveXml, conf, params):
+            return driveXml
+
+        cif = fake.ClientIF()
+        with MonkeyPatchScope([(cif, 'prepareVolumePath',
+                                lambda _: PATH),
+                               (cif, 'teardownVolumePath',
+                                lambda _: None),
+                               (hooks, 'before_disk_hotplug',
+                                _fake_hook),
+                               (utils, 'isBlockDevice',
+                                lambda path: True)]):
+            with fake.VM(devices=[drive_config()],
+                         cif=cif) as fakevm:
+                # no specific meaning, actually any error != None is good
+                fakevm._dom = fake.Domain(
+                    virtError=libvirt.VIR_ERR_ACCESS_DENIED)
+
+                res = fakevm.hotplugDisk({
+                    'drive': drive_config(
+                        path=PATH,
+                        serial='65-a561-23e5b495b9bc')})
+
+                expected_status = define.errCode['hotplugDisk']['status']
+                self.assertEqual(res['status'], expected_status)
+
+    def test_hotunplug_inexistent_disk(self):
+        PATH = '/this/path/does/not/exists'
+
+        def _fake_hook(driveXml, conf, params):
+            return driveXml
+
+        cif = fake.ClientIF()
+        with MonkeyPatchScope([(cif, 'prepareVolumePath',
+                                lambda _: PATH),
+                               (cif, 'teardownVolumePath',
+                                lambda _: None),
+                               (hooks, 'before_disk_hotunplug',
+                                _fake_hook),
+                               (utils, 'isBlockDevice',
+                                lambda path: True)]):
+            with fake.VM(cif=cif) as fakevm:
+                # no specific meaning, actually any error != None is good
+                fakevm._dom = fake.Domain(
+                    virtError=libvirt.VIR_ERR_ACCESS_DENIED)
+
+                res = fakevm.hotunplugDisk({})
+
+                expected_status = define.errCode['hotunplugDisk']['status']
+                self.assertEqual(res['status']['code'],
+                                 expected_status['code'])
+                self.assertEqual(res['status']['message'],
+                                 "Disk not found")
diff --git a/tests/vmfakelib.py b/tests/vmfakelib.py
index 6919351..99c1b42 100644
--- a/tests/vmfakelib.py
+++ b/tests/vmfakelib.py
@@ -61,7 +61,8 @@
                  virtError=libvirt.VIR_ERR_OK,
                  domState=libvirt.VIR_DOMAIN_RUNNING,
                  domReason=0,
-                 vmId=''):
+                 vmId='',
+                 timeoutError=None):
         self._xml = xml
         self.devXml = ''
         self._virtError = virtError
@@ -72,8 +73,12 @@
         self._vmId = vmId
         self.calls = {}
         self._diskErrors = {}
+        self._timeoutError = timeoutError
 
     def _failIfRequested(self):
+        if self._timeoutError:
+            raise vm.TimeoutError(str(self._timeoutError))
+
         if self._virtError != libvirt.VIR_ERR_OK:
             err = libvirt.libvirtError(defmsg='')
             err.err = [self._virtError]
@@ -99,6 +104,9 @@
 
     def vcpusFlags(self, flags):
         return -1
+
+    def setVcpusFlags(self, numberOfCpus, flags):
+        self._failIfRequested()
 
     def metadata(self, type, uri, flags):
         self._failIfRequested()
@@ -130,6 +138,9 @@
     def diskErrors(self):
         return self._diskErrors
 
+    def attachDevice(self, devXml):
+        self._failIfRequested()
+
 
 class GuestAgent(object):
     def __init__(self):


-- 
To view, visit https://gerrit.ovirt.org/38665
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Icf3d03f125f9c53339d9ad7fef8c31482bab0bfb
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Francesco Romani <fromani at redhat.com>


More information about the vdsm-patches mailing list