]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Add coverage for extra routes extension
authorAssaf Muller <amuller@redhat.com>
Mon, 26 Jan 2015 15:37:43 +0000 (10:37 -0500)
committerAssaf Muller <amuller@redhat.com>
Mon, 26 Jan 2015 21:40:49 +0000 (16:40 -0500)
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

neutron/agent/linux/ip_lib.py
neutron/tests/functional/agent/linux/test_ip_lib.py
neutron/tests/functional/agent/test_l3_agent.py
neutron/tests/unit/test_l3_agent.py

index dea22c466e95b1e6ea312f6ab5e312d32bba8f61..ccb1be89eeeba73211cd5dcfb32714db89b6cea0 100644 (file)
@@ -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)
index 43ca327b6444022abf96ea0496ee487d25f9fbc6..ed8580437bffc02c29b019690c787aa382fc572d 100644 (file)
@@ -15,6 +15,7 @@
 
 import collections
 
+import netaddr
 from oslo.config import cfg
 from oslo.utils import importutils
 
@@ -130,3 +131,21 @@ class IpLibTestCase(IpLibTestFramework):
                 *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)
index 7ce844a2131b8cc20bf471844468d0228f2c7df6..fb1affec9921a180e6db14681de54aa8f9b4faeb 100755 (executable)
@@ -98,7 +98,8 @@ class L3AgentTestFramework(base.BaseOVSLinuxTestCase):
     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'])
@@ -190,6 +191,7 @@ vrrp_instance VR_1 {
     }
     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,
@@ -247,6 +249,14 @@ vrrp_instance VR_1 {
             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):
@@ -309,8 +319,15 @@ class L3AgentTestCase(L3AgentTestFramework):
         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)
@@ -343,6 +360,7 @@ class L3AgentTestCase(L3AgentTestFramework):
         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)
@@ -546,6 +564,7 @@ class TestDvrRouter(L3AgentTestFramework):
         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)
index 7a1a067e8031e872336859378420e99cc75440be..bc28e5a8a146382e874843ae82b0b6342aed08af 100644 (file)
@@ -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'
@@ -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: