Merge "Added test cases for DVR L3 schedulers."

This commit is contained in:
Jenkins 2016-07-29 19:30:21 +00:00 committed by Gerrit Code Review
commit 5be941a4a1
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()