pecan.jsonify v1.3 adjustment

From pecan v1.3, pecan.jsonify uses json.Encoder unconditionally so that
jsonifying mock fails.
Pecan v1.2 uses simplejson.Encoder as encoder which accidentally encodes
MagicMock as {} due to check of '_asdict' attributes.
Since pecan.jsonify uses __json__ magic method when it's defined,
add __json__ method to mocks to return {} as json encode.

Closes-bug: #1754978
Change-Id: Iac955a7de2a1b66b5b56a73f5cc8a4e75150f82e
This commit is contained in:
Isaku Yamahata 2018-04-16 23:05:53 -07:00 committed by Isaku Yamahata
parent 390cc07c8c
commit 0063aa33c6
3 changed files with 44 additions and 0 deletions

View File

@ -146,6 +146,46 @@ def verify_mock_calls(mocked_call, expected_calls_and_values,
mocked_call.assert_has_calls(expected_calls, any_order=any_order) mocked_call.assert_has_calls(expected_calls, any_order=any_order)
def _make_magic_method(method_mock):
# NOTE(yamahata): new environment needs to be created to keep actual
# method_mock for each callables.
def __call__(*args, **kwargs):
value_mock = method_mock._orig___call__(*args, **kwargs)
value_mock.__json__ = lambda: {}
return value_mock
def _get_child_mock(**kwargs):
value_mock = method_mock._orig__get_child_mock(**kwargs)
value_mock.__json__ = lambda: {}
return value_mock
return __call__, _get_child_mock
def make_mock_plugin_json_encodable(plugin_instance_mock):
# NOTE(yamahata): Make return value of plugin method json encodable
# e.g. the return value of plugin_instance.create_network() needs
# to be json encodable
# plugin instance -> method -> return value
# Mock MagicMock Mock
# plugin_instance_mock method_mock value_mock
#
# From v1.3 of pecan, pecan.jsonify uses json.Encoder unconditionally.
# pecan v1.2 uses simplejson.Encoder which accidentally encodes
# Mock as {} due to check of '_asdict' attributes.
# pecan.jsonify uses __json__ magic method for encoding when
# it's defined, so add __json__ method to return {}
for method_mock in plugin_instance_mock._mock_children.values():
if not callable(method_mock):
continue
method_mock._orig___call__ = method_mock.__call__
method_mock._orig__get_child_mock = method_mock._get_child_mock
__call__, _get_child_mock = _make_magic_method(method_mock)
method_mock.__call__ = __call__
method_mock._get_child_mock = _get_child_mock
def get_subscribe_args(*args): def get_subscribe_args(*args):
# NOTE(yamahata): from neutron-lib 1.9.1, callback priority was added. # NOTE(yamahata): from neutron-lib 1.9.1, callback priority was added.
# old signature: (callback, resource, event) # old signature: (callback, resource, event)

View File

@ -43,6 +43,7 @@ from neutron import quota
from neutron.quota import resource_registry from neutron.quota import resource_registry
from neutron.tests import base from neutron.tests import base
from neutron.tests import fake_notifier from neutron.tests import fake_notifier
from neutron.tests import tools
from neutron.tests.unit import dummy_plugin from neutron.tests.unit import dummy_plugin
from neutron.tests.unit import testlib_api from neutron.tests.unit import testlib_api
@ -87,6 +88,7 @@ class APIv2TestBase(base.BaseTestCase):
instance = self.plugin.return_value instance = self.plugin.return_value
instance._NeutronPluginBaseV2__native_pagination_support = True instance._NeutronPluginBaseV2__native_pagination_support = True
instance._NeutronPluginBaseV2__native_sorting_support = True instance._NeutronPluginBaseV2__native_sorting_support = True
tools.make_mock_plugin_json_encodable(instance)
api = router.APIRouter() api = router.APIRouter()
self.api = webtest.TestApp(api) self.api = webtest.TestApp(api)

View File

@ -28,6 +28,7 @@ from neutron.api import extensions
from neutron.api.v2 import router from neutron.api.v2 import router
from neutron.extensions import providernet as pnet from neutron.extensions import providernet as pnet
from neutron import quota from neutron import quota
from neutron.tests import tools
from neutron.tests.unit.api import test_extensions from neutron.tests.unit.api import test_extensions
from neutron.tests.unit.api.v2 import test_base from neutron.tests.unit.api.v2 import test_base
from neutron.tests.unit import testlib_api from neutron.tests.unit import testlib_api
@ -70,6 +71,7 @@ class ProvidernetExtensionTestCase(testlib_api.WebTestCase):
instance.get_networks_count.return_value = 1 instance.get_networks_count.return_value = 1
# Register mock plugin and enable the 'provider' extension # Register mock plugin and enable the 'provider' extension
instance.supported_extension_aliases = ["provider"] instance.supported_extension_aliases = ["provider"]
tools.make_mock_plugin_json_encodable(instance)
directory.add_plugin(constants.CORE, instance) directory.add_plugin(constants.CORE, instance)
ext_mgr = ProviderExtensionManager() ext_mgr = ProviderExtensionManager()
self.ext_mdw = test_extensions.setup_extensions_middleware(ext_mgr) self.ext_mdw = test_extensions.setup_extensions_middleware(ext_mgr)