Added test cases for DVR L3 schedulers.

Test cases listed below are to run for Chance and Least-routers scheduler,
for both auto and explicit scheduling.
  1. Legacy router scheduled on dvr_snat agent.
  2. Distributed router not scheduled on legacy agent.
  3. Distributed router not scheduled on dvr agent.
  4. Distributed router scheduled on dvr_snat agent.
  5. Already hosted legacy router not scheduled on dvr agent.
  6. Already hosted legacy router not scheduled on dvr_snat agent.
  7. Already hosted distributed router not scheduled on legacy agent.
  8. Already hosted distributed router not scheduled on dvr agent.
  9. Already hosted distributed router not scheduled on dvr_snat agent.
  10. Already hosted legacy router not scheduled on additional dvr agent.
  11. Distributed router not scheduled if it is on a different external
      network than the dvr_snat agent.

Change-Id: I94d6654631b3cd66dfd469b1230c3ec20d0c0369
This commit is contained in:
Ritesh Anand 2015-06-03 08:25:32 -07:00 committed by Ritesh Anand
parent 412012de59
commit b47bd6bce1
1 changed files with 287 additions and 6 deletions

View File

@ -18,12 +18,21 @@ import random
import testscenarios
from oslo_utils import uuidutils
from neutron.api.v2 import attributes
from neutron.common import constants
from neutron import context
from neutron.db import external_net_db
from neutron.scheduler import l3_agent_scheduler
from neutron.services.l3_router import l3_router_plugin
from neutron.tests.common import helpers
from neutron.tests.unit.db import test_db_base_plugin_v2
_uuid = uuidutils.generate_uuid
PLUGIN_NAME = 'neutron.plugins.ml2.plugin.Ml2Plugin'
# Required to generate tests from scenarios. Not compatible with nose.
load_tests = testscenarios.load_tests_apply_scenarios
@ -35,15 +44,16 @@ class L3SchedulerBaseTest(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
"""
def setUp(self):
super(L3SchedulerBaseTest, self).setUp()
super(L3SchedulerBaseTest, self).setUp(PLUGIN_NAME)
self.l3_plugin = l3_router_plugin.L3RouterPlugin()
self.adminContext = context.get_admin_context()
self.adminContext.tenant_id = '_func_test_tenant_'
self.adminContext.tenant_id = _uuid()
def _create_l3_agent(self, host, context, agent_mode='legacy', plugin=None,
state=True):
agent = helpers.register_l3_agent(host, agent_mode)
def _create_l3_agent(self, host, context, agent_mode='legacy',
state=True, ext_net_id=''):
agent = helpers.register_l3_agent(host, agent_mode,
ext_net_id=ext_net_id)
helpers.set_agent_admin_state(agent.id, state)
return agent
@ -58,7 +68,7 @@ class L3SchedulerBaseTest(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
# down agent count.
self.hosts = ['host-%s' % i for i in range(agent_count)]
self.l3_agents = [self._create_l3_agent(self.hosts[i],
self.adminContext, 'legacy', self.l3_plugin,
self.adminContext, 'legacy',
(i >= down_agent_count)) for i in range(agent_count)]
def _create_routers(self, scheduled_router_count,
@ -549,3 +559,274 @@ class L3AZAutoScheduleTestCaseBase(L3AZSchedulerBaseTest):
for i in range(self.az_count):
self.assertEqual(self.expected_scheduled_agent_count[i],
scheduled_azs.get('az%s' % i, 0))
class L3DVRSchedulerBaseTest(L3SchedulerBaseTest):
"""Base class for functional test of DVR L3 schedulers.
Provides basic setup and utility functions.
"""
def setUp(self):
super(L3DVRSchedulerBaseTest, self).setUp()
self.default_ext_net_id = _uuid()
self.default_ext_subnet_id = _uuid()
self.router_ext_net_id = _uuid()
self.router_ext_subnet_id = _uuid()
def _create_router(self, name, distributed, ext_net_id=None):
router = {'name': name, 'admin_state_up': True,
'tenant_id': self.adminContext.tenant_id,
'distributed': distributed}
if ext_net_id:
router['external_gateway_info'] = {'network_id': ext_net_id}
return self.l3_plugin.create_router(self.adminContext,
{'router': router})
def _create_network(self, net_id, name=None, external=False):
network_dict = {'tenant_id': self.adminContext.tenant_id,
'id': net_id,
'name': name,
'admin_state_up': True,
'shared': False,
'status': constants.NET_STATUS_ACTIVE}
network = self.plugin.create_network(self.adminContext,
{'network': network_dict})
if external:
with self.adminContext.session.begin():
network = external_net_db.ExternalNetwork(network_id=net_id)
self.adminContext.session.add(network)
return network
def _create_subnet(self, sub_id, network_id, cidr, gw_ip, name='test_sub'):
subnet = {'tenant_id': self.adminContext.tenant_id,
'id': sub_id,
'name': name,
'network_id': network_id,
'ip_version': 4,
'cidr': cidr,
'enable_dhcp': False,
'gateway_ip': gw_ip,
'shared': False,
'allocation_pools': attributes.ATTR_NOT_SPECIFIED,
'dns_nameservers': attributes.ATTR_NOT_SPECIFIED,
'host_routes': attributes.ATTR_NOT_SPECIFIED}
return self.plugin.create_subnet(self.adminContext, {'subnet': subnet})
class L3DVRSchedulerTestCase(L3DVRSchedulerBaseTest):
"""Test various scenarios for L3 DVR schedulers:
agent_mode
L3 agent mode.
second_agent_mode
Second L3 agent mode for scenarios with two agents.
agent_has_ext_network
Is there external network on the host.
router_is_distributed
Is router distributed.
router_already_hosted
Is router already hosted.
router_has_ext_gw
Does router have external gateway.
router_agent_have_same_ext_net
Do router and agent have the same external network.
expected_router_scheduled
To verify do we expect router to get scheduled.
"""
def get_scenario(agent_mode=constants.L3_AGENT_MODE_DVR_SNAT,
second_agent_mode=None,
agent_has_ext_network=False,
router_is_distributed=False,
router_already_hosted=False,
router_has_ext_gw=False,
router_agent_have_same_ext_net=False,
expected_router_scheduled=False):
return dict(agent_mode=agent_mode,
second_agent_mode=second_agent_mode,
agent_has_ext_network=agent_has_ext_network,
router_is_distributed=router_is_distributed,
router_already_hosted=router_already_hosted,
router_has_ext_gw=router_has_ext_gw,
router_agent_have_same_ext_net=router_agent_have_same_ext_net,
expected_router_scheduled=expected_router_scheduled)
scenarios = [
('Legacy router not scheduled on dvr agent',
get_scenario(agent_mode=constants.L3_AGENT_MODE_DVR)),
('Legacy router scheduled on dvr_snat agent',
get_scenario(expected_router_scheduled=True)),
('Distributed router not scheduled on legacy agent',
get_scenario(agent_mode=constants.L3_AGENT_MODE_LEGACY,
router_is_distributed=True)),
('Distributed router not scheduled on dvr agent',
get_scenario(agent_mode=constants.L3_AGENT_MODE_DVR,
router_is_distributed=True)),
('Distributed router scheduled on dvr_snat agent',
get_scenario(router_is_distributed=True,
expected_router_scheduled=True)),
('Already hosted legacy router not scheduled on dvr agent',
get_scenario(agent_mode=constants.L3_AGENT_MODE_DVR,
router_already_hosted=True)),
('Already hosted legacy router not scheduled on dvr_snat agent',
get_scenario(router_already_hosted=True)),
('Already hosted distributed router not scheduled on legacy agent',
get_scenario(agent_mode=constants.L3_AGENT_MODE_LEGACY,
router_already_hosted=True,
router_is_distributed=True)),
('Already hosted distributed router not scheduled on dvr agent',
get_scenario(agent_mode=constants.L3_AGENT_MODE_DVR,
router_is_distributed=True,
router_already_hosted=True)),
('Already hosted distributed router not scheduled on dvr_snat agent',
get_scenario(router_is_distributed=True,
router_already_hosted=True)),
('Already hosted legacy router not scheduled on additional dvr agent',
get_scenario(agent_mode=constants.L3_AGENT_MODE_LEGACY,
second_agent_mode=constants.L3_AGENT_MODE_DVR_SNAT,
router_already_hosted=True)),
('Distributed router not scheduled if it is on a different '
'external network than the dvr_snat agent',
get_scenario(agent_has_ext_network=True,
router_is_distributed=True,
router_has_ext_gw=True,
router_agent_have_same_ext_net=False)),
]
def setUp(self):
super(L3DVRSchedulerTestCase, self).setUp()
agent_cnt = 2 if self.second_agent_mode else 1
# create hosts for each agent
self.hosts = ['host-%s' % i for i in range(agent_cnt)]
# create default external network
self._create_network(self.default_ext_net_id,
name='_test-ext-net', external=True)
self._create_subnet(self.default_ext_subnet_id,
self.default_ext_net_id,
'10.10.9.0/24', '10.10.9.1',
'_test-ext-net-subnet')
if self.router_has_ext_gw and not self.router_agent_have_same_ext_net:
# for the test cases in which router and agent are not on same
# external network, we create an external network for router
self._create_network(self.router_ext_net_id,
name='_test-ext-net2', external=True)
self._create_subnet(self.router_ext_subnet_id,
self.router_ext_net_id,
'10.10.8.0/24', '10.10.8.1',
'_test-ext-net2-subnet')
# create agents:
self.l3_agents = [self._create_l3_agent(self.hosts[0],
self.adminContext, self.agent_mode, True,
self.default_ext_net_id if self.agent_has_ext_network else '')]
if self.second_agent_mode:
self.l3_agents.append(self._create_l3_agent(self.hosts[1],
self.adminContext, self.second_agent_mode, True,
self.default_ext_net_id if self.agent_has_ext_network else ''))
# The router to schedule:
self.router_to_schedule = self._create_router_to_schedule()
def _create_router_to_schedule(self):
router_to_schedule = None
if self.router_has_ext_gw:
if self.router_agent_have_same_ext_net:
router_to_schedule = self._create_router('schd_rtr',
self.router_is_distributed,
self.default_ext_net_id)
else:
router_to_schedule = self._create_router('schd_rtr',
self.router_is_distributed,
self.router_ext_net_id)
else:
router_to_schedule = self._create_router('schd_rtr',
self.router_is_distributed)
return router_to_schedule
def _test_schedule_router(self):
if self.router_already_hosted:
self.scheduler.bind_router(self.adminContext,
self.router_to_schedule['id'],
self.l3_agents[0])
# schedule:
actual_scheduled_agent = self.scheduler.schedule(
self.l3_plugin,
self.adminContext,
self.router_to_schedule['id'])
# check for router scheduling:
self.assertEqual(self.expected_router_scheduled,
bool(actual_scheduled_agent),
message='Failed to schedule agent')
def _test_auto_schedule_routers(self):
if self.router_already_hosted:
self.scheduler.bind_router(self.adminContext,
self.router_to_schedule['id'],
self.l3_agents[0])
did_it_schedule = False
# schedule:
for host in self.hosts:
did_it_schedule = self.scheduler.auto_schedule_routers(
self.l3_plugin, self.adminContext,
host, [self.router_to_schedule['id']])
if did_it_schedule:
break
if self.router_already_hosted:
self.assertFalse(did_it_schedule,
'Agent pre scheduled, yet no binding found!')
elif self.expected_router_scheduled:
self.assertTrue(did_it_schedule,
'Agent not scheduled, not expected')
else:
self.assertFalse(did_it_schedule, 'Agent scheduled, not expected')
def test_least_routers_schedule_router(self):
self.scheduler = l3_agent_scheduler.LeastRoutersScheduler()
self._test_schedule_router()
def test_least_routers_auto_schedule_routers(self):
self.scheduler = l3_agent_scheduler.LeastRoutersScheduler()
self._test_auto_schedule_routers()
def test_chance_schedule_router(self):
self.scheduler = l3_agent_scheduler.ChanceScheduler()
self._test_schedule_router()
def test_chance_auto_schedule_routers(self):
self.scheduler = l3_agent_scheduler.ChanceScheduler()
self._test_auto_schedule_routers()