def __init__(self):
"""Load the model class."""
- self._model = importutils.import_object(config.CISCO.model_class)
+ self._model_name = config.CISCO.model_class
+ self._model = importutils.import_object(self._model_name)
native_bulk_attr_name = ("_%s__native_bulk_support"
% self._model.__class__.__name__)
self.__native_bulk_support = getattr(self._model,
return getattr(self._model, name)
else:
# Must make sure we re-raise the error that led us here, since
- # otherwise getattr() and even hasattr() doesn't work corretly.
+ # otherwise getattr() and even hasattr() doesn't work correctly.
raise AttributeError(
_("'%(model)s' object has no attribute '%(name)s'") %
- {'model': self._model, 'name': name})
+ {'model': self._model_name, 'name': name})
def _extend_fault_map(self):
"""Extend the Neutron Fault Map for Cisco exceptions.
# limitations under the License.
import contextlib
+import copy
import inspect
import logging
import mock
+import six
import webob.exc as wexc
from neutron.api import extensions
from neutron.extensions import portbindings
from neutron.extensions import providernet as provider
from neutron.manager import NeutronManager
+from neutron.openstack.common import gettextutils
from neutron.plugins.cisco.common import cisco_constants as const
from neutron.plugins.cisco.common import cisco_exceptions as c_exc
from neutron.plugins.cisco.common import config as cisco_config
self.assertEqual(status, expected_http)
+class TestCiscoGetAttribute(CiscoNetworkPluginV2TestCase):
+
+ def test_get_unsupported_attr_in_lazy_gettext_mode(self):
+ """Test get of unsupported attribute in lazy gettext mode.
+
+ This test also checks that this operation does not cause
+ excessive nesting of calls to deepcopy.
+ """
+ plugin = NeutronManager.get_plugin()
+
+ def _lazy_gettext(msg):
+ return gettextutils.Message(msg, domain='neutron')
+
+ with mock.patch.dict(six.moves.builtins.__dict__,
+ {'_': _lazy_gettext}):
+ self.nesting_count = 0
+
+ def _count_nesting(*args, **kwargs):
+ self.nesting_count += 1
+
+ with mock.patch.object(copy, 'deepcopy',
+ side_effect=_count_nesting,
+ wraps=copy.deepcopy):
+ self.assertRaises(AttributeError, getattr, plugin,
+ 'an_unsupported_attribute')
+ # If there were no nested calls to deepcopy, then the total
+ # number of calls to deepcopy should be 2 (1 call for
+ # each mod'd field in the AttributeError message raised
+ # by the plugin).
+ self.assertEqual(self.nesting_count, 2)
+
+
class TestCiscoBasicGet(CiscoNetworkPluginV2TestCase,
test_db_plugin.TestBasicGet):
pass