def test_invoke_api_with_expected_exception(self):
        api_session = self._create_api_session(True)
        ret = mock.Mock()
        responses = [error_util.VimConnectionException(None), ret]

        def api(*args, **kwargs):
            response = responses.pop(0)
            if isinstance(response, Exception):
                raise response
            return response

        module = mock.Mock()
        module.api = api
        with mock.patch.object(greenthread, 'sleep'):
            self.assertEqual(ret, api_session.invoke_api(module, 'api'))
Esempio n. 2
0
        def vim_request_handler(managed_object, **kwargs):
            """Handler for VI SDK calls.

            Builds the SOAP message and parses the response for fault
            checking and other errors.

            :param managed_object:Managed object reference
            :param kwargs: Keyword arguments of the call
            :return: Response of the API call
            """

            try:
                if isinstance(managed_object, str):
                    # For strings use string value for value and type
                    # of the managed object.
                    managed_object = get_moref(managed_object, managed_object)
                request = getattr(self.client.service, attr_name)
                response = request(managed_object, **kwargs)
                if (attr_name.lower() == 'retrievepropertiesex'):
                    retrieve_properties_ex_fault_checker(response)
                return response

            except error_util.VimFaultException as excep:
                raise

            except suds.WebFault as excep:
                doc = excep.document
                detail = doc.childAtPath('/Envelope/Body/Fault/detail')
                fault_list = []
                for child in detail.getChildren():
                    fault_list.append(child.get('type'))
                raise error_util.VimFaultException(fault_list, excep)

            except AttributeError as excep:
                raise error_util.VimAttributeException(
                    _("No such SOAP method "
                      "%(attr)s. Detailed "
                      "error: %(excep)s.") % {
                          'attr': attr_name,
                          'excep': excep
                      })

            except (httplib.CannotSendRequest, httplib.ResponseNotReady,
                    httplib.CannotSendHeader) as excep:
                raise error_util.SessionOverLoadException(
                    _("httplib error in "
                      "%(attr)s: "
                      "%(excep)s.") % {
                          'attr': attr_name,
                          'excep': excep
                      })

            except (urllib2.URLError, urllib2.HTTPError) as excep:
                raise error_util.VimConnectionException(
                    _("urllib2 error in %(attr)s: %(excep)s.") % {
                        'attr': attr_name,
                        'excep': excep
                    })

            except Exception as excep:
                # Socket errors which need special handling for they
                # might be caused by server API call overload
                if (str(excep).find(ADDRESS_IN_USE_ERROR) != -1
                        or str(excep).find(CONN_ABORT_ERROR)) != -1:
                    raise error_util.SessionOverLoadException(
                        _("Socket error "
                          "in %(attr)s: "
                          "%(excep)s.") % {
                              'attr': attr_name,
                              'excep': excep
                          })
                # Type error that needs special handling for it might be
                # caused by server API call overload
                elif str(excep).find(RESP_NOT_XML_ERROR) != -1:
                    raise error_util.SessionOverLoadException(
                        _("Type error "
                          "in %(attr)s: "
                          "%(excep)s.") % {
                              'attr': attr_name,
                              'excep': excep
                          })
                else:
                    raise error_util.VimException(
                        _("Error in %(attr)s. "
                          "Detailed error: "
                          "%(excep)s.") % {
                              'attr': attr_name,
                              'excep': excep
                          })
