Merge changes from topic 'devl/cam'

* changes:
  initial flow tp test
  added intent reroute test and relevant drivers
diff --git a/TestON/drivers/common/cli/onosdriver.py b/TestON/drivers/common/cli/onosdriver.py
index cfceaf9..4c786a3 100644
--- a/TestON/drivers/common/cli/onosdriver.py
+++ b/TestON/drivers/common/cli/onosdriver.py
@@ -749,39 +749,57 @@
         
         ex)
             onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
-
         ONOSIp = '10.0.0.1'
         configName = 'org.onosproject.myapp'
         configParam = 'appSetting 1'
-
         """
-        try:
-            cfgStr = ( "onos "+str(ONOSIp)+" cfg set "+
-                       str(configName) + " " +
-                       str(configParam)
-                     )
+        for i in range(5):
+            try:
+                cfgStr = ( "onos "+str(ONOSIp)+" cfg set "+
+                           str(configName) + " " +
+                           str(configParam)
+                         )
 
-            self.handle.sendline( "" )
-            self.handle.expect( "\$" )
-            self.handle.sendline( cfgStr )
-            self.handle.expect( "\$" )
-        
-            # TODO: Add meaningful assertion
+                self.handle.sendline( "" )
+                self.handle.expect( ":~" )
+                self.handle.sendline( cfgStr )
+                self.handle.expect("cfg set") 
+                self.handle.expect( ":~" )
             
-            return main.TRUE
+                paramValue = configParam.split(" ")[1]
+                paramName = configParam.split(" ")[0]
+                
+                checkStr = ( "onos " + str(ONOSIp) + """ cfg get " """ + str(configName) + " " + paramName + """ " """)
 
-        except pexpect.ExceptionPexpect as e:
-            main.log.error( self.name + ": Pexpect exception found of type " +
-                            str( type( e ) ) )
-            main.log.error ( e.get_trace() )
-            main.log.error( self.name + ":    " + self.handle.before )
-            main.cleanup()
-            main.exit()
-        except Exception:
-            main.log.exception( self.name + ": Uncaught exception!" )
-            main.cleanup()
-            main.exit()
+                self.handle.sendline( checkStr )
+                self.handle.expect( ":~" )
 
