Make deepcopy of update body in API layer
This adjusts the update handler in the API layer to pass a deepcopy of the original update body to ensure that the original is used on any generated retry requests. Without this update handlers that modified the body as they processed it (e.g. the external gateway update for routers) would be missing data on a retry request. This adds a test case for the bug that was caused by this. Closes-Bug: #1584920 Change-Id: I88fb9d45eb82ef48e0d865decdcc7fad1c5fb361
This commit is contained in:
parent
d5eac3cfe0
commit
5109d16bc5
|
@ -593,7 +593,8 @@ class Controller(object):
|
|||
|
||||
@db_api.retry_db_errors
|
||||
def _update(self, request, id, body, **kwargs):
|
||||
body = Controller.prepare_request_body(request.context, body, False,
|
||||
body = Controller.prepare_request_body(request.context,
|
||||
copy.deepcopy(body), False,
|
||||
self._resource, self._attr_info,
|
||||
allow_bulk=self._allow_bulk)
|
||||
action = self._plugin_handlers[self.UPDATE]
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
import mock
|
||||
from neutron_lib import constants
|
||||
from oslo_config import cfg
|
||||
from oslo_db import exception as db_exc
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import uuidutils
|
||||
import testscenarios
|
||||
|
@ -389,6 +390,19 @@ class ExtGwModeIntTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase,
|
|||
expected_code=expected_code,
|
||||
neutron_context=neutron_context)
|
||||
|
||||
def test_router_gateway_set_retry(self):
|
||||
with self.router() as r, self.subnet() as s:
|
||||
ext_net_id = s['subnet']['network_id']
|
||||
self._set_net_external(ext_net_id)
|
||||
with mock.patch.object(
|
||||
l3_db.L3_NAT_dbonly_mixin, '_validate_gw_info',
|
||||
side_effect=[db_exc.RetryRequest(None), ext_net_id]):
|
||||
self._set_router_external_gateway(r['router']['id'],
|
||||
ext_net_id)
|
||||
res = self._show('routers', r['router']['id'])['router']
|
||||
self.assertEqual(ext_net_id,
|
||||
res['external_gateway_info']['network_id'])
|
||||
|
||||
def test_router_create_with_gwinfo_invalid_ext_ip(self):
|
||||
with self.subnet() as s:
|
||||
self._set_net_external(s['subnet']['network_id'])
|
||||
|
|
Loading…
Reference in New Issue