Refactoring: Made complete codebase PEP8 compatible.
[osm/vim-emu.git] / src / emuvim / test / unittests / test_emulator.py
index e2c3b6b..fc06a69 100755 (executable)
@@ -1,20 +1,36 @@
-"""
-Test suite to automatically test emulator functionalities.
-Directly interacts with the emulator through the Mininet-like
-Python API.
-
-Does not test API endpoints. This is done in separated test suites.
-"""
-
-import time
+# Copyright (c) 2015 SONATA-NFV and Paderborn University
+# ALL RIGHTS RESERVED.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Neither the name of the SONATA-NFV, Paderborn University
+# nor the names of its contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# This work has been performed in the framework of the SONATA project,
+# funded by the European Commission under Grant number 671517 through
+# the Horizon 2020 and 5G-PPP programmes. The authors would like to
+# acknowledge the contributions of their colleagues of the SONATA
+# partner consortium (www.sonata-nfv.eu).
 import unittest
 from emuvim.dcemulator.node import EmulatorCompute
 from emuvim.test.base import SimpleTestTopology
 from mininet.node import RemoteController
 
 
 import unittest
 from emuvim.dcemulator.node import EmulatorCompute
 from emuvim.test.base import SimpleTestTopology
 from mininet.node import RemoteController
 
 
-#@unittest.skip("disabled topology tests for development")
-class testEmulatorTopology( SimpleTestTopology ):
+# @unittest.skip("disabled topology tests for development")
+class testEmulatorTopology(SimpleTestTopology):
     """
     Tests to check the topology API of the emulator.
     """
     """
     Tests to check the topology API of the emulator.
     """
@@ -41,7 +57,7 @@ class testEmulatorTopology( SimpleTestTopology ):
         # stop Mininet network
         self.stopNet()
 
         # stop Mininet network
         self.stopNet()
 
-    #@unittest.skip("disabled to test if CI fails because this is the first test.")
+    # @unittest.skip("disabled to test if CI fails because this is the first test.")
     def testMultipleDatacenterDirect(self):
         """
         Create a two data centers and interconnect them.
     def testMultipleDatacenterDirect(self):
         """
         Create a two data centers and interconnect them.
@@ -88,9 +104,64 @@ class testEmulatorTopology( SimpleTestTopology ):
         # stop Mininet network
         self.stopNet()
 
         # stop Mininet network
         self.stopNet()
 
-class testEmulatorNetworking( SimpleTestTopology ):
 
 
-    def testSDNChaining(self):
+class testEmulatorNetworking(SimpleTestTopology):
+
+    def testSDNChainingSingleService_withLearning(self):
+        """
+        Create a two data centers and interconnect them with additional
+        switches between them.
+        Uses Ryu SDN controller.
+        Connect the Docker hosts to different datacenters and setup the links between.
+        """
+        # create network
+        self.createNet(
+            nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
+            autolinkswitches=True,
+            controller=RemoteController,
+            enable_learning=True)
+        # setup links
+        self.net.addLink(self.dc[0], self.s[0])
+        self.net.addLink(self.s[2], self.dc[1])
+        # start Mininet network
+        self.startNet()
+
+        # add compute resources
+        vnf1 = self.dc[0].startCompute(
+            "vnf1", network=[{'id': 'intf1', 'ip': '10.0.10.1/24'}])
+        vnf2 = self.dc[1].startCompute(
+            "vnf2", network=[{'id': 'intf2', 'ip': '10.0.10.2/24'}])
+        # check number of running nodes
+        self.assertTrue(len(self.getContainernetContainers()) == 2)
+        self.assertTrue(len(self.net.hosts) == 2)
+        self.assertTrue(len(self.net.switches) == 5)
+        # check status
+        # check get status
+        s1 = self.dc[0].containers.get("vnf1").getStatus()
+        print s1
+        self.assertTrue(s1["name"] == "vnf1")
+        self.assertTrue(s1["state"]["Running"])
+        self.assertTrue(s1["network"][0]['intf_name'] == 'intf1')
+        self.assertTrue(s1["network"][0]['ip'] == '10.0.10.1/24')
+
+        s2 = self.dc[1].containers.get("vnf2").getStatus()
+        print s2
+        self.assertTrue(s2["name"] == "vnf2")
+        self.assertTrue(s2["state"]["Running"])
+        self.assertTrue(s2["network"][0]['intf_name'] == 'intf2')
+        self.assertTrue(s2["network"][0]['ip'] == '10.0.10.2/24')
+
+        # should be connected because learning = True
+        self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
+        # setup links
+        self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2',
+                          bidirectional=True, cmd='add-flow')
+        # should still be connected
+        self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
+        # stop Mininet network
+        self.stopNet()
+
+    def testSDNChainingSingleService(self):
         """
         Create a two data centers and interconnect them with additional
         switches between them.
         """
         Create a two data centers and interconnect them with additional
         switches between them.
