Skip to content

Commit

Permalink
Add coverage for extra routes extension
Browse files Browse the repository at this point in the history
Test the extra routes extension for legacy and HA routers
in the L3 agent functional tests.

Partially-Implements: bp/restructure-l3-agent
Change-Id: I26444acf32652d1845ad0325a3a10b8a17c510c9
  • Loading branch information
assafmuller committed Jan 26, 2015
1 parent 51fcac0 commit 7bbba6c
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 5 deletions.
30 changes: 30 additions & 0 deletions neutron/agent/linux/ip_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,36 @@ def device_exists_with_ip_mac(device_name, ip_cidr, mac, namespace=None,
return True


def get_routing_table(root_helper=None, namespace=None):
"""Return a list of dictionaries, each representing a route.
The dictionary format is: {'destination': cidr,
'nexthop': ip,
'device': device_name}
"""

ip_wrapper = IPWrapper(root_helper, namespace=namespace)
table = ip_wrapper.netns.execute(['ip', 'route'], check_exit_code=True)

routes = []
# Example for route_lines:
# default via 192.168.3.120 dev wlp3s0 proto static metric 1024
# 10.0.0.0/8 dev tun0 proto static scope link metric 1024
# The first column is the destination, followed by key/value pairs.
# The generator splits the routing table by newline, then strips and splits
# each individual line.
route_lines = (line.split() for line in table.split('\n') if line.strip())
for route in route_lines:
network = route[0]
# Create a dict of key/value pairs (For example - 'dev': 'tun0')
# excluding the first column.
data = dict(route[i:i + 2] for i in range(1, len(route), 2))
routes.append({'destination': network,
'nexthop': data.get('via'),
'device': data.get('dev')})
return routes


def ensure_device_is_ready(device_name, root_helper=None, namespace=None):
dev = IPDevice(device_name, root_helper, namespace)
dev.set_log_fail_as_error(False)
Expand Down
19 changes: 19 additions & 0 deletions neutron/tests/functional/agent/linux/test_ip_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import collections

import netaddr
from oslo.config import cfg
from oslo.utils import importutils

Expand Down Expand Up @@ -130,3 +131,21 @@ def test_device_exists_with_ip_mac(self):
*attr, root_helper=self.root_helper))

device.link.delete()

def test_get_routing_table(self):
attr = self.generate_device_details()
device = self.manage_device(attr)
device_ip = attr.ip_cidr.split('/')[0]
destination = '8.8.8.0/24'
device.route.add_route(destination, device_ip)

expected_routes = [{'nexthop': device_ip,
'device': attr.name,
'destination': destination},
{'nexthop': None,
'device': attr.name,
'destination': str(
netaddr.IPNetwork(attr.ip_cidr).cidr)}]

routes = ip_lib.get_routing_table(self.root_helper, attr.namespace)
self.assertEqual(expected_routes, routes)
25 changes: 22 additions & 3 deletions neutron/tests/functional/agent/test_l3_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ def _configure_agent(self, host):
def generate_router_info(self, enable_ha):
return test_l3_agent.prepare_router_data(enable_snat=True,
enable_floating_ip=True,
enable_ha=enable_ha)
enable_ha=enable_ha,
extra_routes=True)

def manage_router(self, agent, router):
self.addCleanup(self._delete_router, agent, router['id'])
Expand Down Expand Up @@ -190,6 +191,7 @@ def get_expected_keepalive_configuration(self, router):
}
virtual_routes {
0.0.0.0/0 via %(default_gateway_ip)s dev %(external_device_name)s
8.8.8.0/24 via 19.4.4.4
}
}""" % {
'ha_confs_path': ha_confs_path,
Expand Down Expand Up @@ -247,6 +249,14 @@ def _assert_internal_devices(self, router):
self.assertTrue(self.device_exists_with_ip_mac(
device, self.agent.get_internal_device_name, router.ns_name))

def _assert_extra_routes(self, router):
routes = ip_lib.get_routing_table(self.root_helper, router.ns_name)
routes = [{'nexthop': route['nexthop'],
'destination': route['destination']} for route in routes]

for extra_route in router.router['routes']:
self.assertIn(extra_route, routes)


class L3AgentTestCase(L3AgentTestFramework):
def test_observer_notifications_legacy_router(self):
Expand Down Expand Up @@ -309,8 +319,15 @@ def test_keepalived_configuration(self):
self.assertIn(new_fip, new_config)
self.assertNotIn(old_gw, new_config)
self.assertIn(new_gw, new_config)
self.assertNotIn(old_external_device_ip, new_config)
self.assertIn(new_external_device_ip, new_config)
external_port = self.agent._get_ex_gw_port(router)
external_device_name = self.agent.get_external_device_name(
external_port['id'])
self.assertNotIn('%s/24 dev %s' %
(old_external_device_ip, external_device_name),
new_config)
self.assertIn('%s/24 dev %s' %
(new_external_device_ip, external_device_name),
new_config)

def _router_lifecycle(self, enable_ha):
router_info = self.generate_router_info(enable_ha)
Expand Down Expand Up @@ -343,6 +360,7 @@ def _router_lifecycle(self, enable_ha):
self._assert_snat_chains(router)
self._assert_floating_ip_chains(router)
self._assert_metadata_chains(router)
self._assert_extra_routes(router)

if enable_ha:
self._assert_ha_device(router)
Expand Down Expand Up @@ -546,6 +564,7 @@ def _dvr_router_lifecycle(self, enable_ha=False, enable_snat=False):
self._assert_snat_chains(router)
self._assert_floating_ip_chains(router)
self._assert_metadata_chains(router)
self._assert_extra_routes(router)

self._delete_router(self.agent, router.router_id)
self._assert_router_does_not_exist(router)
Expand Down
9 changes: 7 additions & 2 deletions neutron/tests/unit/test_l3_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ def router_append_interface(router, count=1, ip_version=4, ra_mode=None,


def prepare_router_data(ip_version=4, enable_snat=None, num_internal_ports=1,
enable_floating_ip=False, enable_ha=False):
enable_floating_ip=False, enable_ha=False,
extra_routes=False):
if ip_version == 4:
ip_addr = '19.4.4.4'
cidr = '19.4.4.0/24'
Expand All @@ -114,11 +115,15 @@ def prepare_router_data(ip_version=4, enable_snat=None, num_internal_ports=1,
'subnet': {'cidr': cidr,
'gateway_ip': gateway_ip}}

routes = []
if extra_routes:
routes = [{'destination': '8.8.8.0/24', 'nexthop': ip_addr}]

router = {
'id': router_id,
'distributed': False,
l3_constants.INTERFACE_KEY: [],
'routes': [],
'routes': routes,
'gw_port': ex_gw_port}

if enable_floating_ip:
Expand Down

0 comments on commit 7bbba6c

Please sign in to comment.