SRRouting - Ping between IPv4 hosts in the topo

Change-Id: I76cc750a2417ac94a5ef2df673e0c8b5d9ff0d01
diff --git a/TestON/drivers/common/cli/onosdriver.py b/TestON/drivers/common/cli/onosdriver.py
index 6e3a7d3..4b4329d 100755
--- a/TestON/drivers/common/cli/onosdriver.py
+++ b/TestON/drivers/common/cli/onosdriver.py
@@ -2727,7 +2727,7 @@
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanAndExit()
 
-    def onosDiagnostics( self, onosIPs, dstDir, suffix, timeout=300, profile="TRELLIS_PROFILE" ):
+    def onosDiagnostics( self, onosIPs, dstDir, suffix, timeout=300, profile="TRELLIS_PROFILE", onosPortnumber=8181 ):
         """
             Run onos-diagnostics with given ONOS instance IPs and save output to dstDir
             with suffix specified E.g. onos-diags-suffix.tar.gz
@@ -2741,7 +2741,7 @@
         try:
             self.handle.sendline( "export DIAGS_PROFILE=%s" % profile )
             self.handle.expect( self.prompt )
-            cmd = "onos-diagnostics"
+            cmd = "onos-diagnostics -P %s" % onosPortnumber
             assert isinstance( onosIPs, list )
             for ip in onosIPs:
                 cmd += " " + str( ip )
diff --git a/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.params.tofino b/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.params.tofino
new file mode 100644
index 0000000..e999afb
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.params.tofino
@@ -0,0 +1,102 @@
+<PARAMS>
+    <testcases>1</testcases>
+
+    <GRAPH>
+        <nodeCluster>QA-Pod</nodeCluster>
+        <builds>20</builds>
+        <jobName>SRRouting-tofino</jobName>
+    </GRAPH>
+
+    <SCALE>
+        <size>3</size>
+        <max>3</max>
+    </SCALE>
+
+    <DEPENDENCY>
+        <useCommonConf>False</useCommonConf>
+        <useCommonTopo>True</useCommonTopo>
+        <useBmv2>True</useBmv2>
+        <bmv2SwitchType>stratum</bmv2SwitchType>
+        <switchPrefix></switchPrefix>
+        <stratumRoot>~/stratum</stratumRoot>
+        <topology>trellis_fabric.py</topology>
+        <confName>QA</confName>
+        <lib>routinglib.py,trellislib.py,stratum.py</lib>
+    </DEPENDENCY>
+
+    <jsonFileSuffix>.hw</jsonFileSuffix>
+
+    <persistent_setup>True</persistent_setup>
+
+    <kubernetes>
+        <appName>onos-tost-onos-classic</appName>
+        <namespace>tost</namespace>
+    </kubernetes>
+
+
+    <ENV>
+        <cellName>productionCell</cellName>
+        <cellApps>drivers,fpm,lldpprovider,hostprovider,netcfghostprovider,drivers.bmv2,pipelines.fabric,org.stratumproject.fabric-tna,drivers.barefoot,segmentrouting,t3</cellApps>
+    </ENV>
+
+    <EXTERNAL_APPS>
+    </EXTERNAL_APPS>
+
+    <ONOS_Configuration>
+        <org.onosproject.grpc.ctl.GrpcChannelControllerImpl>
+            <enableMessageLog>true</enableMessageLog>
+        </org.onosproject.grpc.ctl.GrpcChannelControllerImpl>
+    </ONOS_Configuration>
+
+    <ONOS_Logging>
+        <org.onosproject.events>TRACE</org.onosproject.events>
+        <org.onosproject.segmentrouting>DEBUG</org.onosproject.segmentrouting>
+        <org.onosproject.driver>DEBUG</org.onosproject.driver>
+        <org.onosproject.net.flowobjective.impl>DEBUG</org.onosproject.net.flowobjective.impl>
+        <org.onosproject.routeservice.impl>DEBUG</org.onosproject.routeservice.impl>
+        <org.onosproject.routeservice.store>DEBUG</org.onosproject.routeservice.store>
+        <org.onosproject.routing.fpm>DEBUG</org.onosproject.routing.fpm>
+        <org.onosproject.fpm>DEBUG</org.onosproject.fpm>
+        <org.onosproject.mcast>DEBUG</org.onosproject.mcast>
+        <org.onosproject.p4runtime>DEBUG</org.onosproject.p4runtime>
+        <org.onosproject.protocols.p4runtime>DEBUG</org.onosproject.protocols.p4runtime>
+        <org.onosproject.drivers.p4runtime>DEBUG</org.onosproject.drivers.p4runtime>
+        <org.onosproject.protocols.grpc>DEBUG</org.onosproject.protocols.grpc>
+        <org.onosproject.protocols.gnmi>DEBUG</org.onosproject.protocols.gnmi>
+        <org.onosproject.protocols.gnoi>DEBUG</org.onosproject.protocols.gnoi>
+        <org.onosproject.drivers.gnoi>DEBUG</org.onosproject.drivers.gnoi>
+        <org.onosproject.drivers.gmni>DEBUG</org.onosproject.drivers.gmni>
+        <org.onosproject.drivers.barefoot>DEBUG</org.onosproject.drivers.barefoot>
+        <org.onosproject.bmv2>DEBUG</org.onosproject.bmv2>
+    </ONOS_Logging>
+
+
+    <CTRL>
+        <port>6653</port>
+    </CTRL>
+
+    <timers>
+        <LinkDiscovery>12</LinkDiscovery>
+        <SwitchDiscovery>12</SwitchDiscovery>
+        <TrafficDiscovery>10</TrafficDiscovery>
+        <OnosDiscovery>45</OnosDiscovery>
+        <loadNetcfgSleep>5</loadNetcfgSleep>
+        <startMininetSleep>25</startMininetSleep>
+        <dhcpSleep>1</dhcpSleep>
+        <balanceMasterSleep>10</balanceMasterSleep>
+    </timers>
+
+    <SLEEP>
+        <startup>10</startup>
+    </SLEEP>
+
+    <TOPO>
+        <internalIpv4Hosts>h1,h2</internalIpv4Hosts>
+        <switchNum>4</switchNum>
+        <linkNum>16</linkNum>
+    </TOPO>
+
+    <ALARM>
+        <minPassPercent>100</minPassPercent>
+    </ALARM>
+</PARAMS>
diff --git a/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.topo.2x2.physical b/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.topo.2x2.physical
new file mode 100644
index 0000000..e9f18ee
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.topo.2x2.physical
@@ -0,0 +1,177 @@
+<TOPOLOGY>
+    <COMPONENT>
+        <ONOScell>
+            <host>localhost</host>  # ONOS "bench" machine
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosClusterDriver</type>
+            <connect_order>1</connect_order>
+            <home></home>   # defines where onos home is on the build machine. Defaults to "~/onos/" if empty.
+            <COMPONENTS>
+                <kubeConfig>~/.kube/qa-ace-menlo</kubeConfig>  # If set, will attempt to use this file for setting up port-forwarding
+                <useDocker>True</useDocker>  # Whether to use docker for ONOS nodes
+                <docker_prompt>\$</docker_prompt>
+                <cluster_name></cluster_name>  # Used as a prefix for cluster components. Defaults to 'ONOS'
+                <diff_clihost>True</diff_clihost> # if it has different host other than localhost for CLI. True or empty. OC# will be used if True.
+                <karaf_username>karaf</karaf_username>
+                <karaf_password>karaf</karaf_password>
+                <node_username>sdn</node_username>
+                <node_password>rocks</node_password>
+                <karafPrompt_username>karaf</karafPrompt_username>
+                <karafPrompt_password>karaf</karafPrompt_password>
+                <web_user>karaf</web_user>
+                <web_pass>karaf</web_pass>
+                <rest_port></rest_port>
+                <prompt></prompt>  # TODO: we technically need a few of these, one per component
+                <onos_home></onos_home>  # defines where onos home is on the target cell machine. Defaults to entry in "home" if empty.
+                <nodes> 7 </nodes>  # number of nodes in the cluster
+            </COMPONENTS>
+        </ONOScell>
+
+        <Leaf1>
+            <host>10.128.13.209</host>
+            <user>root</user>
+            <password>onl</password>
+            <type>StratumOSSwitchDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS>
+                <prompt>#</prompt>
+                <shortName>leaf1</shortName>
+                <port1>1</port1>
+                <link1>Host1</link1>
+                <onosConfigPath></onosConfigPath>
+                <onosConfigFile></onosConfigFile>
+            </COMPONENTS>
+        </Leaf1>
+
+        <Leaf2>
+            <host>10.128.13.211</host>
+            <user>root</user>
+            <password>onl</password>
+            <type>StratumOSSwitchDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS>
+                <prompt>#</prompt>
+                <shortName>leaf2</shortName>
+                <port1>2</port1>
+                <link1>Host2</link1>
+                <onosConfigPath></onosConfigPath>
+                <onosConfigFile></onosConfigFile>
+            </COMPONENTS>
+        </Leaf2>
+
+        <Spine1>
+            <host>10.128.13.213</host>
+            <user>root</user>
+            <password>onl</password>
+            <type>StratumOSSwitchDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS>
+                <prompt>#</prompt>
+                <shortName>spine1</shortName>
+                <onosConfigPath></onosConfigPath>
+                <onosConfigFile></onosConfigFile>
+            </COMPONENTS>
+        </Spine1>
+
+        <Spine2>
+            <host>10.128.13.215</host>
+            <user>root</user>
+            <password>onl</password>
+            <type>StratumOSSwitchDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS>
+                <prompt>#</prompt>
+                <shortName>spine2</shortName>
+                <onosConfigPath></onosConfigPath>
+                <onosConfigFile></onosConfigFile>
+            </COMPONENTS>
+        </Spine2>
+
+        <Host1>
+            <host>10.128.13.253</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>HostDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS>
+                <mac>3c:fd:fe:a8:ea:30</mac>
+                <inband>false</inband>
+                <ip>192.168.102.3</ip>
+                <shortName>h1</shortName>
+                <port1>0</port1>
+                <link1>Leaf1</link1>
+                <interfaceName>ens6f0</interfaceName>
+                <routes>
+                    <route1>
+                        <network>192.168.101.1</network>
+                        <netmask>24</netmask>
+                        <gw>192.168.103.1</gw>
+                        <interface></interface>
+                    </route1>
+                </routes>
+            </COMPONENTS>
+        </Host1>
+
+        <Host2>
+            <host>10.128.13.253</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>HostDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS>
+                <mac>3c:fd:fe:a8:ea:31</mac>
+                <inband>false</inband>
+                <ip>192.168.103.3</ip>
+                <shortName>h2</shortName>
+                <port1>0</port1>
+                <link1>Leaf1</link1>
+                <interfaceName>ens6f1</interfaceName>
+                <routes>
+                    <route1>
+                        <network>192.168.101.1</network>
+                        <netmask>24</netmask>
+                        <gw>192.168.103.1</gw>
+                        <interface></interface>
+                    </route1>
+                </routes>
+            </COMPONENTS>
+        </Host2>
+
+        <ng40vm>
+            <host>10.92.1.71</host>
+            <user>ng40</user>
+            <password>ng40</password>
+            <type>HostDriver</type>
+            <connect_order>8</connect_order>
+            <COMPONENTS>
+                <mac>52:54:00:e3:88:36</mac>
+                <inband>false</inband>
+                <ip>192.168.101.101</ip>
+                <shortName>ng40</shortName>
+                <port1></port1>
+                <link1></link1>
+                <interfaceName>ens8</interfaceName>
+                <routes>
+                    <route1>
+                        <network>192.168.101.1</network>
+                        <netmask>24</netmask>
+                        <gw>192.168.103.1</gw>
+                        <interface>ens8</interface>
+                    </route1>
+                </routes>
+            </COMPONENTS>
+        </ng40vm>
+
+        <NetworkBench>
+            <host>10.128.13.253</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>NetworkDriver</type>
+            <connect_order>10</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </NetworkBench>
+
+    </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/SRRoutingTest.py b/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/SRRoutingTest.py
index 1b544dc..fd6f018 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/SRRoutingTest.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/SRRoutingTest.py
@@ -41,7 +41,7 @@
             skipPackage = True
 
         main.internalIpv4Hosts = main.params[ 'TOPO' ][ 'internalIpv4Hosts' ].split( ',' )
-        main.internalIpv6Hosts = main.params[ 'TOPO' ][ 'internalIpv6Hosts' ].split( ',' )
+        main.internalIpv6Hosts = main.params[ 'TOPO' ][ 'internalIpv6Hosts' ].split( ',' ) if main.params[ 'TOPO' ].get( 'internalIpv6Hosts' ) else []
         main.externalIpv4Hosts = main.params[ 'TOPO' ][ 'externalIpv4Hosts' ].split( ',' ) if main.params[ 'TOPO' ].get('externalIpv4Hosts') else []
         main.externalIpv6Hosts = main.params[ 'TOPO' ][ 'externalIpv6Hosts' ].split( ',' ) if main.params[ 'TOPO' ].get('externalIpv6Hosts') else []
         main.staticIpv4Hosts = main.params[ 'TOPO' ][ 'staticIpv4Hosts' ].split( ',' ) if main.params[ 'TOPO' ].get('staticIpv4Hosts') else []
@@ -63,16 +63,16 @@
                                                                  1 if ipv6 else 0)
         else:
             main.cfgName = main.params[ "DEPENDENCY" ][ "confName" ]
-        if main.useBmv2:
-            # Translate configuration file from OVS-OFDPA to BMv2 driver
-            translator.bmv2ToOfdpa( main )  # Try to cleanup if switching between switch types
-            switchPrefix = main.params[ 'DEPENDENCY' ].get( 'switchPrefix', '' )
-            if switchPrefix is None:
-                switchPrefix = ''
-            translator.ofdpaToBmv2( main, switchPrefix=switchPrefix )
-        else:
-            translator.bmv2ToOfdpa( main )
         if not main.persistentSetup:
+            if main.useBmv2:
+                # Translate configuration file from OVS-OFDPA to BMv2 driver
+                translator.bmv2ToOfdpa( main )  # Try to cleanup if switching between switch types
+                switchPrefix = main.params[ 'DEPENDENCY' ].get( 'switchPrefix', '' )
+                if switchPrefix is None:
+                    switchPrefix = ''
+                translator.ofdpaToBmv2( main, switchPrefix=switchPrefix )
+            else:
+                translator.bmv2ToOfdpa( main )
             lib.loadJson( main )
         main.log.debug( "sleeping %i seconds" % float( main.params[ 'timers' ][ 'loadNetcfgSleep' ] ) )
         time.sleep( float( main.params[ 'timers' ][ 'loadNetcfgSleep' ] ) )
@@ -270,20 +270,8 @@
     """
     from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
 
