Seperate TOST Failure/Recovery tests

- Move each test to it's own file
- Each depends on the SRStaging test functions
- Topo files are symlinked to SRStaging.topo
- Add a way to specifiy db file header order or
  sort them by default
- Handle issue with scp where prompt sometimes appears
  before and after ouput of command

Change-Id: Ia3818285a332d0f95b2484502d4db6a0f1391211
diff --git a/TestON/tests/USECASE/SegmentRouting/SRStaging/SReNBLeafSpinePortstateFailure/SReNBLeafSpinePortstateFailure.params b/TestON/tests/USECASE/SegmentRouting/SRStaging/SReNBLeafSpinePortstateFailure/SReNBLeafSpinePortstateFailure.params
new file mode 100644
index 0000000..9a3590e
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/SRStaging/SReNBLeafSpinePortstateFailure/SReNBLeafSpinePortstateFailure.params
@@ -0,0 +1,81 @@
+<PARAMS>
+    <testcases>2</testcases>
+
+    <GRAPH>
+        <nodeCluster>staging</nodeCluster>
+        <builds>20</builds>
+        <jobName>SReNBLeafSpinePortstateFaliure</jobName>
+        <branch>master</branch>
+    </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>
+        <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>
+
+    <PERF>
+        <traffic_host>Host1 Host2 Host3</traffic_host>
+        <traffic_cmd_arguments> -u -b 20M -t 40</traffic_cmd_arguments>
+
+        <pcap_host>ng40vm</pcap_host>
+        <pcap_cmd_arguments>-t e -F pcap -s 100 </pcap_cmd_arguments>
+
+    </PERF>
+    <ONOS_Logging>
+        <org.onosproject.p4runtime.ctl.client>DEBUG</org.onosproject.p4runtime.ctl.client>
+        <org.onosproject.segmentrouting>DEBUG</org.onosproject.segmentrouting>
+        <org.onosproject.gnmi.ctl>TRACE</org.onosproject.gnmi.ctl>
+    </ONOS_Logging>
+
+
+    <ENV>
+        <cellName>productionCell</cellName>
+        <cellApps>drivers,fpm,lldpprovider,hostprovider,netcfghostprovider,drivers.bmv2,org.opencord.fabric-tofino,pipelines.fabric,org.stratumproject.fabric-tna,drivers.barefoot,segmentrouting,t3</cellApps>
+    </ENV>
+
+    <EXTERNAL_APPS>
+    </EXTERNAL_APPS>
+
+    <CTRL>
+        <port>6653</port>
+    </CTRL>
+
+    <timers>
+        <LinkDiscovery>12</LinkDiscovery>
+        <SwitchDiscovery>12</SwitchDiscovery>
+        <TrafficDiscovery>10</TrafficDiscovery>
+    </timers>
+
+    <SLEEP>
+        <startup>10</startup>
+    </SLEEP>
+
+    <TOPO>
+        <switchNum>4</switchNum>
+        <linkNum>16</linkNum>
+    </TOPO>
+
+    <ALARM>
+        <minPassPercent>100</minPassPercent>
+    </ALARM>
+</PARAMS>
diff --git a/TestON/tests/USECASE/SegmentRouting/SRStaging/SReNBLeafSpinePortstateFailure/SReNBLeafSpinePortstateFailure.py b/TestON/tests/USECASE/SegmentRouting/SRStaging/SReNBLeafSpinePortstateFailure/SReNBLeafSpinePortstateFailure.py
new file mode 100644
index 0000000..278ea9a
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/SRStaging/SReNBLeafSpinePortstateFailure/SReNBLeafSpinePortstateFailure.py
@@ -0,0 +1,115 @@
+class SReNBLeafSpinePortstateFailure:
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):
+        main.case("Testing connections")
+        main.persistentSetup = True
+
+    def CASE2( self, main ):
+        """
+        Connect to Pod
+        Perform eNB Leaf-Spine Link, portstate failure/recovery test
+        Collect logs and analyze results
+        """
+        try:
+            from tests.USECASE.SegmentRouting.SRStaging.dependencies.SRStagingTest import SRStagingTest
+            import json
+        except ImportError:
+            main.log.error( "SRStagingTest not found. Exiting the test" )
+            main.cleanAndExit()
+        try:
+            main.funcs
+        except ( NameError, AttributeError ):
+            main.funcs = SRStagingTest()
+
+        descPrefix = "eNB_Leaf_Spine_Portstate"
+        main.funcs.setupTest( main,
+                              topology='2x2staging',
+                              onosNodes=3,
+                              description="%s tests on the staging pod" % descPrefix )
+        srcComponentNames = main.params[ 'PERF' ][ 'traffic_host' ].split()
+        srcComponentList = []
+        for name in srcComponentNames:
+            srcComponentList.append( getattr( main, name ) )
+        dstComponent = getattr( main, main.params[ 'PERF' ][ 'pcap_host' ] )
+
+        main.downtimeResults = {}
+        dbHeaders = []
+        srcNames = [ src.name for src in srcComponentList ]
+        srcNames.sort()
+        # TODO: MOVE TO CONFIG FILE
+        device = "device:leaf1"
+        portsList = [ 176, 180, 184, 188 ]
+        port1 = None
+        port2 = None
+        port3 = None
+        port4 = None
+
+        ## First Link Down
+        shortDesc = descPrefix + "-Failure1"
+        longDesc = "%s Failure: Bring down port with most traffic on %s" % ( descPrefix, device )
+        port1 = main.funcs.linkDown( device, portsList, srcComponentList, dstComponent, shortDesc, longDesc )
+        for src in srcNames:
+            dbHeaders.append( "%s-%s" % ( shortDesc, src ) )
+        for src in srcNames:
+            dbHeaders.append( "%s-%s-%s" % ( shortDesc, src, dstComponent.name ) )
+        ## Second Link Down
+        shortDesc = descPrefix + "-Failure2"
+        longDesc = "%s Failure: Bring down port with most traffic on %s" % ( descPrefix, device )
+        port2 = main.funcs.linkDown( device, portsList, srcComponentList, dstComponent, shortDesc, longDesc )
+        for src in srcNames:
+            dbHeaders.append( "%s-%s" % ( shortDesc, src ) )
+        for src in srcNames:
+            dbHeaders.append( "%s-%s-%s" % ( shortDesc, src, dstComponent.name ) )
+        ## First Link Up
+        shortDesc = descPrefix + "-Recovery1"
+        longDesc = "%s Recovery: Bring up %s/%s" % ( descPrefix, device, port1 )
+        main.funcs.linkUp( device, port1, srcComponentList, dstComponent, shortDesc, longDesc )
+        for src in srcNames:
+            dbHeaders.append( "%s-%s" % ( shortDesc, src ) )
+        for src in srcNames:
+            dbHeaders.append( "%s-%s-%s" % ( shortDesc, src, dstComponent.name ) )
+        ## Second Link Up
+        shortDesc = descPrefix + "-Recovery2"
+        longDesc = "%s Recovery: Bring up %s/%s" % ( descPrefix, device, port2 )
+        main.funcs.linkUp( device, port2, srcComponentList, dstComponent, shortDesc, longDesc )
+        for src in srcNames:
+            dbHeaders.append( "%s-%s" % ( shortDesc, src ) )
+        for src in srcNames:
+            dbHeaders.append( "%s-%s-%s" % ( shortDesc, src, dstComponent.name ) )
+        ## Third Link Down
+        shortDesc = descPrefix + "-Failure3"
+        longDesc = "%s Failure: Bring down port with most traffic on %s" % ( descPrefix, device )
+        port3 = main.funcs.linkDown( device, portsList, srcComponentList, dstComponent, shortDesc, longDesc )
+        for src in srcNames:
+            dbHeaders.append( "%s-%s" % ( shortDesc, src ) )
+        for src in srcNames:
+            dbHeaders.append( "%s-%s-%s" % ( shortDesc, src, dstComponent.name ) )
+        ## Forth Link Down
+        shortDesc = descPrefix + "-Failure4"
+        longDesc = "%s Failure: Bring down port with most traffic on %s" % ( descPrefix, device )
+        port4 = main.funcs.linkDown( device, portsList, srcComponentList, dstComponent, shortDesc, longDesc )
+        for src in srcNames:
+            dbHeaders.append( "%s-%s" % ( shortDesc, src ) )
+        for src in srcNames:
+            dbHeaders.append( "%s-%s-%s" % ( shortDesc, src, dstComponent.name ) )
+        ## Third Link Up
+        shortDesc = descPrefix + "-Recovery3"
+        longDesc = "%s Recovery: Bring upn %s/%s" % ( descPrefix, device, port3 )
+        main.funcs.linkUp( device, port3, srcComponentList, dstComponent, shortDesc, longDesc )
+        for src in srcNames:
+            dbHeaders.append( "%s-%s" % ( shortDesc, src ) )
+        for src in srcNames:
+            dbHeaders.append( "%s-%s-%s" % ( shortDesc, src, dstComponent.name ) )
+        ## Forth Link Up
+        shortDesc = descPrefix + "-Recovery4"
+        longDesc = "%s Recovery: Bring up  %s/%s" % ( descPrefix, device, port4 )
+        main.funcs.linkUp( device, port4, srcComponentList, dstComponent, shortDesc, longDesc )
+        for src in srcNames:
+            dbHeaders.append( "%s-%s" % ( shortDesc, src ) )
+        for src in srcNames:
+            dbHeaders.append( "%s-%s-%s" % ( shortDesc, src, dstComponent.name ) )
+
+        main.log.warn( json.dumps( main.downtimeResults, indent=4, sort_keys=True ) )
+        main.funcs.cleanup( main, headerOrder=dbHeaders )
diff --git a/TestON/tests/USECASE/SegmentRouting/SRStaging/SReNBLeafSpinePortstateFailure/SReNBLeafSpinePortstateFailure.topo b/TestON/tests/USECASE/SegmentRouting/SRStaging/SReNBLeafSpinePortstateFailure/SReNBLeafSpinePortstateFailure.topo
new file mode 120000
index 0000000..502edf5
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/SRStaging/SReNBLeafSpinePortstateFailure/SReNBLeafSpinePortstateFailure.topo
@@ -0,0 +1 @@
+../SRStaging.topo
\ No newline at end of file
diff --git a/TestON/tests/USECASE/SegmentRouting/SRStaging/SReNBLeafSpinePortstateFailure/__init__.py b/TestON/tests/USECASE/SegmentRouting/SRStaging/SReNBLeafSpinePortstateFailure/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/SRStaging/SReNBLeafSpinePortstateFailure/__init__.py