Merge "Skip "PortBindingChassisEvent" if revision number changes"
This commit is contained in:
commit
c2c69e2ce0
@ -404,6 +404,16 @@ class PortBindingChassisEvent(row_event.RowEvent):
|
||||
self.event_name = 'PortBindingChassisEvent'
|
||||
|
||||
def run(self, event, row, old):
|
||||
if len(old._data) == 1 and 'external_ids' in old._data:
|
||||
# NOTE: since [1], the NB logical_router_port.external_ids are
|
||||
# copied into the SB port_binding.external_ids. If only the
|
||||
# external_ids are changed, this event should be dismissed or it
|
||||
# will trigger the Neutron NB update (that will trigger the core
|
||||
# SB update and therefore an infinite loop).
|
||||
# [1] https://www.mail-archive.com/ovs-dev@openvswitch.org/
|
||||
# msg62836.html
|
||||
return
|
||||
|
||||
if not utils.is_ovn_l3(self.l3_plugin):
|
||||
return
|
||||
router = host = None
|
||||
|
@ -423,17 +423,22 @@ class TestOVNFunctionalBase(test_plugin.Ml2PluginV2TestCase,
|
||||
self._start_ovn_northd()
|
||||
|
||||
def add_fake_chassis(self, host, physical_nets=None, external_ids=None,
|
||||
name=None, azs=None):
|
||||
name=None, azs=None, enable_chassis_as_gw=False):
|
||||
def append_cms_options(ext_ids, value):
|
||||
if 'ovn-cms-options' not in ext_ids:
|
||||
ext_ids['ovn-cms-options'] = value
|
||||
else:
|
||||
ext_ids['ovn-cms-options'] += ',' + value
|
||||
|
||||
physical_nets = physical_nets or []
|
||||
external_ids = external_ids or {}
|
||||
if azs is None:
|
||||
azs = ['ovn']
|
||||
if azs:
|
||||
if 'ovn-cms-options' not in external_ids:
|
||||
external_ids['ovn-cms-options'] = 'availability-zones='
|
||||
else:
|
||||
external_ids['ovn-cms-options'] += ',availability-zones='
|
||||
append_cms_options(external_ids, 'availability-zones=')
|
||||
external_ids['ovn-cms-options'] += ':'.join(azs)
|
||||
if enable_chassis_as_gw:
|
||||
append_cms_options(external_ids, 'enable-chassis-as-gw')
|
||||
|
||||
bridge_mapping = ",".join(["%s:br-provider%s" % (phys_net, i)
|
||||
for i, phys_net in enumerate(physical_nets)])
|
||||
|
@ -17,6 +17,7 @@ from unittest import mock
|
||||
|
||||
import fixtures as og_fixtures
|
||||
from neutron_lib.api.definitions import allowedaddresspairs
|
||||
from neutron_lib.api.definitions import external_net
|
||||
from neutron_lib.api.definitions import portbindings
|
||||
from neutron_lib.plugins import constants as plugin_constants
|
||||
from neutron_lib.plugins import directory
|
||||
@ -26,7 +27,6 @@ from oslo_utils import uuidutils
|
||||
from ovsdbapp.backend.ovs_idl import event
|
||||
from ovsdbapp.backend.ovs_idl import idlutils
|
||||
|
||||
|
||||
from neutron.common.ovn import constants as ovn_const
|
||||
from neutron.common import utils as n_utils
|
||||
from neutron.conf.plugins.ml2.drivers.ovn import ovn_conf
|
||||
@ -35,8 +35,11 @@ from neutron.plugins.ml2.drivers.ovn.agent import neutron_agent
|
||||
from neutron.plugins.ml2.drivers.ovn.mech_driver import mech_driver
|
||||
from neutron.plugins.ml2.drivers.ovn.mech_driver.ovsdb import ovsdb_monitor
|
||||
from neutron.tests.functional import base
|
||||
from neutron.tests.functional.resources.ovsdb import events as test_events
|
||||
from neutron.tests.functional.resources.ovsdb import fixtures
|
||||
from neutron.tests.functional.resources import process
|
||||
from neutron.tests.unit.api import test_extensions
|
||||
from neutron.tests.unit.extensions import test_l3
|
||||
|
||||
|
||||
class WaitForDataPathBindingCreateEvent(event.WaitEvent):
|
||||
@ -364,6 +367,64 @@ class TestNBDbMonitorOverSsl(TestNBDbMonitor):
|
||||
return 'ssl'
|
||||
|
||||
|
||||
class TestSBDbMonitor(base.TestOVNFunctionalBase, test_l3.L3NatTestCaseMixin):
|
||||
|
||||
def setUp(self, **kwargs):
|
||||
super().setUp(**kwargs)
|
||||
self.chassis = self.add_fake_chassis('ovs-host1',
|
||||
enable_chassis_as_gw=True)
|
||||
self.l3_plugin = directory.get_plugin(plugin_constants.L3)
|
||||
ext_mgr = test_l3.L3TestExtensionManager()
|
||||
self.ext_api = test_extensions.setup_extensions_middleware(ext_mgr)
|
||||
self.handler = event.RowEventHandler()
|
||||
self.sb_api.idl.notify = self.handler.notify
|
||||
|
||||
def _find_port_binding(self, port_type):
|
||||
rows = self.sb_api.db_find_rows(
|
||||
'Port_Binding', ('type', '=', port_type)).execute(check_error=True)
|
||||
return rows[0] if rows else None
|
||||
|
||||
def test_router_port_binding(self):
|
||||
# This test will check the router GW port creation and binding.
|
||||
def check_ext_ids():
|
||||
pb = self._find_port_binding(ovn_const.OVN_CHASSIS_REDIRECT)
|
||||
_, lrp = list(
|
||||
self.nb_api.tables['Logical_Router_Port'].rows.data.items())[0]
|
||||
if pb.external_ids == {}:
|
||||
# The current version of OVN installed in FT CI could not have
|
||||
# [1]. In this case, the Port_Binding.external_ids value is an
|
||||
# empty dictionary.
|
||||
# [1]https://www.mail-archive.com/ovs-dev@openvswitch.org/
|
||||
# msg62836.html
|
||||
return True
|
||||
return lrp.external_ids == pb.external_ids
|
||||
|
||||
kwargs = {'arg_list': (external_net.EXTERNAL,),
|
||||
external_net.EXTERNAL: True}
|
||||
ext_net = self._make_network(self.fmt, 'ext_net', True, **kwargs)
|
||||
self._make_subnet(self.fmt, ext_net, '10.251.0.1', '10.251.0.0/24',
|
||||
enable_dhcp=True)
|
||||
router = self._make_router(self.fmt, self._tenant_id)
|
||||
row_event = test_events.WaitForCreatePortBindingEventPerType()
|
||||
self.handler.watch_event(row_event)
|
||||
self._add_external_gateway_to_router(router['router']['id'],
|
||||
ext_net['network']['id'])
|
||||
self.assertTrue(row_event.wait())
|
||||
|
||||
# Check SB pb.external_ids == NB lrp.external_ids
|
||||
port_binding = self._find_port_binding(ovn_const.OVN_CHASSIS_REDIRECT)
|
||||
self.sb_api.db_set('Port_Binding', port_binding.uuid,
|
||||
('up', True)).execute(check_error=True)
|
||||
try:
|
||||
n_utils.wait_until_true(check_ext_ids, timeout=5)
|
||||
except n_utils.WaitTimeout:
|
||||
pb = self._find_port_binding(ovn_const.OVN_CHASSIS_REDIRECT)
|
||||
_, lrp = list(
|
||||
self.nb_api.tables['Logical_Router_Port'].rows.data.items())[0]
|
||||
self.fail('pb.ext_ids: %s -- lrp.ext_ids: %s' %
|
||||
(pb.external_ids, lrp.external_ids))
|
||||
|
||||
|
||||
class TestAgentMonitor(base.TestOVNFunctionalBase):
|
||||
FAKE_CHASSIS_HOST = 'fake-chassis-host'
|
||||
|
||||
|
@ -18,6 +18,8 @@ import threading
|
||||
from ovsdbapp.backend.ovs_idl import event
|
||||
from ovsdbapp.tests.functional.schema.ovn_southbound import event as test_event
|
||||
|
||||
from neutron.common.ovn import constants as ovn_const
|
||||
|
||||
|
||||
class WaitForCrLrpPortBindingEvent(event.RowEvent):
|
||||
event_name = 'WaitForCrLrpPortBindingEvent'
|
||||
@ -63,3 +65,12 @@ class WaitForUpdatePortBindingEvent(test_event.WaitForPortBindingEvent):
|
||||
(('logical_port', '=', port),
|
||||
('mac', '=', mac)),
|
||||
timeout=timeout)
|
||||
|
||||
|
||||
class WaitForCreatePortBindingEventPerType(event.WaitEvent):
|
||||
event_name = 'WaitForCreatePortBindingEventPerType'
|
||||
|
||||
def __init__(self, port_type=ovn_const.OVN_CHASSIS_REDIRECT,
|
||||
timeout=5):
|
||||
super().__init__((self.ROW_CREATE,), 'Port_Binding',
|
||||
(('type', '=', port_type),), timeout=timeout)
|
||||
|
Loading…
Reference in New Issue
Block a user