]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Check conntrack rule cleanup on floating IP disassociate
authorIhar Hrachyshka <ihrachys@redhat.com>
Tue, 11 Nov 2014 16:15:37 +0000 (17:15 +0100)
committerIhar Hrachyshka <ihrachys@redhat.com>
Fri, 6 Feb 2015 21:33:26 +0000 (22:33 +0100)
Check that conntrack rule is cleaned up immediately after floating IP is
disassociated.

Extend NetcatTester class to allow to specify different addresses for
client and server sides of connection. Fixed the class not to pass -k
option for UDP connections (otherwise the test fails when used with nmap
netcat implementation).

Change-Id: Iaa11e65a0bcf7860d4caa629c3107e5a0a48fd39

neutron/tests/functional/agent/linux/helpers.py
neutron/tests/functional/agent/linux/test_iptables.py
neutron/tests/functional/agent/test_l3_agent.py

index 8726448a8efddb53f9c73f7bb3d59092245ecc64..61a77fc5f806695fc1f2fff2dc39814703ea5ccb 100644 (file)
@@ -214,13 +214,18 @@ class RootHelperProcess(subprocess.Popen):
 class NetcatTester(object):
     TESTING_STRING = 'foo'
 
-    def __init__(self, client_namespace, server_namespace, address, port,
-                 root_helper='', udp=False):
+    def __init__(
+            self, client_namespace, server_namespace, server_address, port,
+            client_address=None, root_helper='', udp=False):
         self.client_namespace = client_namespace
         self.server_namespace = server_namespace
         self._client_process = None
         self._server_process = None
-        self.address = address
+        # Use client_address to specify an address to connect client to that is
+        # different from the one that server side is going to listen on (useful
+        # when testing floating IPs)
+        self.client_address = client_address or server_address
+        self.server_address = server_address
         self.port = str(port)
         self.root_helper = root_helper
         self.udp = udp
@@ -231,7 +236,8 @@ class NetcatTester(object):
             if not self._server_process:
                 self._spawn_server_process()
             self._client_process = self._spawn_nc_in_namespace(
-                self.client_namespace.namespace)
+                self.client_namespace.namespace,
+                address=self.client_address)
         return self._client_process
 
     @property
@@ -242,7 +248,9 @@ class NetcatTester(object):
 
     def _spawn_server_process(self):
         self._server_process = self._spawn_nc_in_namespace(
-            self.server_namespace.namespace, listen=True)
+            self.server_namespace.namespace,
+            address=self.server_address,
+            listen=True)
 
     def test_connectivity(self, respawn=False):
         stop_required = (respawn and self._client_process and
@@ -257,8 +265,8 @@ class NetcatTester(object):
 
         return message == self.TESTING_STRING
 
-    def _spawn_nc_in_namespace(self, namespace, listen=False):
-        cmd = ['nc', self.address, self.port]
+    def _spawn_nc_in_namespace(self, namespace, address, listen=False):
+        cmd = ['nc', address, self.port]
         if self.udp:
             cmd.append('-u')
         if listen:
index f22dcab1dc1740ef433639221cdefa82aab7fc93..8634fddc29ce903b797f9b468d170d01335f05b2 100644 (file)
@@ -70,7 +70,8 @@ class IptablesManagerTestCase(base.BaseIPVethTestCase):
     def _test_with_nc(self, fw_manager, direction, port, udp):
         netcat = helpers.NetcatTester(self.client_ns, self.server_ns,
                                       self.DST_ADDRESS, self.port,
-                                      self.root_helper, udp=udp)
+                                      root_helper=self.root_helper,
+                                      udp=udp)
         self.addCleanup(netcat.stop_processes)
         protocol = 'tcp'
         if udp:
index 5b45cd887e58cc6c11747b4917eb3cbd995a4800..b0e89956f7cc4e4520ab0e12cdc43a2dec75be71 100755 (executable)
@@ -19,6 +19,7 @@ import functools
 import mock
 import netaddr
 from oslo_config import cfg
+import testtools
 import webob
 import webob.dec
 import webob.exc
@@ -292,6 +293,52 @@ class L3AgentTestCase(L3AgentTestFramework):
     def test_ha_router_lifecycle(self):
         self._router_lifecycle(enable_ha=True)
 
+    def test_conntrack_disassociate_fip(self):
+        '''Test that conntrack immediately drops stateful connection
+           that uses floating IP once it's disassociated.
+        '''
+        router_info = self.generate_router_info(enable_ha=False)
+        router = self.manage_router(self.agent, router_info)
+
+        port = helpers.get_free_namespace_port(router.ns_name)
+        client_address = '19.4.4.3'
+        server_address = '35.4.0.4'
+
+        def clean_fips(router):
+            router.router[l3_constants.FLOATINGIP_KEY] = []
+
+        clean_fips(router)
+        self._add_fip(router, client_address, fixed_address=server_address)
+        self.agent.process_router(router)
+
+        router_ns = ip_lib.IPWrapper(self.root_helper,
+                                     namespace=router.ns_name)
+        netcat = helpers.NetcatTester(router_ns, router_ns,
+                                      server_address, port,
+                                      client_address=client_address,
+                                      root_helper=self.root_helper,
+                                      udp=False)
+        self.addCleanup(netcat.stop_processes)
+
+        def assert_num_of_conntrack_rules(n):
+            out = router_ns.netns.execute(["conntrack", "-L",
+                                           "--orig-src", client_address])
+            self.assertEqual(
+                n, len([line for line in out.strip().split('\n') if line]))
+
+        with self.assert_max_execution_time(15):
+            assert_num_of_conntrack_rules(0)
+
+            self.assertTrue(netcat.test_connectivity())
+            assert_num_of_conntrack_rules(1)
+
+            clean_fips(router)
+            self.agent.process_router(router)
+            assert_num_of_conntrack_rules(0)
+
+            with testtools.ExpectedException(RuntimeError):
+                netcat.test_connectivity()
+
     def test_keepalived_configuration(self):
         router_info = self.generate_router_info(enable_ha=True)
         router = self.manage_router(self.agent, router_info)