# one enabled l3 agent hosting since active is just a
# timing problem. Non-active l3 agent can return to
# active any time
- l3_agents = plugin.get_l3_agents_hosting_routers(
+ current_l3_agents = plugin.get_l3_agents_hosting_routers(
context, [sync_router['id']], admin_state_up=True)
- if l3_agents and not sync_router.get('distributed', False):
+ is_router_distributed = sync_router.get('distributed', False)
+ if current_l3_agents and not is_router_distributed:
LOG.debug('Router %(router_id)s has already been hosted '
'by L3 agent %(agent_id)s',
{'router_id': sync_router['id'],
- 'agent_id': l3_agents[0]['id']})
+ 'agent_id': current_l3_agents[0]['id']})
return []
active_l3_agents = plugin.get_l3_agents(context, active=True)
if not active_l3_agents:
LOG.warn(_LW('No active L3 agents'))
return []
- new_l3agents = plugin.get_l3_agent_candidates(context,
- sync_router,
- active_l3_agents)
- old_l3agentset = set(l3_agents)
- if sync_router.get('distributed', False):
- new_l3agentset = set(new_l3agents)
- candidates = list(new_l3agentset - old_l3agentset)
- else:
- candidates = new_l3agents
- if not candidates:
+ potential_candidates = list(
+ set(active_l3_agents) - set(current_l3_agents))
+ new_l3agents = []
+ if potential_candidates:
+ new_l3agents = plugin.get_l3_agent_candidates(
+ context, sync_router, potential_candidates)
+ if not new_l3agents:
LOG.warn(_LW('No L3 agents can host the router %s'),
sync_router['id'])
-
- return candidates
+ return new_l3agents
def _bind_routers(self, context, plugin, routers, l3_agent):
for router in routers:
router['distributed'] = True
plugin.get_l3_agents.return_value = []
iter(self.scheduler._get_candidates(plugin, mock.MagicMock(), router))
+ self.assertFalse(plugin.get_l3_agent_candidates.called)
+
+ def test__get_candidates_skips_get_l3_agent_candidates_if_dvr_scheduled(
+ self):
+ plugin = mock.MagicMock()
+ # distributed router already hosted
+ plugin.get_l3_agents_hosting_routers.return_value = ['a1']
+ router = {'distributed': True, 'id': str(uuid.uuid4())}
+ plugin.get_l3_agents.return_value = ['a1']
+ self.scheduler._get_candidates(plugin, mock.MagicMock(), router)
+ self.assertFalse(plugin.get_l3_agent_candidates.called)
+
+ def test__get_candidates_calls_get_l3_agent_candidates_if_agent_available(
+ self):
+ plugin = mock.MagicMock()
+ # distributed router already hosted in two agent 'a1' and 'a2'
+ plugin.get_l3_agents_hosting_routers.return_value = ['a1', 'a2']
+ router = {'distributed': True, 'id': str(uuid.uuid4())}
+ # Available distributed agents
+ plugin.get_l3_agents.return_value = ['a1', 'a2', 'a3', 'a4', 'a5']
+ unscheduled_agents = ['a3', 'a4', 'a5']
+ plugin.get_l3_agent_candidates.return_value = ['a3', 'a4']
+ agents_returned = self.scheduler._get_candidates(
+ plugin, mock.MagicMock(), router)
+ plugin.get_l3_agent_candidates.called_once_with(
+ mock.ANY, router, unscheduled_agents)
+ self.assertEqual(['a3', 'a4'], sorted(agents_returned))
class L3SchedulerBaseMixin(object):