Pinging ng40 with a host for 2x2 SRBridging

Change-Id: Id31aab3c31f7f2981046ac5c3e45794f4886b6c4
diff --git a/TestON/tests/USECASE/SegmentRouting/SRBridging/SRBridging.py b/TestON/tests/USECASE/SegmentRouting/SRBridging/SRBridging.py
index 3586b0b..dfd9dc0 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRBridging/SRBridging.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRBridging/SRBridging.py
@@ -70,7 +70,7 @@
             main.funcs = SRBridgingTest()
         main.funcs.runTest( main,
                             test_idx=3,
-                            topology='2x2',
+                            topology='2x2 dual-linked',
                             onosNodes=1,
                             description="Bridging test between two untagged hosts on vlan-untagged port" )
 
@@ -193,6 +193,29 @@
                             topology='2x4',
                             onosNodes=3,
                             description="Bridging test between two untagged hosts on vlan-untagged port" )
+    def CASE9( self, main ):
+        """
+        Tests connectivity between two untagged hosts
+        (Ports are configured as vlan-untagged)
+
+        Sets up 3 ONOS instances
+        Start 2x2 leaf-spine topology
+        Pingall
+        """
+        try:
+            from tests.USECASE.SegmentRouting.SRBridging.dependencies.SRBridgingTest import SRBridgingTest
+        except ImportError:
+            main.log.error( "SRBridgingTest not found. Exiting the test" )
+            main.cleanAndExit()
+        try:
+            main.funcs
+        except ( NameError, AttributeError ):
+            main.funcs = SRBridgingTest()
+        main.funcs.runTest( main,
+                            test_idx=7,
+                            topology='2x2 dual-linked',
+                            onosNodes=3,
+                            description="Bridging test between two untagged hosts on vlan-untagged port" )
 
     def CASE11( self, main ):
         """
diff --git a/TestON/tests/USECASE/SegmentRouting/SRBridging/SRBridging.topo.2x2.physical b/TestON/tests/USECASE/SegmentRouting/SRBridging/SRBridging.topo.2x2.physical
index a236f9f..74b8689 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRBridging/SRBridging.topo.2x2.physical
+++ b/TestON/tests/USECASE/SegmentRouting/SRBridging/SRBridging.topo.2x2.physical
@@ -141,19 +141,19 @@
             <type>HostDriver</type>
             <connect_order>8</connect_order>
             <COMPONENTS>
-                <mac>52:54:00:e3:88:36</mac>
+                <mac>52:54:00:71:b5:96</mac>
                 <inband>false</inband>
-                <ip>192.168.101.101</ip>
+                <ip>192.168.102.101</ip>
                 <shortName>ng40</shortName>
                 <port1></port1>
                 <link1></link1>
-                <interfaceName>ens8</interfaceName>
+                <interfaceName>ens9</interfaceName>
                 <routes>
                     <route1>
                         <network>192.168.101.1</network>
                         <netmask>24</netmask>
                         <gw>192.168.103.1</gw>
-                        <interface>ens8</interface>
+                        <interface>ens9</interface>
                     </route1>
                 </routes>
             </COMPONENTS>
diff --git a/TestON/tests/USECASE/SegmentRouting/SRBridging/dependencies/SRBridgingTest.py b/TestON/tests/USECASE/SegmentRouting/SRBridging/dependencies/SRBridgingTest.py
index be98329..1ffa9c2 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRBridging/dependencies/SRBridgingTest.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRBridging/dependencies/SRBridgingTest.py
@@ -26,15 +26,9 @@
 
     def __init__( self ):
         self.default = ''
-        self.topo = dict()
-        # TODO: Check minFlowCount of leaf for BMv2 switch
-        # (number of spine switch, number of leaf switch, dual-homed, description, minFlowCount - leaf (OvS), minFlowCount - leaf (BMv2))
-        self.topo[ '0x1' ] = ( 0, 1, False, 'single ToR', 28, 20 )
-        self.topo[ '0x2' ] = ( 0, 2, True, 'dual-homed ToR', 37, 37 )
-        self.topo[ '2x2' ] = ( 2, 2, False, '2x2 leaf-spine topology', 37, 32 )
+        self.topo = run.getTopo()
         # TODO: Implement 2x3 topology
         # topo[ '2x3' ] = ( 2, 3, True, '2x3 leaf-spine topology with dual ToR and single ToR', 28 )
-        self.topo[ '2x4' ] = ( 2, 4, True, '2x4 dual-homed leaf-spine topology', 53, 53 )
         self.switchNames = {}
         self.switchNames[ '0x1' ] = [ "leaf1" ]
         self.switchNames[ '2x2' ] = [ "leaf1", "leaf2", "spine101", "spine102" ]
@@ -51,14 +45,14 @@
             if not init and onosNodes == main.Cluster.numCtrls:
                 skipPackage = True
 
-            main.case( '%s, with %s, %s switches and %d ONOS instance%s' %
-                       ( description, self.topo[ topology ][ 3 ], main.switchType, onosNodes, 's' if onosNodes > 1 else '' ) )
-            spines = self.topo[ topology ][ 0 ]
-            leaves = self.topo[ topology ][ 1 ]
+            main.case( '%s, with %s, %s switches and %d ONOS instance%s' %( description, self.topo[ topology ][ 'description' ], main.switchType, onosNodes, 's' if onosNodes > 1 else '' ) )
+            spines = self.topo[ topology ][ 'spines' ]
+            leaves = self.topo[ topology ][ 'leaves' ]
             switches = spines + leaves
             links = ( spines * leaves ) * 2
-            if self.topo[ topology ][ 2 ]:
+            if self.topo[ topology ][ 'dual-linked' ]:
                 links += links
+            if self.topo[ topology ][ 'dual-homed' ]:
                 links += ( leaves - 1 ) * 2
 
             main.cfgName = 'CASE%01d%01d' % ( test_idx / 10, ( ( test_idx - 1 ) % 10 ) % 4 + 1 )
@@ -84,8 +78,8 @@
                 run.mnDockerSetup( main )  # optionally create and setup docker image
 
                 # Run the test with Mininet
-                mininet_args = ' --spine=%d --leaf=%d' % ( self.topo[ topology ][ 0 ], self.topo[ topology ][ 1 ] )
-                if self.topo[ topology ][ 2 ]:
+                mininet_args = ' --spine=%d --leaf=%d' % ( self.topo[ topology ][ 'spines' ], self.topo[ topology ][ 'leaves' ] )
+                if self.topo[ topology ][ 'dual-homed' ]:
                     mininet_args += ' --dual-homed'
                 if len( vlan ) > 0 :
                     mininet_args += ' --vlan=%s' % ( ','.join( ['%d' % vlanId for vlanId in vlan ] ) )
@@ -99,18 +93,18 @@
                 # Run the test with physical devices
                 run.connectToPhysicalNetwork( main, hostDiscovery=False )  # We don't want to do host discovery in the pod
 
-            run.checkFlows( main, minFlowCount=self.topo[ topology ][ 5 if main.useBmv2 else 4 ] * self.topo[ topology ][ 1 ], sleep=5 )
+            run.checkFlows( main, minFlowCount=self.topo[ topology ][ 'minFlow-Stratum' if main.useBmv2 else 'minFlow-OvS' ] * self.topo[ topology ][ 'leaves' ], sleep=5 )
             if main.useBmv2:
                 switchPrefix = main.params[ 'DEPENDENCY' ].get( 'switchPrefix', '' )
                 if switchPrefix is None or "None":
                     switchPrefix = ''
                 if switchPrefix is not '' and switchPrefix is not None:
                     switchPrefix += ':'
-                leaf_dpid = [ "device:%sleaf%d" % ( switchPrefix, ls + 1 ) for ls in range( self.topo[ topology ][ 1 ]) ]
+                leaf_dpid = [ "device:%sleaf%d" % ( switchPrefix, ls + 1 ) for ls in range( self.topo[ topology ][ 'leaves' ]) ]
             else:
-                leaf_dpid = [ "of:%016d" % ( ls + 1 ) for ls in range( self.topo[ topology ][ 1 ] ) ]
+                leaf_dpid = [ "of:%016d" % ( ls + 1 ) for ls in range( self.topo[ topology ][ 'leaves' ] ) ]
             for dpid in leaf_dpid:
-                run.checkFlowsByDpid( main, dpid, self.topo[ topology ][ 5 if main.useBmv2 else 4 ], sleep=5 )
+                run.checkFlowsByDpid( main, dpid, self.topo[ topology ][ 'minFlow-Stratum' if main.useBmv2 else 'minFlow-OvS' ], sleep=5 )
             run.verifyTopology( main, switches, links, onosNodes )
             run.pingAll( main )
         except Exception as e:
diff --git a/TestON/tests/USECASE/SegmentRouting/SRBridging/dependencies/chart/CASE03.chart b/TestON/tests/USECASE/SegmentRouting/SRBridging/dependencies/chart/CASE03.chart
index 0102621..38f0a1b 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRBridging/dependencies/chart/CASE03.chart
+++ b/TestON/tests/USECASE/SegmentRouting/SRBridging/dependencies/chart/CASE03.chart
@@ -3,4 +3,4 @@
     "hosts":["h1", "h2"]},
   "leaf2": {"expect": "True",
     "hosts":["h3", "h4"]}
-}
\ No newline at end of file
+}
diff --git a/TestON/tests/USECASE/SegmentRouting/SRBridging/dependencies/chart/CASE09.chart b/TestON/tests/USECASE/SegmentRouting/SRBridging/dependencies/chart/CASE09.chart
new file mode 100644
index 0000000..f52bad8
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/SRBridging/dependencies/chart/CASE09.chart
@@ -0,0 +1,4 @@
+{
+  "leaf1": {"expect": "True",
+    "hosts":["h1", "ng40"]}
+}
diff --git a/TestON/tests/USECASE/SegmentRouting/SRClusterRestart/dependencies/SRClusterRestartFuncs.py b/TestON/tests/USECASE/SegmentRouting/SRClusterRestart/dependencies/SRClusterRestartFuncs.py
index af86ca8..be727a3 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRClusterRestart/dependencies/SRClusterRestartFuncs.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRClusterRestart/dependencies/SRClusterRestartFuncs.py
@@ -25,26 +25,23 @@
 
     def __init__( self ):
         self.default = ''
-        self.topo = dict()
-        self.topo[ '0x1' ] = ( 0, 1, '--leaf=1 --spine=0', 'single switch' )
-        self.topo[ '2x2' ] = ( 2, 2, '', '2x2 Leaf-spine' )
-        self.topo[ '4x4' ] = ( 4, 4, '--leaf=4 --spine=4', '4x4 Leaf-spine' )
+        self.topo = run.getTopo()
 
-    def runTest( self, main, caseNum, numNodes, Topo, minFlow, testing, killList=[ 0, 1, 2 ] ):
+    def runTest( self, main, caseNum, numNodes, topology, minFlow, testing, killList=[ 0, 1, 2 ] ):
         try:
-            description = "Cluster Restart test with " + self.topo[ Topo ][ 3 ]
+            description = "Cluster Restart test with " + self.topo[ topology ][ 'description' ]
             caseTitle = 'CASE{}_'.format( caseNum ) + testing
             main.case( description )
             if not hasattr( main, 'apps' ):
                 run.initTest( main )
-            main.cfgName = Topo
+            main.cfgName = topology
             main.Cluster.setRunningNode( numNodes )
             run.installOnos( main )
             if not main.persistentSetup:
                 run.loadJson( main )
             run.loadChart( main )
             if hasattr( main, 'Mininet1' ):
-                run.startMininet( main, 'cord_fabric.py', args=self.topo[ Topo ][ 2 ] )
+                run.startMininet( main, 'cord_fabric.py', args=self.topo[ topology ][ 'mininetArgs' ] )
             else:
                 # Run the test with physical devices
                 # TODO: connect TestON to the physical network
@@ -54,8 +51,8 @@
             # pre-configured routing and bridging test
             run.checkFlows( main, minFlowCount=minFlow )
             run.pingAll( main )
-            switch = '{}'.format( self.topo[ Topo ][ 0 ] + self.topo[ Topo ][ 1 ] )
-            link = '{}'.format( ( self.topo[ Topo ][ 0 ] + self.topo[ Topo ][ 1 ] ) * self.topo[ Topo ][ 0 ] )
+            switch = '{}'.format( self.topo[ topology ][ 'spines' ] + self.topo[ topology ][ 'leaves' ] )
+            link = '{}'.format( ( self.topo[ topology ][ 'spines' ] + self.topo[ topology ][ 'leaves' ] ) * self.topo[ topology ][ 'spines' ] )
             run.killOnos( main, killList, switch, link, '0' )
             run.pingAll( main, caseTitle, dumpflows=False )
             run.recoverOnos( main, killList, switch, link, '{}'.format( numNodes ) )
diff --git a/TestON/tests/USECASE/SegmentRouting/SRDhcprelay/dependencies/SRDhcprelayTest.py b/TestON/tests/USECASE/SegmentRouting/SRDhcprelay/dependencies/SRDhcprelayTest.py
index 325af80..d5230a0 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRDhcprelay/dependencies/SRDhcprelayTest.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRDhcprelay/dependencies/SRDhcprelayTest.py
@@ -26,6 +26,7 @@
 
     def __init__( self ):
         self.default = ''
+        self.topo = run.getTopo()
 
     @staticmethod
     def runTest( main, testIndex, onosNodes, description, dhcpRelay=False, remoteServer=False, multipleServer=False, ipv6=False, vlan=[], dualHomed=False ):
diff --git a/TestON/tests/USECASE/SegmentRouting/SRDynamic/dependencies/SRDynamicFuncs.py b/TestON/tests/USECASE/SegmentRouting/SRDynamic/dependencies/SRDynamicFuncs.py
index 1e2d0a3..7c83f80 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRDynamic/dependencies/SRDynamicFuncs.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRDynamic/dependencies/SRDynamicFuncs.py
@@ -28,30 +28,27 @@
 
     def __init__( self ):
         self.default = ''
-        self.topo = dict()
-        self.topo[ '0x1' ] = ( 0, 1, '--leaf=1 --spine=0', 'single switch' )
-        self.topo[ '2x2' ] = ( 2, 2, '', '2x2 Leaf-spine' )
-        self.topo[ '4x4' ] = ( 4, 4, '--leaf=4 --spine=4', '4x4 Leaf-spine' )
+        self.topo = run.getTopo()
 
-    def runTest( self, main, caseNum, numNodes, Topo, minBeforeFlow, minAfterFlow, killOnosAndDeleteCfg ):
+    def runTest( self, main, caseNum, numNodes, topology, minBeforeFlow, minAfterFlow, killOnosAndDeleteCfg ):
         try:
             if not hasattr( main, 'apps' ):
                 run.initTest( main )
 
             description = "Bridging and Routing sanity test with " + \
-                          self.topo[ Topo ][ 3 ] + \
+                          self.topo[ topology ][ 'description' ] + \
                           "and {} nodes.".format( numNodes ) + \
                           ( "\nAlso, killing the first Onos and removing the host cfg." if killOnosAndDeleteCfg else "" )
             main.case( description )
 
-            main.cfgName = Topo
+            main.cfgName = topology
             main.Cluster.setRunningNode( numNodes )
             run.installOnos( main )
             if not main.persistentSetup:
                 run.loadJson( main )
             run.loadChart( main )
             run.startMininet( main, 'cord_fabric.py',
-                              args=self.topo[ Topo ][ 2 ] )
+                              args=self.topo[ topology ][ 'mininetArgs' ] )
             # pre-configured routing and bridging test
             run.checkFlows( main, minFlowCount=minBeforeFlow )
             run.pingAll( main, dumpflows=False )
@@ -59,8 +56,8 @@
             run.checkFlows( main, minFlowCount=minAfterFlow, dumpflows=False )
             run.pingAll( main )
             if killOnosAndDeleteCfg:
-                switch = self.topo[ Topo ][ 0 ] + self.topo[ Topo ][ 1 ]
-                link = ( self.topo[ Topo ][ 0 ] + self.topo[ Topo ][ 1 ] ) * self.topo[ Topo ][ 0 ]
+                switch = self.topo[ topology ][ 'spines' ] + self.topo[ topology ][ 'leaves' ]
+                link = ( self.topo[ topology ][ 'spines' ] + self.topo[ topology ][ 'leaves' ] ) * self.topo[ topology ][ 'spines' ]
                 self.killAndDelete( main, caseNum, numNodes, minBeforeFlow, switch, link )
             # TODO Dynamic config of hosts in subnet
             # TODO Dynamic config of host not in subnet
diff --git a/TestON/tests/USECASE/SegmentRouting/SRDynamicConf/dependencies/SRDynamicConfTest.py b/TestON/tests/USECASE/SegmentRouting/SRDynamicConf/dependencies/SRDynamicConfTest.py
index fb44e2e..70b4e6b 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRDynamicConf/dependencies/SRDynamicConfTest.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRDynamicConf/dependencies/SRDynamicConfTest.py
@@ -24,6 +24,7 @@
 class SRDynamicConfTest:
     def __init__( self ):
         self.default = ''
+        self.topo = run.getTopo()
 
     @staticmethod
     def runTest( main, testIndex, topology, onosNodes, description, vlan=( 0, 0, 0, 0 ) ):
@@ -39,12 +40,6 @@
                         Only used when ping chart is updated.
         '''
         try:
-            topo = dict()
-            # (number of spine switch, number of leaf switch, dual-homed, description, port number of h1)
-            topo[ '0x1' ] = ( 0, 1, False, 'single ToR', 1 )
-            topo[ '0x2' ] = ( 0, 2, True, 'dual-homed ToR', 2 )
-            topo[ '2x2' ] = ( 2, 2, False, '2x2 leaf-spine topology', 3 )
-            topo[ '2x4' ] = ( 2, 4, True, '2x4 dual-homed leaf-spine topology', 6 )
             fanout = 4
             switchNames = {}
             switchNames[ '2x2' ] = [ "leaf1", "leaf2", "spine101", "spine102" ]
@@ -52,8 +47,8 @@
             TAG = 'CASE%d' % testIndex
             skipPackage = False
             init = False
-            dualHomed = topo[ topology ][ 2 ]
-            portNum = topo[ topology ][ 4 ]
+            dualHomed = self.topo[ topology ][ 'dual-homed' ]
+            portNum = self.topo[ topology ][ 'description' ]
             defaultIntf = 'bond0' if dualHomed else 'eth0'
 
             from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as run
@@ -65,7 +60,7 @@
                 skipPackage = True
 
             main.case( '%s, with %s and %d ONOS instance%s' %
-                       ( description, topo[ topology ][ 3 ], onosNodes, 's' if onosNodes > 1 else '' ) )
+                       ( description, self.topo[ topology ][ 'description' ], onosNodes, 's' if onosNodes > 1 else '' ) )
             main.cfgName = topology
             main.Cluster.setRunningNode( onosNodes )
             run.installOnos( main, skipPackage=skipPackage, cliSleep=5 )
@@ -124,10 +119,10 @@
                 run.mnDockerSetup( main )
                 # Run the test with mininet topology
                 mininet_args = ' --spine=%d --leaf=%d --fanout=%d' \
-                               % ( topo[ topology ][ 0 ], topo[ topology ][ 1 ], fanout )
+                               % ( self.topo[ topology ][ 'spines' ], self.topo[ topology ][ 'leaves' ], fanout )
                 if len( vlan ) > 0 :
                     mininet_args += ' --vlan=%s' % ( ','.join( [ '%d' % vlanId for vlanId in vlan ] ) )
-                    if topo[ topology ][ 0 ] > 0:
+                    if self.topo[ topology ][ 'spines' ] > 0:
                         mininet_args += ',0,0,0,0'
                 if dualHomed:
                     mininet_args += ' --dual-homed'
@@ -141,15 +136,15 @@
                 run.connectToPhysicalNetwork( main, switchNames[ topology ] )
 
             # minFlowCountPerLeaf = 13 +  [# of ports] * 5 + [# of hosts] * 2 + [# of vlan ids]
-            minFlowCountPerLeaf = 13 + ( fanout + topo[ topology ][ 0 ]) * 5 + fanout * 2 + len( set( vlan ) )
-            run.checkFlows( main, minFlowCount=minFlowCountPerLeaf * topo[ topology ][ 1 ], sleep=5, dumpflows=False )
+            minFlowCountPerLeaf = 13 + ( fanout + self.topo[ topology ][ 'spines' ]) * 5 + fanout * 2 + len( set( vlan ) )
+            run.checkFlows( main, minFlowCount=minFlowCountPerLeaf * self.topo[ topology ][ 'leaves' ], sleep=5, dumpflows=False )
             # Check connectivity before changing interface configuration
             run.pingAll( main, '%s_Before' % TAG, retryAttempts=2 )
 
             if main.useBmv2:
-                leaf_dpid = [ "device:bmv2:leaf%d" % ( ls + 1 ) for ls in range( topo[ topology ][ 1 ] ) ]
+                leaf_dpid = [ "device:bmv2:leaf%d" % ( ls + 1 ) for ls in range( self.topo[ topology ][ 'leaves' ] ) ]
             else:
-                leaf_dpid = [ "of:%016d" % ( ls + 1 ) for ls in range( topo[ topology ][ 1 ] ) ]
+                leaf_dpid = [ "of:%016d" % ( ls + 1 ) for ls in range( self.topo[ topology ][ 'leaves' ] ) ]
             for dpid in leaf_dpid:
                 run.checkFlowsByDpid( main, dpid, minFlowCountPerLeaf, sleep=5 )
 
@@ -375,7 +370,7 @@
                 main.log.debug( "Ping chart is not changed" )
 
             # Check connectivity after changing interface configuration
-            run.checkFlows( main, minFlowCount=minFlowCountPerLeaf * topo[ topology ][ 1 ], sleep=5, dumpflows=False )
+            run.checkFlows( main, minFlowCount=minFlowCountPerLeaf * self.topo[ topology ][ 'leaves' ], sleep=5, dumpflows=False )
             run.pingAll( main, '%s_After' % TAG, retryAttempts=2 )
 
         except Exception as e:
diff --git a/TestON/tests/USECASE/SegmentRouting/SRHighAvailability/dependencies/SRHAFuncs.py b/TestON/tests/USECASE/SegmentRouting/SRHighAvailability/dependencies/SRHAFuncs.py
index 5f71d28..5828d93 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRHighAvailability/dependencies/SRHAFuncs.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRHighAvailability/dependencies/SRHAFuncs.py
@@ -29,33 +29,31 @@
 
     def __init__( self ):
         self.default = ''
-        self.topo = dict()
-        self.topo[ '2x2' ] = ( 2, 2, '', '2x2 Leaf-spine' )
-        self.topo[ '4x4' ] = ( 4, 4, '--leaf=4 --spine=4', '4x4 Leaf-spine' )
+        self.topo = run.getTopo()
 
-    def runTest( self, main, caseNum, numNodes, Topo, minFlow, isRandom, isKillingSwitch ):
+    def runTest( self, main, caseNum, numNodes, topology, minFlow, isRandom, isKillingSwitch ):
         try:
             if not hasattr( main, 'apps' ):
                 run.initTest( main )
 
             description = "High Availability tests - " + \
                           self.generateDescription( isRandom, isKillingSwitch ) + \
-                          self.topo[ Topo ][ 3 ]
+                          self.topo[ topology ][ 'description' ]
             main.case( description )
-            run.config( main, Topo )
+            run.config( main, topology )
             run.installOnos( main )
             if not main.persistentSetup:
                 run.loadJson( main )
             run.loadChart( main )
-            run.startMininet( main, 'cord_fabric.py', args=self.topo[ Topo ][ 2 ] )
+            run.startMininet( main, 'cord_fabric.py', args=self.topo[ topology ][ 'mininetArgs' ] )
             if not main.persistentSetup:
                 # xconnects need to be loaded after topology
                 run.loadXconnects( main )
             # pre-configured routing and bridging test
             run.checkFlows( main, minFlowCount=minFlow )
             run.pingAll( main )
-            switch = self.topo[ Topo ][ 0 ] + self.topo[ Topo ][ 1 ]
-            link = ( self.topo[ Topo ][ 0 ] + self.topo[ Topo ][ 1 ] ) * self.topo[ Topo ][ 0 ]
+            switch = self.topo[ topology ][ 'spines' ] + self.topo[ topology ][ 'leaves' ]
+            link = ( self.topo[ topology ][ 'spines' ] + self.topo[ topology ][ 'leaves' ] ) * self.topo[ topology ][ 'spines' ]
             self.generateRandom( isRandom )
             for i in range( 0, main.failures ):
                 toKill = self.getNextNum( isRandom, main.Cluster.numCtrls, i )
@@ -64,7 +62,7 @@
                 run.pingAll( main, 'CASE{}_ONOS_Failure{}'.format( caseNum, i + 1 ) )
                 if isKillingSwitch:
                     self.killAndRecoverSwitch( main, caseNum, numNodes,
-                                               Topo, minFlow, isRandom,
+                                               topology, minFlow, isRandom,
                                                i, switch, link )
                 run.recoverOnos( main, [ toKill ], '{}'.format( switch ),
                                  '{}'.format( link ), '{}'.format( numNodes ) )
@@ -94,8 +92,8 @@
     def getNextNum( self, isRandom, numCtrl, pos ):
         return randint( 0, ( numCtrl - 1 ) ) if isRandom else pos % numCtrl
 
-    def killAndRecoverSwitch( self, main, caseNum, numNodes, Topo, minFlow, isRandom, pos, numSwitch, numLink ):
-        switchToKill = self.getNextNum( isRandom, self.topo[ Topo ][ 0 ], pos )
+    def killAndRecoverSwitch( self, main, caseNum, numNodes, topology, minFlow, isRandom, pos, numSwitch, numLink ):
+        switchToKill = self.getNextNum( isRandom, self.topo[ topology ][ 'spines' ], pos )
         run.killSwitch( main, main.spines[ switchToKill ][ 'name' ],
                         switches='{}'.format( numSwitch - 1 ),
                         links='{}'.format( numLink - numSwitch ) )
diff --git a/TestON/tests/USECASE/SegmentRouting/SRLinkFailure/dependencies/SRLinkFailFuncs.py b/TestON/tests/USECASE/SegmentRouting/SRLinkFailure/dependencies/SRLinkFailFuncs.py
index ea55f04..d6a9ba5 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRLinkFailure/dependencies/SRLinkFailFuncs.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRLinkFailure/dependencies/SRLinkFailFuncs.py
@@ -26,10 +26,7 @@
 
     def __init__( self ):
         self.default = ''
-        self.topo = dict()
-        self.topo[ '0x1' ] = ( 0, 1, '--leaf=1 --spine=0', 'single switch' )
-        self.topo[ '2x2' ] = ( 2, 2, '', '2x2 Leaf-spine' )
-        self.topo[ '4x4' ] = ( 4, 4, '--leaf=4 --spine=4', '4x4 Leaf-spine' )
+        self.topo = run.getTopo()
         main.switchType = "ovs"
         self.switchOne = 'spine101'
         self.switchTwo = 'leaf2'
@@ -38,13 +35,13 @@
         self.portOne = '2'
         self.portTwo = '3'
 
-    def runTest( self, main, caseNum, numNodes, Topo, minFlow ):
+    def runTest( self, main, caseNum, numNodes, topology, minFlow ):
         try:
-            description = "Bridging and Routing Link Failure test with " + self.topo[ Topo ][ 3 ] + " and {} Onos".format( numNodes )
+            description = "Bridging and Routing Link Failure test with " + self.topo[ topology ][ 'description' ] + " and {} Onos".format( numNodes )
             main.case( description )
             if not hasattr( main, 'apps' ):
                 run.initTest( main )
-            main.cfgName = Topo
+            main.cfgName = topology
             main.Cluster.setRunningNode( numNodes )
             run.installOnos( main )
             suf = main.params.get( 'jsonFileSuffix', '')
@@ -71,7 +68,7 @@
                 run.mnDockerSetup( main )  # optionally create and setup docker image
 
                 # Run the test with Mininet
-                mininet_args = self.topo[ Topo ][ 2 ]
+                mininet_args = self.topo[ topology ][ 'mininetArgs' ]
                 if main.useBmv2:
                     mininet_args += ' --switch %s' % main.switchType
                     main.log.info( "Using %s switch" % main.switchType )
@@ -83,8 +80,8 @@
                 pass
             # xconnects need to be loaded after topology
             run.loadXconnects( main )
-            switches = self.topo[ Topo ][ 0 ] + self.topo[ Topo ][ 1 ]
-            links = ( self.topo[ Topo ][ 0 ] * self.topo[ Topo ][ 1 ] ) * 2
+            switches = self.topo[ topology ][ 'spines' ] + self.topo[ topology ][ 'leaves' ]
+            links = ( self.topo[ topology ][ 'spines' ] * self.topo[ topology ][ 'leaves' ] ) * 2
             # pre-configured routing and bridging test
             run.verifyTopology( main, switches, links, numNodes )
             run.checkFlows( main, minFlowCount=minFlow )
diff --git a/TestON/tests/USECASE/SegmentRouting/SROnosFailure/dependencies/SROnosFailureFuncs.py b/TestON/tests/USECASE/SegmentRouting/SROnosFailure/dependencies/SROnosFailureFuncs.py
index f374c47..9da11a5 100644
--- a/TestON/tests/USECASE/SegmentRouting/SROnosFailure/dependencies/SROnosFailureFuncs.py
+++ b/TestON/tests/USECASE/SegmentRouting/SROnosFailure/dependencies/SROnosFailureFuncs.py
@@ -26,19 +26,16 @@
 
     def __init__( self ):
         self.default = ''
-        self.topo = dict()
-        self.topo[ '0x1' ] = ( 0, 1, '--leaf=1 --spine=0', 'single switch' )
-        self.topo[ '2x2' ] = ( 2, 2, '', '2x2 Leaf-spine' )
-        self.topo[ '4x4' ] = ( 4, 4, '--leaf=4 --spine=4', '4x4 Leaf-spine' )
+        self.topo = run.getTopo()
         main.switchType = "ovs"
 
-    def runTest( self, main, caseNum, numNodes, Topo, minFlow, killList=[ 0 ] ):
+    def runTest( self, main, caseNum, numNodes, topology, minFlow, killList=[ 0 ] ):
         try:
-            description = "ONOS Failure test with " + self.topo[ Topo ][ 3 ]
+            description = "ONOS Failure test with " + self.topo[ topology ][ 'description' ]
             main.case( description )
             if not hasattr( main, 'apps' ):
                 run.initTest( main )
-            main.cfgName = Topo
+            main.cfgName = topology
             main.Cluster.setRunningNode( numNodes )
             run.installOnos( main )
             suf = main.params.get( 'jsonFileSuffix', '')
@@ -65,7 +62,7 @@
                 run.mnDockerSetup( main )  # optionally create and setup docker image
 
                 # Run the test with Mininet
-                mininet_args = self.topo[ Topo ][ 2 ]
+                mininet_args = self.topo[ topology ][ 'mininetArgs' ]
                 if main.useBmv2:
                     mininet_args += ' --switch %s' % main.switchType
                     main.log.info( "Using %s switch" % main.switchType )
@@ -78,8 +75,8 @@
             if not main.persistentSetup:
                 # xconnects need to be loaded after topology
                 run.loadXconnects( main )
-            switches = self.topo[ Topo ][ 0 ] + self.topo[ Topo ][ 1 ]
-            links = ( self.topo[ Topo ][ 0 ] * self.topo[ Topo ][ 1 ] ) * 2
+            switches = self.topo[ topology ][ 'spines' ] + self.topo[ topology ][ 'leaves' ]
+            links = ( self.topo[ topology ][ 'spines' ] * self.topo[ topology ][ 'leaves' ] ) * 2
             # pre-configured routing and bridging test
             run.verifyTopology( main, switches, links, numNodes )
             run.checkFlows( main, minFlowCount=minFlow )
diff --git a/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.topo b/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.topo
index ec400c8..12bde17 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.topo
+++ b/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.topo
@@ -10,8 +10,12 @@
             <COMPONENTS>
                 <cluster_name></cluster_name>  # Used as a prefix for cluster components. Defaults to 'ONOS'
                 <diff_clihost></diff_clihost> # if it has different host other than localhost for CLI. True or empty. OC# will be used if True.
-                <karaf_username></karaf_username>
-                <karaf_password></karaf_password>
+                <karaf_username>sdn</karaf_username>
+                <karaf_password>rocks</karaf_password>
+                <node_username>sdn</node_username>
+                <node_password>rocks</node_password>
+                <karafPrompt_username>sdn</karafPrompt_username>
+                <karafPrompt_password>rocks</karafPrompt_password>
                 <web_user></web_user>
                 <web_pass></web_pass>
                 <rest_port></rest_port>
diff --git a/TestON/tests/USECASE/SegmentRouting/SRSanity/dependencies/SRSanityFuncs.py b/TestON/tests/USECASE/SegmentRouting/SRSanity/dependencies/SRSanityFuncs.py
index f079be4..e596a79 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRSanity/dependencies/SRSanityFuncs.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRSanity/dependencies/SRSanityFuncs.py
@@ -25,26 +25,23 @@
 
     def __init__( self ):
         self.default = ''
-        self.topo = dict()
-        self.topo[ '0x1' ] = ( 0, 1, '--leaf=1 --spine=0', 'single switch' )
-        self.topo[ '2x2' ] = ( 2, 2, '', '2x2 Leaf-spine' )
-        self.topo[ '4x4' ] = ( 4, 4, '--leaf=4 --spine=4', '4x4 Leaf-spine' )
+        self.topo = run.getTopo()
 
-    def runTest( self, main, caseNum, numNodes, Topo, minFlow ):
+    def runTest( self, main, caseNum, numNodes, topology, minFlow ):
         try:
             if not hasattr( main, 'apps' ):
                 run.initTest( main )
 
-            description = "Bridging and Routing sanity test with " + self.topo[ Topo ][ 3 ] + " and {} Onos".format( numNodes )
+            description = "Bridging and Routing sanity test with " + self.topo[ topology ][ 'description' ] + " and {} Onos".format( numNodes )
             main.case( description )
 
-            main.cfgName = Topo
+            main.cfgName = topology
             main.Cluster.setRunningNode( numNodes )
             run.installOnos( main )
             if not main.persistentSetup:
                 run.loadJson( main )
             run.loadChart( main )
-            run.startMininet( main, 'cord_fabric.py', args=self.topo[ Topo ][ 2 ] )
+            run.startMininet( main, 'cord_fabric.py', args=self.topo[ topology ][ 'mininetArgs' ] )
             if not main.persistentSetup:
                 # xconnects need to be loaded after topology
                 run.loadXconnects( main )
diff --git a/TestON/tests/USECASE/SegmentRouting/SRStaging/dependencies/SRStagingTest.py b/TestON/tests/USECASE/SegmentRouting/SRStaging/dependencies/SRStagingTest.py
index 2593912..bdfaa49 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRStaging/dependencies/SRStagingTest.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRStaging/dependencies/SRStagingTest.py
@@ -30,17 +30,9 @@
 
     def __init__( self ):
         self.default = ''
-        self.topo = dict()
+        self.topo = run.getTopo()
         # TODO: Check minFlowCount of leaf for BMv2 switch
         # (number of spine switch, number of leaf switch, dual-homed, description, minFlowCount - leaf (OvS), minFlowCount - leaf (BMv2))
-        self.topo[ '0x1' ] = ( 0, 1, False, 'single ToR', 28, 20 )
-        self.topo[ '0x2' ] = ( 0, 2, True, 'dual-homed ToR', 37, 37 )
-        self.topo[ '2x2' ] = ( 2, 2, False, '2x2 leaf-spine topology', 37, 32 )
-        self.topo[ '2x2staging' ] = ( 2, 2, True, '2x2 leaf-spine topology', 37, 32 )
-        # TODO: Implement 2x3 topology
-        # topo[ '2x3' ] = ( 2, 3, True, '2x3 leaf-spine topology with dual ToR and single ToR', 28 )
-        self.topo[ '2x4' ] = ( 2, 4, True, '2x4 dual-homed leaf-spine topology', 53, 53 )
-        self.topo[ '2x4' ] = ( 2, 4, True, '2x4 dual-homed leaf-spine topology', 53, 53 )
         self.switchNames = {}
         self.switchNames[ '0x1' ] = [ "leaf1" ]
         self.switchNames[ '2x2' ] = [ "leaf1", "leaf2", "spine101", "spine102" ]
@@ -58,7 +50,7 @@
                 skipPackage = True
 
             main.case( '%s, with %s, %s switches and %d ONOS instance%s' %
-                       ( description, self.topo[ topology ][ 3 ],
+                       ( description, self.topo[ topology ][ 'description' ],
                          main.switchType,
                          onosNodes,
                          's' if onosNodes > 1 else '' ) )
@@ -72,8 +64,8 @@
                 run.mnDockerSetup( main )  # optionally create and setup docker image
 
                 # Run the test with Mininet
-                mininet_args = ' --spine=%d --leaf=%d' % ( self.topo[ topology ][ 0 ], self.topo[ topology ][ 1 ] )
-                if self.topo[ topology ][ 2 ]:
+                mininet_args = ' --spine=%d --leaf=%d' % ( self.topo[ topology ][ 'spines' ], self.topo[ topology ][ 'leaves' ] )
+                if self.topo[ topology ][ 'dual-homed' ]:
                     mininet_args += ' --dual-homed'
                 if len( vlan ) > 0:
                     mininet_args += ' --vlan=%s' % ( ','.join( ['%d' % vlanId for vlanId in vlan ] ) )
diff --git a/TestON/tests/USECASE/SegmentRouting/SRSwitchFailure/dependencies/SRSwitchFailureFuncs.py b/TestON/tests/USECASE/SegmentRouting/SRSwitchFailure/dependencies/SRSwitchFailureFuncs.py
index 82a4616..16293d1 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRSwitchFailure/dependencies/SRSwitchFailureFuncs.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRSwitchFailure/dependencies/SRSwitchFailureFuncs.py
@@ -26,19 +26,16 @@
 
     def __init__( self ):
         self.default = ''
-        self.topo = dict()
-        self.topo[ '0x1' ] = ( 0, 1, '--leaf=1 --spine=0', 'single switch' )
-        self.topo[ '2x2' ] = ( 2, 2, '', '2x2 Leaf-spine' )
-        self.topo[ '4x4' ] = ( 4, 4, '--leaf=4 --spine=4', '4x4 Leaf-spine' )
+        self.topo = run.getTopo()
         main.switchType = "ovs"
 
-    def runTest( self, main, caseNum, numNodes, Topo, minFlow ):
+    def runTest( self, main, caseNum, numNodes, topology, minFlow ):
         try:
-            description = "Switch Failure test with " + self.topo[ Topo ][ 3 ] + " and {} Onos".format( numNodes )
+            description = "Switch Failure test with " + self.topo[ topology ][ 'description' ] + " and {} Onos".format( numNodes )
             main.case( description )
             if not hasattr( main, 'apps' ):
                 run.initTest( main )
-            main.cfgName = Topo
+            main.cfgName = topology
             main.Cluster.setRunningNode( numNodes )
             run.installOnos( main )
             suf = main.params.get( 'jsonFileSuffix', '')
@@ -65,7 +62,7 @@
                 run.mnDockerSetup( main )  # optionally create and setup docker image
 
                 # Run the test with Mininet
-                mininet_args = self.topo[ Topo ][ 2 ]
+                mininet_args = self.topo[ topology ][ 'mininetArgs' ]
                 if main.useBmv2:
                     mininet_args += ' --switch %s' % main.switchType
                     main.log.info( "Using %s switch" % main.switchType )
@@ -79,8 +76,8 @@
             run.loadXconnects( main )
             # switch failure
             switch = main.params[ 'kill' ][ 'switch' ]
-            switchNum = self.topo[ Topo ][ 0 ] + self.topo[ Topo ][ 1 ]
-            linkNum = ( self.topo[ Topo ][ 0 ] + self.topo[ Topo ][ 1 ] ) * self.topo[ Topo ][ 0 ]
+            switchNum = self.topo[ topology ][ 'spines' ] + self.topo[ topology ][ 'leaves' ]
+            linkNum = ( self.topo[ topology ][ 'spines' ] + self.topo[ topology ][ 'leaves' ] ) * self.topo[ topology ][ 'spines' ]
             # pre-configured routing and bridging test
             run.checkFlows( main, minFlowCount=minFlow )
             run.pingAll( main )
diff --git a/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py b/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
index c8d83ef..eedd8d5 100644
--- a/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
+++ b/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
@@ -96,7 +96,19 @@
             main.testSetUp.envSetupException( e )
 
         main.testSetUp.envSetupConclusion( stepResult )
-
+    @staticmethod
+    def getTopo():
+        topo = dict()
+        # TODO: Check minFlowCount of leaf for BMv2 switch
+        # (number of spine switch, number of leaf switch, dual-homed, description, minFlowCount - leaf (OvS), minFlowCount - leaf (BMv2))
+        topo[ '0x1' ] = { 'spines': 0,'leaves': 1, 'mininetArgs': "--leaf=1 --spine=0", 'dual-homed': False,'description': 'single ToR','minFlow-OvS': 28,'minFlow-Stratum': 20,'dual-linked': False }
+        topo[ '0x2' ] = {'spines': 0,'leaves': 2, 'mininetArgs': "--leaf=2 --spine=0", 'dual-homed': True,'description': 'dual-homed ToR','minFlow-OvS': 37,'minFlow-Stratum': 37,'dual-linked': True }
+        topo[ '2x2' ] = {'spines': 2,'leaves': 2, 'mininetArgs': "--leaf=2 --spine=2", 'dual-homed': False,'description': '2x2 leaf-spine topology','minFlow-OvS': 37,'minFlow-Stratum': 32,'dual-linked': False }
+        topo[ '2x2 dual-linked' ] = {'spines': 2, 'leaves': 2, 'mininetArgs': "--leaf=2 --spine=2", 'dual-homed': False,'description': '2x2 aether dual-linked','minFlow-OvS': 37,'minFlow-Stratum': 32,'dual-linked': True }
+        topo[ '2x4' ] = { 'spines':2,'leaves': 4, 'mininetArgs': "--leaf=4 --spine=2",'dual-homed': True,'description': '2x4 dual-homed leaf-spine topology','minFlow-OvS': 53,'minFlow-Stratum': 53, 'dual-linked': False }
+        topo[ '4x4' ] = {'spines': 4,'leaves': 4, 'dual-homed': True, 'description': '4x4 dual-homed leaf-spine topology','dual-linked': True }
+        topo[ '2x2staging' ] = { 'spines': 2, 'leaves': 2,'dual-homed':  True, 'description': '2x2 leaf-spine topology', 'minFlowOvS': 37, 'minFlow-Stratum': 32 }
+        return topo
     @staticmethod
     def installOnos( main, vlanCfg=True, skipPackage=False, cliSleep=10,
                      parallel=True ):