Integrated Xconnect into SR Sanity

Change-Id: Ib70361da9f3c5fcd13c4ec65cbc9eb425c8ba0ed
diff --git a/TestON/tests/USECASE/SegmentRouting/dependencies/0x1.json b/TestON/tests/USECASE/SegmentRouting/dependencies/0x1.json
index 8232036..867785a 100755
--- a/TestON/tests/USECASE/SegmentRouting/dependencies/0x1.json
+++ b/TestON/tests/USECASE/SegmentRouting/dependencies/0x1.json
@@ -41,6 +41,24 @@
                 "location": "of:0000000000000001/2"
             }
         }
+    },
+    "apps": {
+        "org.onosproject.segmentrouting": {
+          "xconnect": {
+            "of:0000000000000001": [
+              {
+                "vlan": 5,
+                "ports": [3, 4],
+                "name": "OLT 1"
+              },
+              {
+                "vlan": 10,
+                "ports": [3, 5],
+                "name": "OLT 2"
+              }
+            ]
+          }
+        }
     }
 
 }
diff --git a/TestON/tests/USECASE/SegmentRouting/dependencies/2x2.json b/TestON/tests/USECASE/SegmentRouting/dependencies/2x2.json
index a5ec00d..d4fa3fb 100755
--- a/TestON/tests/USECASE/SegmentRouting/dependencies/2x2.json
+++ b/TestON/tests/USECASE/SegmentRouting/dependencies/2x2.json
@@ -100,5 +100,23 @@
                 "location": "of:0000000000000002/4"
             }
         }
+    },
+    "apps": {
+        "org.onosproject.segmentrouting": {
+          "xconnect": {
+            "of:0000000000000001": [
+              {
+                "vlan": 5,
+                "ports": [5, 6],
+                "name": "OLT 1"
+              },
+              {
+                "vlan": 10,
+                "ports": [5, 7],
+                "name": "OLT 2"
+              }
+            ]
+          }
+        }
     }
 }
diff --git a/TestON/tests/USECASE/SegmentRouting/dependencies/4x4.json b/TestON/tests/USECASE/SegmentRouting/dependencies/4x4.json
index 7442359..55f3225 100755
--- a/TestON/tests/USECASE/SegmentRouting/dependencies/4x4.json
+++ b/TestON/tests/USECASE/SegmentRouting/dependencies/4x4.json
@@ -196,5 +196,23 @@
                 "location": "of:0000000000000004/6"
             }
         }
+    },
+    "apps": {
+        "org.onosproject.segmentrouting": {
+          "xconnect": {
+            "of:0000000000000001": [
+              {
+                "vlan": 5,
+                "ports": [7, 8],
+                "name": "OLT 1"
+              },
+              {
+                "vlan": 10,
+                "ports": [7, 9],
+                "name": "OLT 2"
+              }
+            ]
+          }
+        }
     }
 }
diff --git a/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py b/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
index 8565930..a195450 100755
--- a/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
+++ b/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
@@ -234,11 +234,21 @@
     @staticmethod

     def pingAll( main, tag="", dumpflows=True ):

         main.log.report( "Check full connectivity" )

-        main.step( "Check full connectivity %s" % tag )

-        pa = main.Mininet1.pingall( )

+        main.step("Check IP connectivity %s" %tag)

+        hosts = main.Mininet1.getHosts().keys()

+        vlan10 = [ '%s10' % s for s in [ 'olt', 'vsg' ] ]

+        vlan5 = [ '%s5' % s for s in [ 'olt', 'vsg' ] ]

+        IPHosts = [ host for host in hosts if host not in ( vlan10 + vlan5 ) ]

+        pa = main.Mininet1.pingallHosts(IPHosts)

         utilities.assert_equals( expect=main.TRUE, actual=pa,

-                                 onpass="Full connectivity successfully tested",

-                                 onfail="Full connectivity failed" )

+                                 onpass="IP connectivity successfully tested",

+                                 onfail="IP connectivity failed" )

+        main.step("Check VLAN  connectivity %s" %tag)

+        p1 = main.Mininet1.pingallHosts(vlan5)

+        p2 = main.Mininet1.pingallHosts(vlan10)

+        utilities.assert_equals( expect=main.TRUE, actual=p1&p2,

+                             onpass="Vlan connectivity successfully tested",

+                             onfail="Vlan connectivity failed" )

         if dumpflows:

             main.ONOSbench.dumpFlows( main.ONOSip[ main.active ],

                                       main.logdir, "flowsOn" + tag )

diff --git a/TestON/tests/USECASE/SegmentRouting/dependencies/cord_fabric.py b/TestON/tests/USECASE/SegmentRouting/dependencies/cord_fabric.py
index c890177..4f52689 100755
--- a/TestON/tests/USECASE/SegmentRouting/dependencies/cord_fabric.py
+++ b/TestON/tests/USECASE/SegmentRouting/dependencies/cord_fabric.py
@@ -5,7 +5,7 @@
 
 from mininet.net import Mininet
 from mininet.topo import Topo
