Skip to content

Commit

Permalink
Merge "Reduce DB hit when checking for trunk-able ports"
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins authored and openstack-gerrit committed Aug 31, 2016
2 parents 8ad9558 + b3c2a4a commit 92bcaed
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 34 deletions.
3 changes: 2 additions & 1 deletion neutron/services/trunk/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,11 @@ def can_be_trunked(self, context):
# can be determined based on the vif type, whether or not the
# driver is agent-based, and whether the host is running the agent
# associated to the driver itself.
host_agent_types = utils.get_agent_types_by_host(context, binding_host)
drivers = [
driver for driver in trunk_plugin.registered_drivers
if utils.is_driver_compatible(
context, driver, vif_type, binding_host)
context, driver, vif_type, host_agent_types)
]
if len(drivers) > 1:
raise trunk_exc.TrunkPluginDriverConflict()
Expand Down
22 changes: 10 additions & 12 deletions neutron/services/trunk/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,19 @@ def gen_trunk_br_name(trunk_id):
[:constants.DEVICE_NAME_MAX_LEN - 1])


def are_agent_types_available_on_host(context, agent_types, host):
"""Return true if agent types are present on the host."""
def get_agent_types_by_host(context, host):
"""Return the agent types registered on the host."""
agent_types = []
core_plugin = manager.NeutronManager.get_plugin()
if utils.is_extension_supported(core_plugin, 'agent'):
return bool(core_plugin.get_agents(
context.elevated(),
filters={'host': [host], 'agent_type': agent_types}))
return False
agents = core_plugin.get_agents(
context.elevated(), filters={'host': [host]})
agent_types = [a['agent_type'] for a in agents]
return agent_types


def is_driver_compatible(context, driver, interface, binding_host):
"""Return true if the driver is compatible with the interface and host.
def is_driver_compatible(context, driver, interface, host_agent_types):
"""True if the driver is compatible with interface and host_agent_types.
There may be edge cases where a stale view or the deployment may make the
following test fail to detect the right driver in charge of the bound port.
Expand All @@ -56,7 +57,4 @@ def is_driver_compatible(context, driver, interface, binding_host):
return is_interface_compatible

# For an agent-based driver, both interface and agent compat is required.
return (
is_interface_compatible and
are_agent_types_available_on_host(
context, [driver.agent_type], binding_host))
return is_interface_compatible and driver.agent_type in host_agent_types
41 changes: 20 additions & 21 deletions neutron/tests/unit/services/trunk/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,50 +20,49 @@

class UtilsTestCase(test_plugin.Ml2PluginV2TestCase):

def test_are_agent_types_available_on_host_returns_false(self):
def test_get_agent_types_by_host_returns_empty(self):
self.assertFalse(
utils.are_agent_types_available_on_host(
self.context, ['foo_type'], 'foo_host'))
utils.get_agent_types_by_host(
self.context, 'foo_host'))

def test_are_agent_types_available_on_host_returns_true(self):
def test_get_agent_types_by_host_returns_agents(self):
with mock.patch("neutron.db.agents_db.AgentDbMixin.get_agents") as f:
f.return_value = ['foo_agent']
self.assertTrue(
utils.are_agent_types_available_on_host(
self.context, ['foo_type'], 'foo_host'))
f.return_value = [{'agent_type': 'foo_type'}]
self.assertEqual(
['foo_type'],
utils.get_agent_types_by_host(
self.context, 'foo_host'))

def _test_is_driver_compatible(self, driver, interface, host, agents=None):
with mock.patch("neutron.db.agents_db.AgentDbMixin.get_agents") as f:
f.return_value = agents or []
return utils.is_driver_compatible(self.context,
driver,
interface,
host)
def _test_is_driver_compatible(self, driver, interface, agent_types):
return utils.is_driver_compatible(self.context,
driver,
interface,
agent_types)

def test_is_driver_compatible(self):
driver = fakes.FakeDriverWithAgent.create()
self.assertTrue(self._test_is_driver_compatible(
driver, 'foo_intfs', 'foo_host', [{'agent_type': 'foo_type'}]))
driver, 'foo_intfs', ['foo_type']))

def test_is_driver_compatible_agent_based_agent_mismatch(self):
driver = fakes.FakeDriverWithAgent.create()
self.assertFalse(self._test_is_driver_compatible(
driver, 'foo_intfs', 'foo_host'))
driver, 'foo_intfs', ['foo_type_unknown']))

def test_is_driver_incompatible_because_of_interface_mismatch(self):
driver = fakes.FakeDriverWithAgent.create()
self.assertFalse(self._test_is_driver_compatible(
driver, 'not_my_interface', 'foo_host'))
driver, 'not_my_interface', ['foo_type']))

def test_is_driver_compatible_agentless(self):
driver = fakes.FakeDriver.create()
self.assertTrue(self._test_is_driver_compatible(
driver, 'foo_intfs', 'foo_host'))
driver, 'foo_intfs', ['foo_type']))

def test_is_driver_compatible_multiple_drivers(self):
driver1 = fakes.FakeDriverWithAgent.create()
driver2 = fakes.FakeDriver2.create()
self.assertTrue(self._test_is_driver_compatible(
driver1, 'foo_intfs', 'foo_host', [{'agent_type': 'foo_type'}]))
driver1, 'foo_intfs', ['foo_type']))
self.assertFalse(self._test_is_driver_compatible(
driver2, 'foo_intfs', 'foo_host', [{'agent_type': 'foo_type'}]))
driver2, 'foo_intfs', ['foo_type']))

0 comments on commit 92bcaed

Please sign in to comment.