@@ -110,35 +181,109 @@ class testEmulatorNetworking( SimpleTestTopology ):
         self.startNet()
 
         # add compute resources
         self.startNet()
 
         # add compute resources
-        vnf1 = self.dc[0].startCompute("vnf1", network=[{'id':'intf1', 'ip':'10.0.10.1/24'}])
-        vnf2 = self.dc[1].startCompute("vnf2", network=[{'id':'intf2', 'ip':'10.0.10.2/24'}])
+        vnf1 = self.dc[0].startCompute(
+            "vnf1", network=[{'id': 'intf1', 'ip': '10.0.10.1/24'}])
+        vnf2 = self.dc[1].startCompute(
+            "vnf2", network=[{'id': 'intf2', 'ip': '10.0.10.2/24'}])
         # check number of running nodes
         # check number of running nodes
-        self.assertTrue(len(self.getDockernetContainers()) == 2)
+        self.assertTrue(len(self.getContainernetContainers()) == 2)
         self.assertTrue(len(self.net.hosts) == 2)
         self.assertTrue(len(self.net.switches) == 5)
         # check status
         # check get status
         s1 = self.dc[0].containers.get("vnf1").getStatus()
         self.assertTrue(len(self.net.hosts) == 2)
         self.assertTrue(len(self.net.switches) == 5)
         # check status
         # check get status
         s1 = self.dc[0].containers.get("vnf1").getStatus()
+        print s1
         self.assertTrue(s1["name"] == "vnf1")
         self.assertTrue(s1["state"]["Running"])
         self.assertTrue(s1["network"][0]['intf_name'] == 'intf1')
         self.assertTrue(s1["name"] == "vnf1")
         self.assertTrue(s1["state"]["Running"])
         self.assertTrue(s1["network"][0]['intf_name'] == 'intf1')
-        self.assertTrue(s1["network"][0]['ip'] == '10.0.10.1')
+        self.assertTrue(s1["network"][0]['ip'] == '10.0.10.1/24')
 
         s2 = self.dc[1].containers.get("vnf2").getStatus()
 
         s2 = self.dc[1].containers.get("vnf2").getStatus()
+        print s2
         self.assertTrue(s2["name"] == "vnf2")
         self.assertTrue(s2["state"]["Running"])
         self.assertTrue(s2["network"][0]['intf_name'] == 'intf2')
         self.assertTrue(s2["name"] == "vnf2")
         self.assertTrue(s2["state"]["Running"])
         self.assertTrue(s2["network"][0]['intf_name'] == 'intf2')
-        self.assertTrue(s2["network"][0]['ip'] == '10.0.10.2')
+        self.assertTrue(s2["network"][0]['ip'] == '10.0.10.2/24')
 
 
+        # should be not not yet connected
+        self.assertTrue(self.net.ping([vnf1, vnf2]) > 0.0)
         # setup links
         # setup links
-        self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2', bidirectional=True, cmd='add-flow')
+        self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2',
+                          bidirectional=True, cmd='add-flow')
         # check connectivity by using ping
         self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
         # stop Mininet network
         self.stopNet()
 
         # check connectivity by using ping
         self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
         # stop Mininet network
         self.stopNet()
 