-from mininet.node import RemoteController, UserSwitch, Host
+from mininet.node import RemoteController, UserSwitch, Host, OVSBridge
 from mininet.link import TCLink
 from mininet.log import setLogLevel
 from mininet.cli import CLI
@@ -23,7 +23,6 @@
                        help='number of hosts per leaf switch, default=2' )
     parser.add_option( '--onos', dest='onos', type='int', default=0,
                        help='number of ONOS Instances, default=0, 0 means localhost, 1 will use OC1 and so on' )
-
     (options, args) = parser.parse_args( )
     return options, args
 
@@ -34,32 +33,42 @@
 class LeafAndSpine( Topo ):
     def __init__( self, spine=2, leaf=2, fanout=2, **opts ):
         "Create Leaf and Spine Topo."
-
         Topo.__init__( self, **opts )
-
         # Add spine switches
         spines = { }
+        leafs = { }
         for s in range( spine ):
             spines[ s ] = self.addSwitch( 'spine10%s' % (s + 1),
                                           dpid="00000000010%s" % (s + 1) )
         # Set link speeds to 100Mb/s
         linkopts = dict( bw=100 )
-
         # Add Leaf switches
         for ls in range( leaf ):
-            leafSwitch = self.addSwitch( 'leaf%s' % (ls + 1),
-                                         dpid="00000000000%s" % (1 + ls) )
+            leafs[ ls ] = self.addSwitch( 'leaf%s' % (ls + 1),
+                                          dpid="00000000000%s" % (1 + ls) )
             # Connect leaf to all spines
             for s in range( spine ):
                 switch = spines[ s ]
-                self.addLink( leafSwitch, switch, **linkopts )
+                self.addLink( leafs[ ls ], switch, **linkopts )
             # Add hosts under a leaf, fanout hosts per leaf switch
             for f in range( fanout ):
                 host = self.addHost( 'h%s' % (ls * fanout + f + 1),
                                      cls=IpHost,
                                      ip='10.0.%s.%s/24' % ((ls + 1), (f + 1)),
                                      gateway='10.0.%s.254' % (ls + 1) )
-                self.addLink( host, leafSwitch, **linkopts )
+                self.addLink( host, leafs[ ls ], **linkopts )
+                # Add Xconnect simulation
+        br1 = self.addSwitch( 'br1', cls=OVSBridge )
+        self.addLink( br1, leafs[ 0 ], **linkopts )
+        for vid in [ 5, 10 ]:
+            olt = self.addHost( 'olt%s' % vid, cls=VLANHost, vlan=vid,
+                                ip="10.%s.0.1/24" % vid
+                                , mac="00:00:%02d:00:00:01" % vid )
+            vsg = self.addHost( 'vsg%s' % vid, cls=VLANHost, vlan=vid,
+                                ip="10.%s.0.2/24" % vid
+                                , mac="00:00:%02d:00:00:02" % vid )
+            self.addLink( olt, leafs[ 0 ], **linkopts )
+            self.addLink( vsg, br1, **linkopts )
 
 
 class IpHost( Host ):
@@ -74,6 +83,29 @@
         self.cmd( 'ip route add default via %s' % self.gateway )
 
 
+class VLANHost( Host ):
+    "Host connected to VLAN interface"
+
+    def config( self, vlan=100, **params ):
+        """Configure VLANHost according to (optional) parameters:
+           vlan: VLAN ID for default interface"""
+        r = super( VLANHost, self ).config( **params )
+        intf = self.defaultIntf( )
+        # remove IP from default, "physical" interface
+        self.cmd( 'ifconfig %s inet 0' % intf )
+        intf = self.defaultIntf( )
+        # create VLAN interface
+        self.cmd( 'vconfig add %s %d' % (intf, vlan) )
+        self.cmd( 'ifconfig %s.%d %s' % (intf, vlan, params[ 'ip' ]) )
+        # update the intf name and host's intf map
+        self.cmd( 'ifconfig %s.%d mtu 1480' % (intf, vlan) )
+        newName = '%s.%d' % (intf, vlan)
+        # update the (Mininet) interface to refer to VLAN interface name
+        intf.name = newName
+        # add VLAN interface to host's name to intf map
+        self.nameToIntf[ newName ] = intf
+
+
 def config( opts ):
     spine = opts.spine
     leaf = opts.leaf
@@ -83,9 +115,7 @@
         '127.0.0.1' ]
     topo = LeafAndSpine( spine=spine, leaf=leaf, fanout=fanout )
     net = Mininet( topo=topo, link=TCLink, build=False,
-                   switch=UserSwitch,
-                   controller=None,
-                   autoSetMacs=True )
+                   switch=UserSwitch, controller=None, autoSetMacs=True )
     i = 0
     for ip in controllers:
         net.addController( "c%s" % (i), controller=RemoteController, ip=ip )