-    spines = 4
-    leaves = 6
-    switches = spines + leaves
-    links = 0
-    #links = ( spines * leaves ) * 2
-    # Some double links, spines 101 and 102 to leaves 2-5
-    links += ( 2 * 4 * 2 ) * 2
-    # Some paired leaves
-    links += ( ( leaves - 2 ) / 2 ) * 2
-    # Paired spines
-    links += ( spines / 2 ) * 2
-    # single homed leaf to spines
-    links += ( 2 * 2 ) * 2
-
+    switches = int(main.params["TOPO"][ "switchNum" ])
+    links = int( main.params["TOPO"][ "linkNum" ])
     lib.verifyTopology( main, switches, links, len( main.Cluster.runningNodes ) )
     # check flows / groups numbers
     if countFlowsGroups:
diff --git a/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/host/QA.host b/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/host/QA.host
new file mode 100644
index 0000000..e0ac2fa
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/host/QA.host
@@ -0,0 +1,12 @@
+{
+    "onos":
+    {
+        "3C:FD:FE:A8:EA:30/None": "192.168.102.3",
+        "3C:FD:FE:A8:EA:31/None": "192.168.103.3"
+        },
+    "network":
+    {
+        "h1": "192.168.102.3",
+        "h2": "192.168.103.3"
+        }
+}
diff --git a/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py b/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
index eedd8d5..b5f61a7 100644
--- a/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
+++ b/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
@@ -438,9 +438,8 @@
         suffix: suffix string of the file name. E.g. onos-diags-case1.tar.gz
         """
         main.log.info( "Collecting onos-diags..." )
-        main.ONOSbench.onosDiagnostics( [ctrl.ipAddress for ctrl in main.Cluster.runningNodes],
-                                        main.logdir,
-                                        "-CASE%d" % main.CurrentTestCaseNumber )
+        for ctrl in main.Cluster.runningNodes:
+            main.ONOSbench.onosDiagnostics( [ctrl.ipAddress], main.logdir,"-CASE%d" % main.CurrentTestCaseNumber, onosPortnumber=ctrl.REST.port )
 
     @staticmethod
     def config( main, cfgName ):
diff --git a/TestON/tests/dependencies/topology.py b/TestON/tests/dependencies/topology.py
index 26c3309..9d20cda 100644
--- a/TestON/tests/dependencies/topology.py
+++ b/TestON/tests/dependencies/topology.py
@@ -259,10 +259,12 @@
                     hostHandle.startHostCli()
                 else:
                     hostHandle.connectInband()
-            srcIpList[ src ] = main.Network.getIPAddress( src, proto='IPV6' if ipv6 else 'IPV4' )
+            hostHandle = getattr( main, src )
+            srcIpList[ src ] = main.Network.getIPAddress( src, proto='IPV6' if ipv6 else 'IPV4', iface=hostHandle.interfaces[0].get("name") )
         unexpectedPings = []
         for dst in dstList:
-            dstIp = main.Network.getIPAddress( dst, proto='IPV6' if ipv6 else 'IPV4' )
+            hostHandle = getattr( main, dst )
+            dstIp = main.Network.getIPAddress( dst, proto='IPV6' if ipv6 else 'IPV4', iface=hostHandle.interfaces[0].get("name") )
             # Start pings from src hosts in parallel
             pool = []
             for src in srcList: