Fix Rollback port's device_owner
From this patch: https://review.openstack.org/#/c/341427/ Sometimes, port doesn't revert device_owner to previous value in concurrent requests case. This patch fixes this problem and adds unit test. Change-Id: I864a559f0316e164caa065abd75c44fae971b571 Closes-Bug: #1621750
This commit is contained in:
parent
dc6e83771c
commit
5f9d888707
|
@ -802,13 +802,13 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
|
|||
port, subnets, new_port = self._add_interface_by_subnet(
|
||||
context, router, interface_info['subnet_id'], device_owner)
|
||||
cleanup_port = new_port # only cleanup port we created
|
||||
revert_value = {'device_id': '',
|
||||
'device_owner': port['device_owner']}
|
||||
|
||||
if cleanup_port:
|
||||
mgr = p_utils.delete_port_on_error(
|
||||
self._core_plugin, context, port['id'])
|
||||
else:
|
||||
revert_value = {'device_id': '',
|
||||
'device_owner': port['device_owner']}
|
||||
mgr = p_utils.update_port_on_error(
|
||||
self._core_plugin, context, port['id'], revert_value)
|
||||
|
||||
|
|
|
@ -327,6 +327,8 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
|
|||
port, subnets, new_port = self._add_interface_by_subnet(
|
||||
context, router, interface_info['subnet_id'], device_owner)
|
||||
cleanup_port = new_port
|
||||
revert_value = {'device_id': '',
|
||||
'device_owner': port['device_owner']}
|
||||
|
||||
subnet = subnets[0]
|
||||
|
||||
|
@ -334,8 +336,6 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
|
|||
mgr = p_utils.delete_port_on_error(
|
||||
self._core_plugin, context, port['id'])
|
||||
else:
|
||||
revert_value = {'device_id': '',
|
||||
'device_owner': port['device_owner']}
|
||||
mgr = p_utils.update_port_on_error(
|
||||
self._core_plugin, context, port['id'], revert_value)
|
||||
|
||||
|
|
|
@ -52,6 +52,10 @@ class L3DvrTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
|
|||
with self.ctx.session.begin(subtransactions=True):
|
||||
return self.mixin._create_router_db(self.ctx, router, 'foo_tenant')
|
||||
|
||||
def create_port(self, net_id, port_info):
|
||||
with self.ctx.session.begin(subtransactions=True):
|
||||
return self._create_port(self.fmt, net_id, **port_info)
|
||||
|
||||
def _test__create_router_db(self, expected=False, distributed=None):
|
||||
router = {'name': 'foo_router', 'admin_state_up': True}
|
||||
if distributed is not None:
|
||||
|
@ -725,3 +729,46 @@ class L3DvrTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
|
|||
self.assertEqual(1, len(router_ports))
|
||||
self.assertEqual(l3_const.DEVICE_OWNER_ROUTER_GW,
|
||||
router_ports[0]['device_owner'])
|
||||
|
||||
def test_add_router_interface_by_port_failure(self):
|
||||
router_dict = {'name': 'test_router',
|
||||
'admin_state_up': True,
|
||||
'distributed': True}
|
||||
router = self._create_router(router_dict)
|
||||
with self.subnet(cidr='10.10.10.0/24') as subnet:
|
||||
port_dict = {
|
||||
'device_id': '',
|
||||
'device_owner': '',
|
||||
'admin_state_up': True,
|
||||
'fixed_ips': [{'subnet_id': subnet['subnet']['id'],
|
||||
'ip_address': '10.10.10.100'}]
|
||||
}
|
||||
net_id = subnet['subnet']['network_id']
|
||||
port_res = self.create_port(net_id, port_dict)
|
||||
port = self.deserialize(self.fmt, port_res)
|
||||
self.assertIn('port', port, message='Create port failed.')
|
||||
|
||||
orig_update_port = self.mixin._core_plugin.update_port
|
||||
call_info = {'count': 0}
|
||||
|
||||
def _fake_update_port(*args, **kwargs):
|
||||
call_info['count'] += 1
|
||||
if call_info['count'] == 2:
|
||||
raise RuntimeError()
|
||||
else:
|
||||
return orig_update_port(*args, **kwargs)
|
||||
|
||||
# NOTE(trananhkma): expect that update_port() only raises an error
|
||||
# at the 2nd function call (Update owner after actual process
|
||||
# again in order).
|
||||
with mock.patch.object(self.mixin._core_plugin, 'update_port',
|
||||
side_effect=_fake_update_port):
|
||||
self.assertRaises(
|
||||
RuntimeError,
|
||||
self.mixin.add_router_interface,
|
||||
self.ctx, router['id'], {'port_id': port['port']['id']})
|
||||
|
||||
port_info = self.core_plugin.get_port(self.ctx, port['port']['id'])
|
||||
self.assertEqual(port_dict['device_id'], port_info['device_id'])
|
||||
self.assertEqual(port_dict['device_owner'],
|
||||
port_info['device_owner'])
|
||||
|
|
Loading…
Reference in New Issue