Esempio n. 3
0
    def test_select_datastore(self, filter_datastores, get_profile_id):
        # Test with no hosts.
        size_bytes = units.Ki
        req = {self._ds_sel.SIZE_BYTES: size_bytes}
        self._vops.get_hosts.return_value = mock.Mock(objects=[])

        self.assertEqual((), self._ds_sel.select_datastore(req))
        self._vops.get_hosts.assert_called_once_with()

        # Test with single host with no valid datastores.
        host_1 = mock.sentinel.host_1
        self._vops.get_hosts.return_value = mock.Mock(
            objects=[mock.Mock(obj=host_1)])
        self._vops.continue_retrieval.return_value = None
        self._vops.get_dss_rp.side_effect = error_util.VimException('error')

        self.assertEqual((), self._ds_sel.select_datastore(req))
        self._vops.get_dss_rp.assert_called_once_with(host_1)

        # Test with three hosts and vCenter connection problem while fetching
        # datastores for the second host.
        self._vops.get_dss_rp.reset_mock()
        host_2 = mock.sentinel.host_2
        host_3 = mock.sentinel.host_3
        self._vops.get_hosts.return_value = mock.Mock(objects=[
            mock.Mock(obj=host_1),
            mock.Mock(obj=host_2),
            mock.Mock(obj=host_3)
        ])
        self._vops.get_dss_rp.side_effect = [
            error_util.VimException('no valid datastores'),
            error_util.VimConnectionException('connection error')
        ]

        self.assertRaises(error_util.VimConnectionException,
                          self._ds_sel.select_datastore, req)
        get_dss_rp_exp_calls = [mock.call(host_1), mock.call(host_2)]
        self.assertEqual(get_dss_rp_exp_calls,
                         self._vops.get_dss_rp.call_args_list)

        # Modify previous case to return datastores for second and third host,
        # where none of them meet the requirements which include a storage
        # profile and affinity requirements.
        aff_ds_types = [ds_sel.DatastoreType.VMFS]
        req[ds_sel.DatastoreSelector.HARD_AFFINITY_DS_TYPE] = aff_ds_types

        ds_1a = mock.sentinel.ds_1a
        anti_affinity_ds = [ds_1a]
        req[ds_sel.DatastoreSelector.HARD_ANTI_AFFINITY_DS] = anti_affinity_ds

        profile_name = mock.sentinel.profile_name
        req[ds_sel.DatastoreSelector.PROFILE_NAME] = profile_name

        profile_id = mock.sentinel.profile_id
        get_profile_id.return_value = profile_id

        ds_2a = mock.sentinel.ds_2a
        ds_2b = mock.sentinel.ds_2b
        ds_3a = mock.sentinel.ds_3a

        self._vops.get_dss_rp.reset_mock()
        rp_2 = mock.sentinel.rp_2
        rp_3 = mock.sentinel.rp_3
        self._vops.get_dss_rp.side_effect = [
            error_util.VimException('no valid datastores'),
            ([ds_2a, ds_2b], rp_2), ([ds_3a], rp_3)
        ]

        filter_datastores.return_value = []

        self.assertEqual((), self._ds_sel.select_datastore(req))
        get_profile_id.assert_called_once_with(profile_name)
        get_dss_rp_exp_calls.append(mock.call(host_3))
        self.assertEqual(get_dss_rp_exp_calls,
                         self._vops.get_dss_rp.call_args_list)
        filter_datastores_exp_calls = [
            mock.call([ds_2a, ds_2b], size_bytes, profile_id, anti_affinity_ds,
                      aff_ds_types),
            mock.call([ds_3a], size_bytes, profile_id, anti_affinity_ds,
                      aff_ds_types)
        ]
        self.assertEqual(filter_datastores_exp_calls,
                         filter_datastores.call_args_list)

        # Modify previous case to have a non-empty summary list after filtering
        # with preferred utilization threshold unset.
        self._vops.get_dss_rp.side_effect = [
            error_util.VimException('no valid datastores'),
            ([ds_2a, ds_2b], rp_2), ([ds_3a], rp_3)
        ]

        summary_2b = self._create_summary(ds_2b,
                                          free_space=0.5 * units.Mi,
                                          capacity=units.Mi)
        filter_datastores.side_effect = [[summary_2b]]
        self._vops.get_connected_hosts.return_value = [host_1]

        self.assertEqual((host_2, rp_2, summary_2b),
                         self._ds_sel.select_datastore(req))

        # Modify previous case to have a preferred utilization threshold
        # satsified by one datastore.
        self._vops.get_dss_rp.side_effect = [
            error_util.VimException('no valid datastores'),
            ([ds_2a, ds_2b], rp_2), ([ds_3a], rp_3)
        ]

        req[ds_sel.DatastoreSelector.PREF_UTIL_THRESH] = 0.4
        summary_3a = self._create_summary(ds_3a,
                                          free_space=0.7 * units.Mi,
                                          capacity=units.Mi)
        filter_datastores.side_effect = [[summary_2b], [summary_3a]]

        self.assertEqual((host_3, rp_3, summary_3a),
                         self._ds_sel.select_datastore(req))

        # Modify previous case to have a preferred utilization threshold
        # which cannot be satisfied.
        self._vops.get_dss_rp.side_effect = [
            error_util.VimException('no valid datastores'),
            ([ds_2a, ds_2b], rp_2), ([ds_3a], rp_3)
        ]
        filter_datastores.side_effect = [[summary_2b], [summary_3a]]

        req[ds_sel.DatastoreSelector.PREF_UTIL_THRESH] = 0.2
        summary_2b.freeSpace = 0.75 * units.Mi

        self.assertEqual((host_2, rp_2, summary_2b),
                         self._ds_sel.select_datastore(req))

        # Clear side effects.
        self._vops.get_dss_rp.side_effect = None