-#@unittest.skip("disabled compute tests for development")
-class testEmulatorCompute( SimpleTestTopology ):
+    def testSDNChainingMultiService(self):
+        """
+        Create a two data centers and interconnect them with additional
+        switches between them.
+        Uses Ryu SDN controller.
+        Setup 2 services and setup isolated paths between them
+        Delete only the first service, and check that other one still works
+        """
+        # create network
+        self.createNet(
+            nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
+            autolinkswitches=True,
+            controller=RemoteController,
+            enable_learning=False)
+        # setup links
+        self.net.addLink(self.dc[0], self.s[0])
+        self.net.addLink(self.s[2], self.dc[1])
+        # start Mininet network
+        self.startNet()
+
+        # First Service
+        # add compute resources
+        vnf1 = self.dc[0].startCompute(
+            "vnf1", network=[{'id': 'intf1', 'ip': '10.0.10.1/24'}])
+        vnf2 = self.dc[1].startCompute(
+            "vnf2", network=[{'id': 'intf2', 'ip': '10.0.10.2/24'}])
+        # setup links
+        self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2',
+                          bidirectional=True, cmd='add-flow', cookie=1)
+        # check connectivity by using ping
+        self.assertTrue(self.net.ping([vnf1, vnf2]) <= 0.0)
+
+        # Second Service
+        # add compute resources
+        vnf11 = self.dc[0].startCompute(
+            "vnf11", network=[{'id': 'intf1', 'ip': '10.0.20.1/24'}])
+        vnf22 = self.dc[1].startCompute(
+            "vnf22", network=[{'id': 'intf2', 'ip': '10.0.20.2/24'}])
+
+        # check number of running nodes
+        self.assertTrue(len(self.getContainernetContainers()) == 4)
+        self.assertTrue(len(self.net.hosts) == 4)
+        self.assertTrue(len(self.net.switches) == 5)
+
+        # setup links
+        self.net.setChain('vnf11', 'vnf22', 'intf1', 'intf2',
+                          bidirectional=True, cmd='add-flow', cookie=2)
+        # check connectivity by using ping
+        self.assertTrue(self.net.ping([vnf11, vnf22]) <= 0.0)
+        # check first service cannot ping second service
+        self.assertTrue(self.net.ping([vnf1, vnf22]) > 0.0)
+        self.assertTrue(self.net.ping([vnf2, vnf11]) > 0.0)
+
+        # delete the first service chain
+        self.net.setChain('vnf1', 'vnf2', 'intf1', 'intf2',
+                          bidirectional=True, cmd='del-flows', cookie=1)
+        # check connectivity of first service is down
+        self.assertTrue(self.net.ping([vnf1, vnf2]) > 0.0)
+        # time.sleep(100)
+        # check connectivity of second service is still up
+        self.assertTrue(self.net.ping([vnf11, vnf22]) <= 0.0)
+
+        # stop Mininet network
+        self.stopNet()
+
+# @unittest.skip("disabled compute tests for development")
+
+
+class testEmulatorCompute(SimpleTestTopology):
     """
     Tests to check the emulator's API to add and remove
     compute resources at runtime.
     """
     Tests to check the emulator's API to add and remove
     compute resources at runtime.
@@ -164,7 +309,8 @@ class testEmulatorCompute( SimpleTestTopology ):
         self.assertTrue(len(self.net.switches) == 1)
         # check compute list result
         self.assertTrue(len(self.dc[0].listCompute()) == 1)
         self.assertTrue(len(self.net.switches) == 1)
         # check compute list result
         self.assertTrue(len(self.dc[0].listCompute()) == 1)
-        self.assertTrue(isinstance(self.dc[0].listCompute()[0], EmulatorCompute))
+        self.assertTrue(isinstance(
+            self.dc[0].listCompute()[0], EmulatorCompute))
         self.assertTrue(self.dc[0].listCompute()[0].name == "vnf1")
         # check connectivity by using ping
         self.assertTrue(self.net.ping([self.h[0], vnf1]) <= 0.0)
         self.assertTrue(self.dc[0].listCompute()[0].name == "vnf1")
         # check connectivity by using ping
         self.assertTrue(self.net.ping([self.h[0], vnf1]) <= 0.0)
@@ -222,7 +368,8 @@ class testEmulatorCompute( SimpleTestTopology ):
         self.assertTrue(len(self.net.switches) == 1)
         # check compute list result
         self.assertTrue(len(self.dc[0].listCompute()) == 1)
         self.assertTrue(len(self.net.switches) == 1)
         # check compute list result
         self.assertTrue(len(self.dc[0].listCompute()) == 1)
-        self.assertTrue(isinstance(self.dc[0].listCompute()[0], EmulatorCompute))
+        self.assertTrue(isinstance(
+            self.dc[0].listCompute()[0], EmulatorCompute))
         self.assertTrue(self.dc[0].listCompute()[0].name == "vnf1")
         # check connectivity by using ping
         self.assertTrue(self.net.ping([self.h[0], vnf1]) <= 0.0)
         self.assertTrue(self.dc[0].listCompute()[0].name == "vnf1")
         # check connectivity by using ping
         self.assertTrue(self.net.ping([self.h[0], vnf1]) <= 0.0)
@@ -267,7 +414,7 @@ class testEmulatorCompute( SimpleTestTopology ):
         Test multiple, interleaved add and remove operations and ensure
         that always all expected compute instances are reachable.
         """
         Test multiple, interleaved add and remove operations and ensure
         that always all expected compute instances are reachable.
         """
-                # create network
+        # create network
         self.createNet(
             nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
             autolinkswitches=True)
         self.createNet(
             nswitches=3, ndatacenter=2, nhosts=0, ndockers=0,
             autolinkswitches=True)
@@ -315,5 +462,6 @@ class testEmulatorCompute( SimpleTestTopology ):
         # stop Mininet network
         self.stopNet()
 
         # stop Mininet network
         self.stopNet()
 
+
 if __name__ == '__main__':
     unittest.main()
 if __name__ == '__main__':
     unittest.main()