+                if "value=" + paramValue + "," in self.handle.before:
+                    main.log.info("cfg " + configName + " successfully set to " + configParam)    
+                    return main.TRUE
+
+            except pexpect.ExceptionPexpect as e:
+                main.log.error( self.name + ": Pexpect exception found of type " +
+                                str( type( e ) ) )
+                main.log.error ( e.get_trace() )
+                main.log.error( self.name + ":    " + self.handle.before )
+                main.cleanup()
+                main.exit()
+            except Exception:
+                main.log.exception( self.name + ": Uncaught exception!" )
+                main.cleanup()
+                main.exit()
+            
+            time.sleep(5)
+
+        main.log.error("CFG SET FAILURE: " + configName + " " + configParam )
+        main.ONOSbench.handle.sendline("onos $OC1 cfg get") 
+        main.ONOSbench.handle.expect("\$")
+        print main.ONOSbench.handle.before
+        main.ONOSbench.logReport( ONOSIp, ["ERROR","WARN","EXCEPT"], "d")
+        return main.FALSE
+
+        
     def onosCli( self, ONOSIp, cmdstr ):
         """
         Uses 'onos' command to send various ONOS CLI arguments.
@@ -2116,149 +2134,6 @@
         main.log.info("================================================================\n")
         return totalHits 
 
-    def getOnosIpFromEnv(self):
-
-        import string  
-
-        # returns a list of ip addresses for the onos nodes, will work with up to 7 nodes + OCN and OCI
-        # returns in format [ 'x', OC1 ip, OC2 i... ect. ... , ONN ip ]
-
-        self.handle.sendline("env| grep OC") 
-        self.handle.expect(":~")
-        rawOutput = self.handle.before
-        print rawOutput
-        print "-----------------------------"
-        print repr(rawOutput)
-        mpa = dict.fromkeys(range(32))
-        translated = rawOutput.translate(mpa)
-        print translated
-
-
-        # create list with only the lines that have the needed IPs 
-        unparsedIps = []
-
-        # remove preceeding or trailing lines
-        for line in rawOutput: 
-            if "OC" in line and "=" in line: 
-                unparsedIps.append(str(line)) 
-
-        # determine cluster size
-        clusterCount = 0
-        for line in unparsedIps:
-            line = str(line)
-            print line
-            temp = line.replace("OC","")
-            print("line index " + str(line.index("="))) 
-            OCindex = temp[0]
-            for i in range(0, 7):
-                if OCindex == str(i) and i > clusterCount:
-                    clusterCount == i
-                    print(clusterCount)
-        # create list to hold ips such that OC1 is at list[1] and OCN and OCI are at the end (in that order)
-        ONOSIps = ["x"] * (clusterCount + 3) 
-
-        # populate list 
-        for line in unparsedIps:
-            main.log.info(line)########## 
-            temp = str(line.replace("OC",""))
-            main.log.info(str(list(temp)))
-            OCindex = temp[0]
-            main.log.info(OCindex)############
-            if OCindex == "N":
-                ONOSIps[ clusterCount + 1 ] = temp.replace("N=","")
-    
-            if OCindex == "I":
-                ONOSIps[ clusterCount + 2 ] = temp.replace("I=","")
-
-            else:
-                ONOSIps[ int(OCindex) ] = temp.replace((OCindex + "=") ,"")
-
-        # validate 
-        for x in ONOSIps: 
-            if ONOSIps.index(x) != 0 and x == "x": 
-                main.log.error("ENV READ FAILURE, MISSING DATA: \n\n" + str(ONOSIps) + "\n\n") 
-
-        return ONOSIps
-
-
-    def onosErrorLog(self, nodeIp): 
-
-        cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep WARN"
-        self.handle.sendline(cmd) 
-        self.handle.expect(":~")
-        before = (self.handle.before).splitlines() 
-
-        warnings = []
-
-        for line in before: 
-            if "WARN" in line and "grep" not in line: 
-                warnings.append(line) 
-                main.warnings[main.warnings[0]+1] = line
-                main.warnings[0] += 1
-                if main.warnings[0] >= 10: 
-                    main.warnings[0] = 0 
-
-        cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep ERROR"
-        self.handle.sendline(cmd)
-        self.handle.expect(":~")
-        before = (self.handle.before).splitlines()
-
-        errors = []
-
-        for line in before:
-            if "ERROR" in line and "grep" not in line:
-                errors.append(line)
-                main.errors[main.errors[0]+1] = line
-                main.errors[0] += 1
-                if main.errors[0] >= 10:
-                    main.errors[0] = 0
-
-        cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep Exept"
-        self.handle.sendline(cmd)
-        self.handle.expect(":~")
-        before = (self.handle.before).splitlines()
-
-        exceptions = []
-
-        for line in before:
-            if "Except" in line and "grep" not in line:
-                exceptions.append(line)
-                main.exceptions[main.errors[0]+1] = line
-                main.exceptions[0] += 1
-                if main.exceptions[0] >= 10:
-                    main.exceptions[0] = 0
-
-
-
-        ################################################################
-
-        msg1 = "WARNINGS: \n"
-        for i in main.warnings: 
-            if type(i) is not int: 
-                msg1 += ( i + "\n")
-
-        msg2 = "ERRORS: \n"
-        for i in main.errors:
-            if type(i) is not int:
-                msg2 += ( i + "\n")
-
-        msg3 = "EXCEPTIONS: \n"
-        for i in main.exceptions: 
-            if type(i) is not int:
-                msg3 += ( i + "\n")
-
-        main.log.info("===============================================================\n") 
-        main.log.info( "Warnings: " + str(len(warnings))) 
-        main.log.info( "Errors: " + str(len(errors))) 
-        main.log.info( "Exceptions: " + str(len(exceptions)))
-        if len(warnings) > 0:
-            main.log.info(msg1)
-        if len(errors) > 0: 
-            main.log.info(msg2)
-        if len(exceptions) > 0: 
-            main.log.info(msg3)
-        main.log.info("===============================================================\n")
-
     def getOnosIPfromCell(self):
         '''
             Returns the ONOS node names and their IP addresses as defined in the cell and applied to shell environment
@@ -2357,3 +2232,68 @@
             main.log.error( self.name + ":     " + self.handle.before )
             main.cleanup()
             main.exit()
+
+    def jvmSet(self, memory=8):
+        
+        import os
+
+        homeDir = os.path.expanduser('~')
+        filename = "/onos/tools/package/bin/onos-service"
+
+        serviceConfig = open(homeDir + filename, 'w+')
+        serviceConfig.write("#!/bin/bash\n ")
+        serviceConfig.write("#------------------------------------- \n ")
+        serviceConfig.write("# Starts ONOS Apache Karaf container\n ")
+        serviceConfig.write("#------------------------------------- \n ")
+        serviceConfig.write("#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n ")
+        serviceConfig.write("""export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str(memory) + "G -Xmx" + str(memory) + """G}" \n """)
+        serviceConfig.write("[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n")
+        serviceConfig.write("""${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """)
+        serviceConfig.close()
+
+    def createDBFile(self, testData):
+        
+        filename = main.TEST + "DB"
+        DBString = ""
+        
+        for item in testData:
+            if type(item) is string: 
+                item = "'" + item + "'"
+            if testData.index(item) < len(testData-1):
+                item += ","
+            DBString += str(item) 
+
+        DBFile = open(filename, "a")
+        DBFile.write(DBString)
+        DBFile.close()
+
+    def verifySummary(self, ONOSIp,*deviceCount): 
+
+        self.handle.sendline("onos " + ONOSIp  + " summary")
+        self.handle.expect(":~")
+
+        summaryStr = self.handle.before
+        print "\nSummary\n==============\n" + summaryStr + "\n\n"
+
+        #passed = "SCC(s)=1" in summaryStr
+        #if deviceCount:
+        #    passed = "devices=" + str(deviceCount) + "," not in summaryStr
+
+           
+        if "SCC(s)=1," in summaryStr:
+            passed = True
+            print("Summary is verifed")
+        else: 
+            print("Summary failed") 
+
+        if deviceCount:
+            print" ============================="
+            checkStr = "devices=" + str(deviceCount[0]) + ","
+            print "Checkstr: " + checkStr
+            if checkStr not in summaryStr:
+                passed = False
+                print("Device count failed") 
+            else: 
+                print "device count verified" 
+
+        return passed
diff --git a/TestON/tests/SCPFflowTp1g/SCPFflowTp1g.params b/TestON/tests/SCPFflowTp1g/SCPFflowTp1g.params
new file mode 100644
index 0000000..a3b104f
--- /dev/null
+++ b/TestON/tests/SCPFflowTp1g/SCPFflowTp1g.params
@@ -0,0 +1,73 @@
+<PARAMS>
+
+    <testcases>1,2,1,2,1,2,1,2,1,2,1,2,1,2</testcases>
+    
+    <isOnBaremetal>True</isOnBaremetal>
+    <SCALE>1,3,3,5,5,7,7</SCALE>
+    <availableNodes>7</availableNodes>
+    
+
+
+    <ENV>
+        <cellName>flowTP</cellName>
+        <cellApps>drivers,null,demo</cellApps>
+    </ENV>
+
+    <TEST>
+        <enableFlowRuleStoreBackup>true</enableFlowRuleStoreBackup>
+        <skipCleanInstall>yes</skipCleanInstall> 
+        <warmUp>5</warmUp>                              #number of runs to warm up the system
+        <sampleSize>20</sampleSize>                     #number of runs to take data from
+        <neighbors>0,a</neighbors>                      #list of number of neighbors, a = all 
+        <flows>122500</flows>
+        <switches>35</switches>
+        <cooldown>10</cooldown>
+        <testCMD0>flow-tester.py -f</testCMD0>          #base command 
+        <testCMD1> -n </testCMD1>                       #neighbors 
+        
+    </TEST>
+
+    <GIT>
+        <autopull>off</autopull>
+        <checkout>master</checkout>
+    </GIT>
+
+    <CTRL>
+        <USER>admin</USER>
+        
+        <ip1>OC1</ip1>
+        <port1>6633</port1>
+        
+        <ip2>OC2</ip2>
+        <port2>6633</port2>
+        
+        <ip3>OC3</ip3>
+        <port3>6633</port3>
+        
+        <ip4>OC4</ip4>
+        <port4>6633</port4>
+        
+        <ip5>OC5</ip5>
+        <port5>6633</port5>
+        
+        <ip6>OC6</ip6>
+        <port6>6633</port6> 
+       
+        <ip7>OC7</ip7>
+        <port7>6633</port7>
+
+    </CTRL>
+
+    <MN>
+        <ip1>OCN</ip1>
+    </MN>
+
+    <BENCH>
+        <user>admin</user>
+        <ip1>OCN</ip1>
+    </BENCH>
+
+    <JSON>
+    </JSON>
+
+</PARAMS>
diff --git a/TestON/tests/SCPFflowTp1g/SCPFflowTp1g.py b/TestON/tests/SCPFflowTp1g/SCPFflowTp1g.py
new file mode 100644
index 0000000..48f1b57
--- /dev/null
+++ b/TestON/tests/SCPFflowTp1g/SCPFflowTp1g.py
@@ -0,0 +1,403 @@
+# ScaleOutTemplate -> flowTP
+#
+# CASE1 starts number of nodes specified in param file
+#
+# cameron@onlab.us
+
+import sys
+import os.path
+
+
+class SCPFflowTp1g:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):          
+
+        import time
+        global init
+        try:
+            if type(init) is not bool:
+                init = False
+        except NameError:
+            init = False
+
+        #Load values from params file
+        checkoutBranch = main.params[ 'GIT' ][ 'checkout' ]
+        gitPull = main.params[ 'GIT' ][ 'autopull' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        Apps = main.params[ 'ENV' ][ 'cellApps' ]
+        BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+        maxNodes = int(main.params[ 'availableNodes' ])
+        skipMvn = main.params[ 'TEST' ][ 'skipCleanInstall' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]       
+    
+        main.log.info("==========DEBUG VERSION 3===========")
+
+        main.exceptions = [0]*11
+        main.warnings = [0]*11
+        main.errors = [0]*11
+
+        # -- INIT SECTION, ONLY RUNS ONCE -- #
+        if init == False:
+            init = True
+            global clusterCount             #number of nodes running
+            global ONOSIp                   #list of ONOS IP addresses
+            global scale
+            global commit
+
+            clusterCount = 0
+            ONOSIp = [ 0 ]
+            scale = (main.params[ 'SCALE' ]).split(",")
+            clusterCount = int(scale[0])
+
+            #Populate ONOSIp with ips from params
+            for i in range(1, maxNodes + 1):
+                ipString = 'ip' + str(i)
+                ONOSIp.append(main.params[ 'CTRL' ][ ipString ])
+
+            ONOSIp = [0]
+            ONOSIp.extend(main.ONOSbench.getOnosIps())
+
+            #mvn clean install, for debugging set param 'skipCleanInstall' to yes to speed up test
+            if skipMvn != "yes":
+                mvnResult = main.ONOSbench.cleanInstall()
+
+            #git
+            main.step( "Git checkout and pull " + checkoutBranch )
+            if gitPull == 'on':
+                checkoutResult = main.ONOSbench.gitCheckout( checkoutBranch )
+                pullResult = main.ONOSbench.gitPull()
+
+            else:
+                checkoutResult = main.TRUE
+                pullResult = main.TRUE
+                main.log.info( "Skipped git checkout and pull" )
+            
+            commit = main.ONOSbench.getVersion()
+            commit = (commit.split(" "))[1]
+
+            resultsDB = open("flowTP1gDB", "w+")
+            resultsDB.close()
+
+        # -- END OF INIT SECTION --#
+
+        clusterCount = int(scale[0])
+        scale.remove(scale[0])
+        main.log.info("CLUSTER COUNT: " + str(clusterCount))
+
+        MN1Ip = ONOSIp[len(ONOSIp)-1]
+        BENCHIp = ONOSIp[len(ONOSIp)-2]
+
+        #kill off all onos processes 
+        main.log.step("Safety check, killing all ONOS processes")
+        main.log.step("before initiating enviornment setup")
+        for node in range(1, maxNodes + 1):
+            main.ONOSbench.onosDie(ONOSIp[node])
+
+        #Uninstall everywhere
+        main.log.step( "Cleaning Enviornment..." )
+        for i in range(1, maxNodes + 1):
+            main.log.info(" Uninstalling ONOS " + str(i) )
+            main.ONOSbench.onosUninstall( ONOSIp[i] )
+
+        #construct the cell file
+        main.log.info("Creating cell file")
+        cellIp = []
+        for node in range (1, clusterCount + 1):
+            cellIp.append(ONOSIp[node])        
+        
+        main.ONOSbench.createCellFile(BENCHIp,cellName,MN1Ip,str(Apps), *cellIp)
+        main.log.info("Cell Ip list: " + str(cellIp))
+        
+        main.step( "Set Cell" )
+        main.ONOSbench.setCell(cellName)       
+ 
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.onosPackage()  
+
+        main.step( "verify cells" )
+        verifyCellResult = main.ONOSbench.verifyCell()
+
+        main.log.report( "Initializeing " + str( clusterCount ) + " node cluster." )
+        for node in range(1, clusterCount + 1):
+            main.log.info("Starting ONOS " + str(node) + " at IP: " + ONOSIp[node])
+            main.ONOSbench.onosInstall( ONOSIp[node])
+
+        for node in range(1, clusterCount + 1):
+            for i in range( 2 ):
+                isup = main.ONOSbench.isup( ONOSIp[node] )
+                if isup:
+                    main.log.info("ONOS " + str(node) + " is up\n")
+                    break
+            if not isup:
+                main.log.report( "ONOS " + str(node) + " didn't start!" )
+        
+        for node in range(1, clusterCount + 1):
+            exec "a = main.ONOS%scli.startOnosCli" %str(node)
+            a(ONOSIp[node])
+         
+        main.log.info("Startup sequence complete")
+        main.ONOSbench.onosErrorLog(ONOSIp[1])
+        
+    def CASE2( self, main ):
+        #
+        # This is the flow TP test 
+        #
+        import os.path  
+        import numpy       
+        import math
+        import time 
+        import datetime
+        import traceback
+
+        global currentNeighbors
+        try:
+            currentNeighbors
+        except:
+            currentNeighbors = (main.params[ 'TEST' ][ 'neighbors' ]).split(",")[0]
+        else:
+            if currentNeighbors == "r":      #reset
+                currentNeighbors = "0"
+            else:
+                currentNeighbors = "a"
+
+        testCMD = [ 0,0,0,0 ]
+        warmUp = int(main.params[ 'TEST' ][ 'warmUp' ])
+        sampleSize = int(main.params[ 'TEST' ][ 'sampleSize' ])
+        switches = int(main.params[ 'TEST' ][ 'switches' ])
+        neighborList = (main.params[ 'TEST' ][ 'neighbors' ]).split(",")
+        testCMD[0] = main.params[ 'TEST' ][ 'testCMD0' ]
+        testCMD[1] = main.params[ 'TEST' ][ 'testCMD1' ]
+        maxNodes = main.params[ 'availableNodes' ]
+        onBaremetal = main.params['isOnBaremetal']
+        cooldown = main.params[ 'TEST' ][ 'cooldown' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+        MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+        maxNodes = int(main.params[ 'availableNodes' ])
+        homeDir = os.path.expanduser('~')
+        flowRuleBackup = str(main.params[ 'TEST' ][ 'enableFlowRuleStoreBackup' ])
+        main.log.info("Flow Rule Backup is set to:" + flowRuleBackup)
+
+        servers = str(clusterCount) 
+        
+        if clusterCount == 1: 
+            neighborList = ['0']
+            currentNeighbors = "r"
+        else:
+            if currentNeighbors == "a":
+                neighborList = [str(clusterCount-1)]
+                currentNeighbors = "r"
+            else:
+                neighborList = ['0'] 
+
+        main.log.info("neightborlist: " + str(neighborList))
+
+        ts = time.time()
+        st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
+
+        #write file to change mem limit to 32 gigs (BAREMETAL ONLY!)
+        if onBaremetal == "true":
+            filename = "/onos/tools/package/bin/onos-service"
+            serviceConfig = open(homeDir + filename, 'w+')
+            serviceConfig.write("#!/bin/bash\n ")
+            serviceConfig.write("#------------------------------------- \n ")
+            serviceConfig.write("# Starts ONOS Apache Karaf container\n ")
+            serviceConfig.write("#------------------------------------- \n ")
+            serviceConfig.write("#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n ")
+            serviceConfig.write("""export JAVA_OPTS="${JAVA_OPTS:--Xms8G -Xmx8G}" \n """)
+            serviceConfig.write("")
+            serviceConfig.write("ONOS_HOME=/opt/onos \n ")
+            serviceConfig.write("")
+            serviceConfig.write("[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n")
+            serviceConfig.write("""${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """)
+            serviceConfig.close()
+
+        for n in neighborList:
+            main.log.step("\tSTARTING TEST")
+            main.log.step("\tLOADING FROM SERVERS:  \t" + str(clusterCount) ) 
+            main.log.step("\tNEIGHBORS:\t" + n )  
+            main.log.info("=============================================================")
+            main.log.info("=============================================================")
+            #write file to configure nil link
+            ipCSV = ""
+            for i in range (1, int(maxNodes) + 1):
+                tempstr = "ip" + str(i)
+                ipCSV += main.params[ 'CTRL' ][ tempstr ] 
+                if i < int(maxNodes):
+                    ipCSV +=","
+            
+            for i in range(3):
+                main.ONOSbench.onosCfgSet(ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "deviceCount 35")
+                main.ONOSbench.onosCfgSet(ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "topoShape linear")
+                main.ONOSbench.onosCfgSet(ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "enabled true") 
+
+                time.sleep(5)
+                main.ONOSbench.handle.sendline("onos $OC1 summary")
+                main.ONOSbench.handle.expect(":~")
+                check = main.ONOSbench.handle.before
+                main.log.info("\nStart up check: \n" + check + "\n") 
+                if "SCC(s)=1," in check: 
+                    break 
+                time.sleep(5)
+                
+            #devide flows
+            flows = int(main.params[ 'TEST' ][ 'flows' ])
+            main.log.info("Flow Target  = " + str(flows))
+
+            flows = (flows *max(int(n)+1,int(servers)))/((int(n) + 1)*int(servers)*(switches))
+
+            main.log.info("Flows per switch = " + str(flows))
+
+            #build list of servers in "$OC1, $OC2...." format
+            serverEnvVars = ""
+            for i in range (1,int(servers)+1):
+                serverEnvVars += ("-s " + ONOSIp[i] + " ")
+            
+            data = [[""]*int(servers)]*int(sampleSize)
+            maxes = [""]*int(sampleSize)
+
+            flowCMD = "python3 " + homeDir + "/onos/tools/test/bin/"
+            flowCMD += testCMD[0] + " " + str(flows) + " " + testCMD[1]
+            flowCMD += " " + str(n) + " " + str(serverEnvVars) + "-j" 
+
+            main.log.info(flowCMD)
+            #time.sleep(60)
+            
+            for test in range(0, warmUp + sampleSize): 
+                if test < warmUp: 
+                    main.log.info("Warm up " + str(test + 1) + " of " + str(warmUp))
+                else: 
+                     main.log.info("====== Test run: " + str(test-warmUp+1) + " ======") 
+
+                main.ONOSbench.handle.sendline(flowCMD)
+                main.ONOSbench.handle.expect(":~")
+                rawResult = main.ONOSbench.handle.before
+                main.log.info("Raw results: \n" + rawResult + "\n")
+
+                if "failed" in rawResult: 
+                    main.log.report("FLOW_TESTER.PY FAILURE")
+                    main.log.report( " \n" + rawResult + " \n")
+                    for i in range(clusterCount):
+                        main.log.report("=======================================================")
+                        main.log.report(" ONOS " + str(i) + "LOG REPORT") 
+                        main.ONOSbench.logReport(ONOSIp[i], ["ERROR", "WARNING", "EXCEPT"], outputMode="d")
+                    main.ONOSbench.handle.sendline("onos $OC1 flows") 
+                    main.ONOSbench.handle.expect(":~") 
+                    main.log.info(main.ONOSbench.handle.before)
+
+                    break
+            
+            ########################################################################################
+                result = [""]*(clusterCount)
+        
+                #print("rawResult: " + rawResult)
+
+                rawResult = rawResult.splitlines()
+
+                for node in range(1, clusterCount + 1):        
+                    for line in rawResult:
+                        #print("line: " + line) 
+                        if ONOSIp[node] in line and "server" in line:
+                            temp = line.split(" ") 
+                            for word in temp:
+                                #print ("word: " + word) 
+                                if "elapsed" in repr(word): 
+                                    index = temp.index(word) + 1
+                                    myParsed = (temp[index]).replace(",","")
+                                    myParsed = myParsed.replace("}","")
+                                    myParsed = int(myParsed)
+                                    result[node-1] = myParsed
+                                    main.log.info( ONOSIp[node] + " : " + str(myParsed))
+                                    break 
+
+                if test >= warmUp:
+                    for i in result: 
+                        if i == "": 
+                            main.log.error("Missing data point, critical failure incoming")
+
+                    print result
+                    maxes[test-warmUp] = max(result)
+                    main.log.info("Data collection iteration: " + str(test-warmUp) + " of " + str(sampleSize))
+                    main.log.info("Throughput time: " + str(maxes[test-warmUp]) + "(ms)")                
+
+                    data[test-warmUp] = result
+
+                # wait for flows = 0 
+                for checkCount in range(0,5): 
+                    time.sleep(10)
+                    main.ONOSbench.handle.sendline("onos $OC1 summary")
+                    main.ONOSbench.handle.expect(":~")
+                    flowCheck = main.ONOSbench.handle.before
+                    if "flows=0," in flowCheck: 
+                        main.log.info("Flows removed")
+                        break
+                    else: 
+                        for line in flowCheck.splitlines(): 
+                            if "flows=" in line: 
+                                main.log.info("Current Summary: " + line) 
+                    if checkCount == 2: 
+                        main.log.info("Flows are stuck, moving on ")
+
+
+                time.sleep(5)
+                
+            main.log.info("raw data: " + str(data))
+            main.log.info("maxes:" + str(maxes))
+
+            
+            # report data
+            print("")
+            main.log.info("\t Results (measurments are in milliseconds)")
+            print("")
+
+            nodeString = ""
+            for i in range(1, int(servers) + 1):
+                nodeString += ("\tNode " + str(i)) 
+             
+            for test in range(0, sampleSize ):
+                main.log.info("\t Test iteration " + str(test + 1) )
+                main.log.info("\t------------------")
+                main.log.info(nodeString)       
+                resultString = ""
+
+                for i in range(0, int(servers) ):
+                    resultString += ("\t" + str(data[test][i]) ) 
+                main.log.info(resultString)
+
+                print("\n")
+
+            avgOfMaxes = numpy.mean(maxes)
+            main.log.info("Average of max value from each test iteration: " + str(avgOfMaxes))
+
+            stdOfMaxes = numpy.std(maxes)
+            main.log.info("Standard Deviation of max values: " + str(stdOfMaxes))       
+            print("\n\n")
+
+            avgTP = int(main.params[ 'TEST' ][ 'flows' ])  / avgOfMaxes #result in kflows/second
+            
+            tp = []
+            for i in maxes: 
+                tp.append((int(main.params[ 'TEST' ][ 'flows' ]) / i ))
+
+            stdTP = numpy.std(tp)
+
+            main.log.info("Average thoughput:  " + str(avgTP) + " Kflows/second" )
+            main.log.info("Standard deviation of throughput: " + str(stdTP) + " Kflows/second") 
+
+            resultsLog = open("flowTP1gDB","a")
+            resultString = ("'" + commit + "',")
+            resultString += ("'1gig',")
+            resultString += ((main.params[ 'TEST' ][ 'flows' ]) + ",")
+            resultString += (str(clusterCount) + ",")
+            resultString += (str(n) + ",")
+            resultString += (str(avgTP) + "," + str(stdTP) + "\n")
+            resultsLog.write(resultString) 
+            resultsLog.close()
+            
+            main.log.report("Result line to file: " + resultString)
+           
+        main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"], outputMode="d") 
diff --git a/TestON/tests/SCPFflowTp1g/SCPFflowTp1g.topo b/TestON/tests/SCPFflowTp1g/SCPFflowTp1g.topo
new file mode 100644
index 0000000..d82f3fd
--- /dev/null
+++ b/TestON/tests/SCPFflowTp1g/SCPFflowTp1g.topo
@@ -0,0 +1,144 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>OCN</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS><home>~/onos</home></COMPONENTS>
+        </ONOSbench>
+
+        <ONOS1cli>
+            <host>OCN</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1cli>
+
+        <ONOS2cli>
+            <host>OCN</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2cli>
+
+        <ONOS3cli>
+            <host>OCN</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3cli>
+
+        <ONOS4cli>
+            <host>OCN</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4cli>
+
+        <ONOS5cli>
+            <host>OCN</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5cli>
+
+        <ONOS6cli>
+            <host>OCN</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6cli>
+
+        <ONOS7cli>
+            <host>OCN</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>8</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS7cli>
+
+        <ONOS1>
+            <host>OC1</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>9</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1>
+
+        <ONOS2>
+            <host>OC2</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>10</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2>
+
+        <ONOS3>
+            <host>OC3</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>11</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3>
+
+        <ONOS4>
+            <host>OC4</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>12</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4>
+
+    
+        <ONOS5>
+            <host>OC5</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>13</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5>
+
+        <ONOS6>
+            <host>OC6</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>14</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6>
+
+        <ONOS7>
+            <host>OC7</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>15</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS7>
+
+    </COMPONENT>
+
+</TOPOLOGY>
+ 
diff --git a/TestON/tests/SCPFflowTp1g/__init__.py b/TestON/tests/SCPFflowTp1g/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPFflowTp1g/__init__.py
diff --git a/TestON/tests/SCPFintentRerouteLat/SCPFintentRerouteLat.params b/TestON/tests/SCPFintentRerouteLat/SCPFintentRerouteLat.params
new file mode 100644
index 0000000..2e43679
--- /dev/null
+++ b/TestON/tests/SCPFintentRerouteLat/SCPFintentRerouteLat.params
@@ -0,0 +1,79 @@
+<PARAMS>
+
+    <testcases>1,2,1,2,1,2,1,2</testcases>
+
+    <SCALE>1,3,5,7</SCALE>
+    <availableNodes>7</availableNodes>
+ 
+    <ENV>
+        <cellName>intentRerouteCell</cellName>
+        <cellApps>drivers,null,intentperf,metrics</cellApps>
+    </ENV>
+
+    <TEST>
+        <skipCleanInstall>yes</skipCleanInstall>
+        <warmUp>5</warmUp>
+        <sampleSize>20</sampleSize>                     
+        <wait></wait>
+        <intents>1,100,1000</intents>                       #list format, will be split on ','
+        <debug>True</debug>     
+       
+        <s1>1,1,1,1,1,1,1,1</s1>
+        <s3>2,2,1,1,3,3,3,1</s3>
+        <s5>2,2,1,1,3,4,5,3</s5>
+        <s7>2,3,1,1,5,6,7,4</s7>
+
+    </TEST>
+
+    <METRICS>
+        <Submitted>0</Submitted>
+        <Installed>1</Installed>
+        <Failed>0</Failed>
+        <Withdraw>0</Withdraw>
+        <Withdrawn>0</Withdrawn>
+    </METRICS>
+
+    <GIT>
+        <autopull>off</autopull>
+        <checkout>master</checkout>
+    </GIT>
+
+    <CTRL>
+        <USER>admin</USER>
+        
+        <ip1>OC1</ip1>
+        <port1>6633</port1>
+        
+        <ip2>OC2</ip2>
+        <port2>6633</port2>
+        
+        <ip3>OC3</ip3>
+        <port3>6633</port3>
+        
+        <ip4>OC4</ip4>
+        <port4>6633</port4>
+        
+        <ip5>OC5</ip5>
+        <port5>6633</port5>
+        
+        <ip6>OC6</ip6>
+        <port6>6633</port6> 
+       
+        <ip7>OC7</ip7>
+        <port7>6633</port7>
+
+    </CTRL>
+
+    <MN>
+        <ip1>OCN</ip1>
+    </MN>
+
+    <BENCH>
+        <user>admin</user>
+        <ip1>OCN</ip1>
+    </BENCH>
+
+    <JSON>
+    </JSON>
+
+</PARAMS>
diff --git a/TestON/tests/SCPFintentRerouteLat/SCPFintentRerouteLat.py b/TestON/tests/SCPFintentRerouteLat/SCPFintentRerouteLat.py
new file mode 100644
index 0000000..cc8892e
--- /dev/null
+++ b/TestON/tests/SCPFintentRerouteLat/SCPFintentRerouteLat.py
@@ -0,0 +1,412 @@
+# ScaleOutTemplate
+#
+# CASE1 starts number of nodes specified in param file
+#
+# cameron@onlab.us
+
+import sys
+import os.path
+
+
+class SCPFintentRerouteLat:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):
+
+        import time
+
+        global init
+        try:
+            if type(init) is not bool:
+                init = False
+        except NameError:
+            init = False
+
+        #Load values from params file
+        checkoutBranch = main.params[ 'GIT' ][ 'checkout' ]
+        gitPull = main.params[ 'GIT' ][ 'autopull' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        Apps = main.params[ 'ENV' ][ 'cellApps' ]
+        BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+        maxNodes = int(main.params[ 'availableNodes' ])
+        skipMvn = main.params[ 'TEST' ][ 'skipCleanInstall' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+
+        # -- INIT SECTION, ONLY RUNS ONCE -- # 
+        if init == False: 
+            init = True
+            global clusterCount             #number of nodes running
+            global ONOSIp                   #list of ONOS IP addresses
+            global scale 
+            global commit
+
+            clusterCount = 0
+            ONOSIp = [ 0 ]
+            scale = (main.params[ 'SCALE' ]).split(",")            
+            clusterCount = int(scale[0])
+
+            #Populate ONOSIp with ips from params 
+            ONOSIp = [0]
+            ONOSIp.extend(main.ONOSbench.getOnosIps())
+
+            print("-----------------" + str(ONOSIp))
+            #mvn clean install, for debugging set param 'skipCleanInstall' to yes to speed up test
+            if skipMvn != "yes":
+                mvnResult = main.ONOSbench.cleanInstall()
+
+            #git
+            main.step( "Git checkout and pull " + checkoutBranch )
+            if gitPull == 'on':
+                checkoutResult = main.ONOSbench.gitCheckout( checkoutBranch )
+                pullResult = main.ONOSbench.gitPull()
+
+            else:
+                checkoutResult = main.TRUE
+                pullResult = main.TRUE
+                main.log.info( "Skipped git checkout and pull" )
+            
+            commit = main.ONOSbench.getVersion()
+            commit = (commit.split(" "))[1]
+
+            resultsDB = open("IntentRerouteLatDB", "w+")
+            resultsDB.close()
+
+        # -- END OF INIT SECTION --#
+         
+        clusterCount = int(scale[0])
+        scale.remove(scale[0])       
+      
+        MN1Ip = ONOSIp[len(ONOSIp)-1]
+        BENCHIp = ONOSIp[len(ONOSIp)-2]
+
+        #kill off all onos processes 
+        main.log.step("Safety check, killing all ONOS processes")
+        main.log.step("before initiating enviornment setup")
+        for node in range(1, maxNodes + 1):
+            main.ONOSbench.onosDie(ONOSIp[node])
+        
+        #Uninstall everywhere
+        main.log.step( "Cleaning Enviornment..." )
+        for i in range(1, maxNodes + 1):
+            main.log.info(" Uninstalling ONOS " + str(i) )
+            main.ONOSbench.onosUninstall( ONOSIp[i] )
+       
+        #construct the cell file
+        main.log.info("Creating cell file")
+        cellIp = []
+        for node in range (1, clusterCount + 1):
+            cellIp.append(ONOSIp[node])
+        
+        main.ONOSbench.createCellFile(BENCHIp,cellName,MN1Ip,str(Apps), *cellIp)
+
+        main.step( "Set Cell" )
+        main.ONOSbench.setCell(cellName)
+        
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.onosPackage()  
+
+        main.step( "verify cells" )
+        verifyCellResult = main.ONOSbench.verifyCell()
+      
+        main.log.report( "Initializing " + str( clusterCount ) + " node cluster." )
+        for node in range(1, clusterCount + 1):
+            main.log.info("Starting ONOS " + str(node) + " at IP: " + ONOSIp[node])
+            main.ONOSbench.onosInstall( ONOSIp[node])
+
+        for node in range(1, clusterCount + 1):
+            for i in range( 2 ):
+                isup = main.ONOSbench.isup( ONOSIp[node] )
+                if isup:
+                    main.log.info("ONOS " + str(node) + " is up\n")
+                    break
+            if not isup:
+                main.log.report( "ONOS " + str(node) + " didn't start!" )
+        main.log.info("Startup sequence complete")
+    
+        deviceMastership = (main.params[ 'TEST' ][ "s" + str(clusterCount) ]).split(",")
+        print("Device mastership list: " + str(deviceMastership))
+
+        main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.store.flow.impl.NewDistributedFlowRuleStore", "backupEnabled false")
+
+        main.log.step("Setting up null provider")
+        for i in range(3):
+            main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "deviceCount 8")
+            main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "topoShape reroute")
+            main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "enabled true")
+            time.sleep(5)
+            main.ONOSbench.handle.sendline("onos $OC1 summary")
+            main.ONOSbench.handle.expect(":~")
+            x = main.ONOSbench.handle.before
+            if "devices=8" in x and "links=16," in x:
+                break
+
+        index = 1
+        for node in deviceMastership:
+            for attempt in range(0,10):
+                cmd = ( "onos $OC" + node + """ "device-role null:000000000000000""" + str(index) + " " + ONOSIp[int(node)]  + """ master" """)
+                main.log.info("assigning mastership of device " + str(index) + " to node " + node + ": \n " + cmd + "\n")
+                main.ONOSbench.handle.sendline(cmd)
+                main.ONOSbench.handle.expect(":~")
+                time.sleep(4)
+                
+                cmd = ( "onos $OC" + node + " roles|grep 00000" + str(index)) 
+                main.log.info(cmd) 
+                main.ONOSbench.handle.sendline(cmd)
+                main.ONOSbench.handle.expect(":~")
+                check = main.ONOSbench.handle.before
+                main.log.info("CHECK:\n" + check)
+                if ("master=" + ONOSIp[int(node)]) in check:
+                    break
+            index += 1
+
+        main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"])
+
+    def CASE2( self, main ):
+         
+        import time
+        import numpy
+        import datetime
+        #from scipy import stats
+
+        ts = time.time()
+        date = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d')
+
+        sampleSize = int(main.params[ 'TEST' ][ 'sampleSize' ])
+        warmUp = int(main.params[ 'TEST' ][ 'warmUp' ])
+        intentsList = (main.params[ 'TEST' ][ 'intents' ]).split(",")
+        debug = main.params[ 'TEST' ][ 'debug' ]
+        for i in range(0,len(intentsList)):
+            intentsList[i] = int(intentsList[i])
+
+        timestampMetrics = []
+        if main.params['METRICS']['Submitted'] == "1":
+            timestampMetrics.append("Submitted")
+        if main.params['METRICS']['Installed'] == "1":
+            timestampMetrics.append("Installed")
+        if main.params['METRICS']['Failed'] == "1":
+            timestampMetrics.append("Failed")
+        if main.params['METRICS']['Withdraw'] == "1":
+            timestampMetrics.append("Withdraw")
+        if main.params['METRICS']['Withdrawn'] == "1":
+            timestampMetrics.append("Withdrawn")
+        if debug: main.log.info(timestampMetrics)
+
+        if debug == "True":
+            debug = True
+        else:
+            debug = False
+
+        ingress = "null:0000000000000001"
+        egress = "null:0000000000000007"
+
+        for intents in intentsList:
+            main.log.report("Intent Batch size: " + str(intents) + "\n      ")
+            myResult = [["latency", "lastNode"] for x in range(sampleSize)]
+
+            for run in range(0, (warmUp + sampleSize)):
+                if run > warmUp:
+                    main.log.info("Starting test iteration " + str(run-warmUp))
+
+                cmd = """onos $OC1 "push-test-intents -i """
+                cmd += ingress + "/0 "
+                cmd += egress + "/0 "
+                cmd += str(intents) +""" 1" """
+                if debug: main.log.info(cmd)
+
+                withdrawCmd = cmd.replace("intents -i", "intents -w ")
+
+                #push-test-intents
+                main.ONOSbench.handle.sendline(cmd)
+                main.ONOSbench.handle.expect(":~")
+                myRawResult = main.ONOSbench.handle.before
+
+                for i in range(0, 40):
+                    main.ONOSbench.handle.sendline("onos $OC1 summary")
+                    main.ONOSbench.handle.expect(":~")
+                    linkCheck = main.ONOSbench.handle.before
+                    if ("links=16,") in linkCheck and ("flows=" + str(intents*7) + ","):
+                        break
+                    if i == 39:
+                        main.log.error("Flow/link count incorrect, data invalid."+ linkCheck)
+                        main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"], "d")
+                        #main.ONOSbench.logReport(ONOSIp[(clusterCount-1)], ["ERROR", "WARNING", "EXCEPT"], "d")
+                        main.ONOSbench.sendline("onos $OC1 summary")
+                        main.ONOSbench.sendline("onos $OC1 devices")
+                        main.ONOSbench.sendline("onos $OC1 links") 
+                        main.ONOSbench.expect(":~")
+                        main.log.info(main.ONOSbench.before)
+
+                #collect timestamp from link cut
+                cmd = """onos $OC1 null-link "null:0000000000000004/1 null:0000000000000003/2 down" """
+                if debug: main.log.info("COMMAND: " + str(cmd))
+                main.ONOSbench.handle.sendline(cmd)
+                main.ONOSbench.handle.expect(":~")
+
+                cmd = "onos-ssh $OC1 cat /opt/onos/log/karaf.log | grep TopologyManager| tail -1"
+                for i in range(0,10):
+                    main.ONOSbench.handle.sendline(cmd)
+                    time.sleep(2)
+                    main.ONOSbench.handle.expect(":~")
+                    raw = main.ONOSbench.handle.before
+                    #if "NullLinkProvider" in raw and "links=14" in raw:
+                    if "links=14" in raw:
+                        break
+                    if i >= 9:
+                        main.log.error("Expected output not being recieved... continuing")
+                        main.log.info(raw)
+                        break
+                    time.sleep(2)
+
+                temp = raw.splitlines()
+                for line in temp:
+                    if str(date) in line:
+                        temp = line
+                        break
+
+                cutTimestamp = (temp.split(" "))[0] + " " + (temp.split(" "))[1]
+                if debug: main.log.info("Cut timestamp: " + cutTimestamp) 
+
+                #validate link count and flow count
+                for i in range(0, 40):
+                    main.ONOSbench.handle.sendline("onos $OC1 summary")
+                    main.ONOSbench.handle.expect(":~")
+                    linkCheck = main.ONOSbench.handle.before
+                    #if "links=" + str(7*intents)+ "," in linkCheck and ("flows=" + str(7*intents) + ",") in linkCheck:
+                    if "links=14," in linkCheck and ("flows=" + str(8*intents) + ",") in linkCheck:
+                        break
+                    if i == 39:
+                        main.log.error("Link or flow count incorrect, data invalid." + linkCheck)
+                        main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"], "d")
+
+                time.sleep(5) #trying to avoid negative values 
+
+                #intents events metrics installed timestamp
+                IEMtimestamps = [0]*(clusterCount + 1)
+                installedTemp = [0]*(clusterCount + 1)
+                for node in range(1, clusterCount +1):
+                    cmd = "onos $OC" + str(node) + """ "intents-events-metrics"|grep Timestamp """
+                    raw = ""
+                    while "epoch)" not in raw:
+                        main.ONOSbench.handle.sendline(cmd)
+                        main.ONOSbench.handle.expect(":~")
+                        raw = main.ONOSbench.handle.before
+
+                    print(raw)
+
+                    intentsTimestamps = {}
+                    rawTimestamps = raw.splitlines()
+                    for line in rawTimestamps:
+                        if "Timestamp" in line and "grep" not in line:
+                            metricKey = (line.split(" "))[1]
+                            metricTimestamp = (line.split(" ")[len(line.split(" ")) -1]).replace("epoch)=","")
+                            metricTimestamp = float(metricTimestamp)
+                            metricTimestamp = numpy.divide(metricTimestamp, 1000)
+                            if debug: main.log.info(repr(metricTimestamp))
+                            intentsTimestamps[metricKey] = metricTimestamp
+                            if metricKey == "Installed":
+                                installedTemp[node] = metricTimestamp
+
+                    main.log.info("Node: " + str(node) + " Timestamps: " + str(intentsTimestamps))
+                    IEMtimestamps[node] = intentsTimestamps
+
+                myMax = max(installedTemp)
+                indexOfMax = installedTemp.index(myMax)
+
+                #number crunch
+                for metric in timestampMetrics:     #this is where we sould add support for computing other timestamp metrics
+                    if metric == "Installed":
+                        if run >= warmUp:
+                            main.log.report("link cut timestamp: " + cutTimestamp)
+                            #readableInstalledTimestamp = str(intentsTimestamps["Installed"])
+                            readableInstalledTimestamp = str(myMax)
+
+                            #main.log.report("Intent Installed timestamp: " + str(intentsTimestamps["Installed"]))
+                            main.log.report("Intent Installed timestamp: " + str(myMax))
+
+                            cutEpoch = time.mktime(time.strptime(cutTimestamp, "%Y-%m-%d %H:%M:%S,%f"))
+                            if debug: main.log.info("cutEpoch=" + str(cutEpoch))
+                            #rerouteLatency = float(intentsTimestamps["Installed"] - cutEpoch)
+                            rerouteLatency = float(myMax - cutEpoch)
+
+                            rerouteLatency = numpy.divide(rerouteLatency, 1000)
+                            main.log.report("Reroute latency:" + str(rerouteLatency) + " (seconds)\n    ")
+                            myResult[run-warmUp][0] = rerouteLatency
+                            myResult[run-warmUp][1] = indexOfMax
+                            if debug: main.log.info("Latency: " + str(myResult[run-warmUp][0]))
+                            if debug: main.log.info("last node: " + str(myResult[run-warmUp][1]))
+
+                cmd = """ onos $OC1 null-link "null:0000000000000004/1 null:0000000000000003/2 up" """
+                if debug: main.log.info(cmd)
+                main.ONOSbench.handle.sendline(cmd)
+                main.ONOSbench.handle.expect(":~")
+                
+                
+                
+                #wait for intent withdraw
+                main.ONOSbench.handle.sendline(withdrawCmd)
+                main.log.info(withdrawCmd) 
+                main.ONOSbench.handle.expect(":~")
+                if debug: main.log.info(main.ONOSbench.handle.before) 
+                main.ONOSbench.handle.sendline("onos $OC1 intents|grep WITHDRAWN|wc -l")
+                main.ONOSbench.handle.expect(":~")
+                intentWithdrawCheck = main.ONOSbench.handle.before
+                if (str(intents)) in intentWithdrawCheck:
+                    main.log.info("intents withdrawn")
+                if debug: main.log.info(intentWithdrawCheck)
+
+                # wait for links to be reestablished
+                for i in range(0, 10):
+                    main.ONOSbench.handle.sendline("onos $OC1 summary")
+                    main.ONOSbench.handle.expect(":~")
+                    linkCheck = main.ONOSbench.handle.before
+                    if "links=16," in linkCheck:
+                        break
+                    time.sleep(1)
+                    if i == 9:
+                        main.log.info("Links Failed to reconnect, next iteration of data invalid." + linkCheck)
+
+                if run < warmUp:
+                    main.log.info("Warm up run " + str(run+1) + " completed")
+
+            if debug: main.log.info(myResult)
+            latTemp = []
+            nodeTemp = []
+            for i in myResult:
+                latTemp.append(i[0])
+                nodeTemp.append(i[1])
+                 
+            mode = {}
+            for i in nodeTemp:
+                if i in mode:
+                    mode[i] += 1
+                else:
+                    mode[i] = 1
+
+            for i in mode.keys():
+                if mode[i] == max(mode.values()):
+                    nodeMode = i
+
+            average = numpy.average(latTemp)
+            stdDev = numpy.std(latTemp)
+
+            average = numpy.multiply(average, 1000)
+            stdDev = numpy.multiply(stdDev, 1000)
+
+            main.log.report("Scale: " + str(clusterCount) + "  \tIntent batch: " + str(intents))
+            main.log.report("Latency average:................" + str(average))
+            main.log.report("Latency standard deviation:....." + str(stdDev))
+            main.log.report("Mode of last node to respond:..." + str(nodeMode))
+            main.log.report("________________________________________________________")
+
+            resultsDB = open("IntentRerouteLatDB", "a")
+            resultsDB.write("'" + commit + "',") 
+            resultsDB.write(str(clusterCount) + ",")
+            resultsDB.write(str(intents) + ",")
+            resultsDB.write(str(average) + ",")
+            resultsDB.write(str(stdDev) + "\n")
+            resultsDB.close()
+
+            main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"])
+
diff --git a/TestON/tests/SCPFintentRerouteLat/SCPFintentRerouteLat.topo b/TestON/tests/SCPFintentRerouteLat/SCPFintentRerouteLat.topo
new file mode 100644
index 0000000..d82f3fd
--- /dev/null
+++ b/TestON/tests/SCPFintentRerouteLat/SCPFintentRerouteLat.topo
@@ -0,0 +1,144 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>OCN</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS><home>~/onos</home></COMPONENTS>
+        </ONOSbench>
+
+        <ONOS1cli>
+            <host>OCN</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1cli>
+
+        <ONOS2cli>
+            <host>OCN</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2cli>
+
+        <ONOS3cli>
+            <host>OCN</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3cli>
+
+        <ONOS4cli>
+            <host>OCN</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4cli>
+
+        <ONOS5cli>
+            <host>OCN</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5cli>
+
+        <ONOS6cli>
+            <host>OCN</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6cli>
+
+        <ONOS7cli>
+            <host>OCN</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>8</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS7cli>
+
+        <ONOS1>
+            <host>OC1</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>9</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1>
+
+        <ONOS2>
+            <host>OC2</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>10</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2>
+
+        <ONOS3>
+            <host>OC3</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>11</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3>
+
+        <ONOS4>
+            <host>OC4</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>12</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4>
+
+    
+        <ONOS5>
+            <host>OC5</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>13</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5>
+
+        <ONOS6>
+            <host>OC6</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>14</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6>
+
+        <ONOS7>
+            <host>OC7</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>15</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS7>
+
+    </COMPONENT>
+
+</TOPOLOGY>
+ 
diff --git a/TestON/tests/SCPFintentRerouteLat/__init__.py b/TestON/tests/SCPFintentRerouteLat/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPFintentRerouteLat/__init__.py