Merge "Guard against concurrent port removal in DVR"
This commit is contained in:
commit
7193476d03
@ -576,6 +576,7 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
|
||||
ports = (
|
||||
rp.port.id for rp in
|
||||
router.attached_ports.filter_by(port_type=DEVICE_OWNER_DVR_SNAT)
|
||||
if rp.port
|
||||
)
|
||||
|
||||
c_snat_ports = self._core_plugin.get_ports(
|
||||
|
@ -24,6 +24,7 @@ from neutron.common import exceptions as exc
|
||||
from neutron.common import utils
|
||||
from neutron import context
|
||||
from neutron.db import db_base_plugin_v2 as base_plugin
|
||||
from neutron.db import l3_db
|
||||
from neutron.extensions import external_net as external_net
|
||||
from neutron.extensions import l3agentscheduler
|
||||
from neutron.extensions import multiprovidernet as mpnet
|
||||
@ -296,6 +297,38 @@ class TestMl2DvrPortsV2(TestMl2PortsV2):
|
||||
self._test_delete_dvr_serviced_port(
|
||||
device_owner=constants.DEVICE_OWNER_LOADBALANCER)
|
||||
|
||||
def test_concurrent_csnat_port_delete(self):
|
||||
plugin = manager.NeutronManager.get_service_plugins()[
|
||||
service_constants.L3_ROUTER_NAT]
|
||||
r = plugin.create_router(
|
||||
self.context,
|
||||
{'router': {'name': 'router', 'admin_state_up': True}})
|
||||
with self.subnet() as s:
|
||||
p = plugin.add_router_interface(self.context, r['id'],
|
||||
{'subnet_id': s['subnet']['id']})
|
||||
|
||||
# lie to turn the port into an SNAT interface
|
||||
with self.context.session.begin():
|
||||
rp = self.context.session.query(l3_db.RouterPort).filter_by(
|
||||
port_id=p['port_id']).first()
|
||||
rp.port_type = constants.DEVICE_OWNER_ROUTER_SNAT
|
||||
|
||||
# take the port away before csnat gets a chance to delete it
|
||||
# to simulate a concurrent delete
|
||||
orig_get_ports = plugin._core_plugin.get_ports
|
||||
|
||||
def get_ports_with_delete_first(*args, **kwargs):
|
||||
plugin._core_plugin.delete_port(self.context,
|
||||
p['port_id'],
|
||||
l3_port_check=False)
|
||||
return orig_get_ports(*args, **kwargs)
|
||||
plugin._core_plugin.get_ports = get_ports_with_delete_first
|
||||
|
||||
# This should be able to handle a concurrent delete without raising
|
||||
# an exception
|
||||
router = plugin._get_router(self.context, r['id'])
|
||||
plugin.delete_csnat_router_interface_ports(self.context, router)
|
||||
|
||||
|
||||
class TestMl2PortBinding(Ml2PluginV2TestCase,
|
||||
test_bindings.PortBindingsTestCase):
|
||||
|
Loading…
Reference in New Issue
Block a user