Creating subfolders for test suites

allow teston to look in subfolders
create subfolders for current test suites
move tests into sub folders
create HA suite dependencies folder and moved all common files there
minor driver and test updates
standardize on the name dependencies for the directory
change from admin to sdn users

Conflicts:
	TestON/tests/FUNC/FUNCipv6Intent/FUNCipv6Intent.topo

Change-Id: I849e45ab67da8b285c36c5fdf43b34323876e741
diff --git a/TestON/tests/SCPF/SCPFcbench/README b/TestON/tests/SCPF/SCPFcbench/README
new file mode 100644
index 0000000..c689cf3
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFcbench/README
@@ -0,0 +1,4 @@
+Summary: This is a performance test suite to test onos single instance with Cbench TP mode.
+Pre-requisites: OC1 - is the single onos cell also has cbench pre-installed for all users; 
+                this env variable is required on the TestStation. Passwordless login is set
+                from TestStation "sdn" root user.
diff --git a/TestON/tests/SCPF/SCPFcbench/SCPFcbench.params b/TestON/tests/SCPF/SCPFcbench/SCPFcbench.params
new file mode 100644
index 0000000..d862129
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFcbench/SCPFcbench.params
@@ -0,0 +1,46 @@
+<PARAMS>
+
+    <testcases>1,2</testcases>
+
+    <SCALE>1</SCALE>
+    <availableNodes>1</availableNodes>
+
+    <ENV>
+    <cellName>Cbenchcell</cellName>
+    <cellApps>drivers,openflow-base,fwd</cellApps>
+    </ENV>
+
+    <TEST>
+        <skipCleanInstall>yes</skipCleanInstall>
+        <cbenchCMD>cbench -c localhost -p 6653 -m 1000 -l 70 -s 16 -M 100000 -w 10 -D 5000 -</cbenchCMD>
+        <mode>t</mode>                     #t throughput
+    </TEST>
+
+    <GIT>
+        <autopull>off</autopull>
+        <checkout>master</checkout>
+    </GIT>
+
+    <CTRL>
+        <USER>sdn</USER>
+        <ip1>OC1</ip1>
+        <port1>6653</port1>
+    </CTRL>
+
+    <MN>
+        <ip1>OC1</ip1>
+    </MN>
+
+    <BENCH>
+        <user>sdn</user>
+        <ip1>localhost</ip1>
+    </BENCH>
+
+    <CBENCH>
+        <user>sdn</user>
+    </CBENCH>
+
+    <JSON>
+    </JSON>
+
+</PARAMS>
diff --git a/TestON/tests/SCPF/SCPFcbench/SCPFcbench.py b/TestON/tests/SCPF/SCPFcbench/SCPFcbench.py
new file mode 100644
index 0000000..403e0fe
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFcbench/SCPFcbench.py
@@ -0,0 +1,221 @@
+# ScaleOutTemplate --> CbenchBM
+#
+# CASE1 starts number of nodes specified in param file
+#
+# cameron@onlab.us
+
+import sys
+import os
+import os.path
+
+
+class SCPFcbench:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):
+
+        import time
+        import os
+        global init
+        main.case("pre-condition for cbench test.")
+
+        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' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+        CBENCHuser = main.params[ 'CBENCH'][ 'user' ]
+        MN1Ip = os.environ[ main.params[ 'MN' ][ 'ip1' ] ]
+        maxNodes = int(main.params[ 'availableNodes' ])
+        skipMvn = main.params[ 'TEST' ][ 'skipCleanInstall' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        cellApps = main.params[ 'ENV' ][ 'cellApps' ]
+
+        # -- 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
+
+            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 = os.environ[main.params['CTRL']['ip1']]
+                ONOSIp.append(ipString)
+
+            #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" )
+
+        # -- END OF INIT SECTION --#
+
+        clusterCount = int(scale[0])
+        scale.remove(scale[0])
+
+        #kill off all onos processes
+        main.log.step("Safety check, killing all ONOS processes")
+        main.log.step("before initiating environment 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] )
+
+        time.sleep(10)
+        main.ONOSbench.handle.sendline(" ")
+        main.ONOSbench.handle.expect(":~")
+        print "pexpect: \n" + main.ONOSbench.handle.before
+
+
+        print "Cellname is: "+ cellName + "ONOS IP is: " + str(ONOSIp)
+        main.ONOSbench.createCellFile(BENCHIp,cellName,MN1Ip,cellApps,[ONOSIp[1]])
+
+        main.step( "Set Cell" )
+        main.ONOSbench.setCell(cellName)
+
+        #main.ONOSbench.handle.sendline(" ")
+        #main.ONOSbench.handle.expect(":~")
+        #print "pexpect: \n" + main.ONOSbench.handle.before
+
+        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")
+
+        for i in range(5):
+            main.ONOSbench.onosCfgSet(ONOSIp[1], "org.onosproject.fwd.ReactiveForwarding","packetOutOnly true")
+            time.sleep(5)
+            main.ONOSbench.handle.sendline("onos $OC1 cfg get|grep packetOutOnly")
+            main.ONOSbench.handle.expect(":~")
+            check = main.ONOSbench.handle.before
+            if "value=true" in check:
+                main.log.info("cfg set successful")
+                stepResult = main.TRUE
+                break
+            if i == 4:
+                main.log.info("Cfg set failed")
+                stepResult = main.FALSE
+            else:
+                time.sleep(5)
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully configure onos for cbench test ",
+                                 onfail="Failed to configure onos for cbench test" )
+
+
+
+
+    def CASE2( self, main ):
+        main.case("Running Cbench")
+        main.step("Issuing cbench commands and grab returned results")
+        validFlag = False
+        cbenchCMD = main.params[ 'TEST' ][ 'cbenchCMD' ]
+        mode = main.params[ 'TEST' ][ 'mode' ]
+        if mode != "t":
+            mode = " "
+
+        runCbench = ( "ssh " + CBENCHuser + "@" + ONOSIp[1] + " " + cbenchCMD + mode )
+        main.ONOSbench.handle.sendline(runCbench)
+        time.sleep(30)
+        main.ONOSbench.handle.expect(":~")
+        output = main.ONOSbench.handle.before
+        main.log.info(output)
+
+        output = output.splitlines()
+        for line in output:
+            if "RESULT: " in line:
+                validFlag = True
+                print line
+                resultLine = line.split(" ")
+                for word in resultLine:
+                    if word == "min/max/avg/stdev":
+                        resultsIndex = resultLine.index(word)
+                        print resultsIndex
+                        break
+
+                finalDataString = resultLine[resultsIndex + 2]
+                print finalDataString
+                finalDataList = finalDataString.split("/")
+                avg = finalDataList[2]
+                stdev = finalDataList[3]
+
+                main.log.info("Average: \t\t\t" + avg)
+                main.log.info("Standard Deviation: \t" + stdev)
+
+
+                commit = main.ONOSbench.getVersion()
+                commit = (commit.split(" "))[1]
+
+                try:
+                    dbFileName="/tmp/CbenchDB"
+                    dbfile = open(dbFileName, "w+")
+                    temp = "'" + commit + "',"
+                    temp += "'" + mode + "',"
+                    temp += "'" + avg + "',"
+                    temp += "'" + stdev + "'\n"
+                    dbfile.write(temp)
+                    dbfile.close()
+                    main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"], outputMode="d")
+                except IOError:
+                    main.log.warn("Error opening " + dbFileName + " to write results.")
+
+                stepResult = main.TRUE
+                break
+        if ( validFlag == False ):
+            main.log.warn("Cbench Test produced no valid results!!!!")
+            stepResult = main.FALSE
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully tested onos for cbench. ",
+                                 onfail="Failed to obtain valid onos cbench result!" )
+
+
+
+
+
+
diff --git a/TestON/tests/SCPF/SCPFcbench/SCPFcbench.topo b/TestON/tests/SCPF/SCPFcbench/SCPFcbench.topo
new file mode 100644
index 0000000..d4637ad
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFcbench/SCPFcbench.topo
@@ -0,0 +1,29 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+                <home>~/onos</home>
+                <nodes>1</nodes>
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOS1>
+            <host>OC1</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>9</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1>
+
+    </COMPONENT>
+
+</TOPOLOGY>
+ 
diff --git a/TestON/tests/SCPF/SCPFcbench/__init__.py b/TestON/tests/SCPF/SCPFcbench/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFcbench/__init__.py
diff --git a/TestON/tests/SCPF/SCPFflowTp1g/README b/TestON/tests/SCPF/SCPFflowTp1g/README
new file mode 100644
index 0000000..9d83fc3
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFflowTp1g/README
@@ -0,0 +1,31 @@
+FLOW THROUGHPUT
+
+Summary:
+        This is a performance test suite to test the flow throughput
+        capabilities of ONOS with various controller cluster sizes. This
+        This test uses the null-provider to simulate a network topology
+        and tests the throughput via a python script called flow-tester.py.
+
+Pre-requisites: To run out-of-the box this test requires 7 NODES.
+    OC1->OC7 must be set before initiating the test. Passwordless login
+    must be set from TestStation "sdn" root user.
+
+***If you wish to run this test with less than 7 nodes the following
+    alterations must be made:
+
+NOTE: Only scale sizes 1,3,5 and 7 will be functional
+
+Modifying .params file:
+-- Remove any values in the comma separated list in the
+    <scale> tag that are above your desired cluster size.
+
+-- Remove one instance of “1,2” from the <testcases>
+    tag for each value you removed from <scale> (case 1 and 2 are each
+    called once for each scale value)
+
+-- Change the value in the <max> tag to your desired scale size (1,3, or 5)
+
+Modifying .topo file:
+-- Change the <ONOSbench/COMPONENTS/nodes> tag to your desired scale size
+
+-- Remove all unneeded <ONOS#cli> tags and their contents
diff --git a/TestON/tests/SCPF/SCPFflowTp1g/SCPFflowTp1g.params b/TestON/tests/SCPF/SCPFflowTp1g/SCPFflowTp1g.params
new file mode 100644
index 0000000..fe10703
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFflowTp1g/SCPFflowTp1g.params
@@ -0,0 +1,72 @@
+<PARAMS>
+
+    <testcases>1,2,1,2,1,2,1,2,1,2,1,2,1,2</testcases>
+
+    <SCALE>1,3,3,5,5,7,7</SCALE>
+    <max>7</max>
+
+
+
+    <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>sdn</USER>
+
+        <ip1>OC1</ip1>
+        <port1>6653</port1>
+
+        <ip2>OC2</ip2>
+        <port2>6653</port2>
+
+        <ip3>OC3</ip3>
+        <port3>6653</port3>
+
+        <ip4>OC4</ip4>
+        <port4>6653</port4>
+
+        <ip5>OC5</ip5>
+        <port5>6653</port5>
+
+        <ip6>OC6</ip6>
+        <port6>6653</port6>
+
+        <ip7>OC7</ip7>
+        <port7>6653</port7>
+
+    </CTRL>
+
+    <MN>
+        <ip1>OCN</ip1>
+    </MN>
+
+    <BENCH>
+        <user>sdn</user>
+        <ip1>localhost</ip1>
+    </BENCH>
+
+    <JSON>
+    </JSON>
+
+</PARAMS>
diff --git a/TestON/tests/SCPF/SCPFflowTp1g/SCPFflowTp1g.py b/TestON/tests/SCPF/SCPFflowTp1g/SCPFflowTp1g.py
new file mode 100644
index 0000000..ddb9d7c
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFflowTp1g/SCPFflowTp1g.py
@@ -0,0 +1,383 @@
+# 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' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        main.maxNodes = int(main.params[ 'max' ])
+        skipMvn = main.params[ 'TEST' ][ 'skipCleanInstall' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+
+        main.log.info("==========DEBUG VERSION 3===========")
+
+        # -- 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, main.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("/tmp/flowTP1gDB", "w+")
+            resultsDB.close()
+
+        # -- END OF INIT SECTION --#
+
+        clusterCount = int(scale[0])
+        scale.remove(scale[0])
+        main.log.info("CLUSTER COUNT: " + str(clusterCount))
+
+        #kill off all onos processes
+        main.log.step("Safety check, killing all ONOS processes")
+        main.log.step("before initiating environment setup")
+        for node in range(1, main.maxNodes + 1):
+            main.ONOSbench.onosDie(ONOSIp[node])
+
+        #Uninstall everywhere
+        main.log.step( "Cleaning Enviornment..." )
+        for i in range(1, main.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,"localhost",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.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"], outputMode="d")
+    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' ]
+        main.maxNodes = main.params[ 'max' ]
+        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' ]
+        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')
+
+        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(main.maxNodes) + 1):
+                tempstr = "ip" + str(i)
+                ipCSV += main.params[ 'CTRL' ][ tempstr ]
+                if i < int(main.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:
+                    main.ONOSbench.handle.sendline( "onos $OC1 balance-masters" )
+                    main.ONOSbench.handle.expect( ":~" )
+                    time.sleep(5)
+                    main.ONOSbench.handle.sendline( "onos $OC1 roles ")
+                    main.ONOSbench.handle.expect ( ":~" )
+                    main.log.info( "switch masterships:" + str( main.ONOSbench.handle.before ) )
+                    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("/tmp/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/SCPF/SCPFflowTp1g/SCPFflowTp1g.topo b/TestON/tests/SCPF/SCPFflowTp1g/SCPFflowTp1g.topo
new file mode 100644
index 0000000..d521c3a
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFflowTp1g/SCPFflowTp1g.topo
@@ -0,0 +1,146 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+                <home>~/onos</home>
+                <nodes>7</nodes> 
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOS1cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1cli>
+
+        <ONOS2cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2cli>
+
+        <ONOS3cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3cli>
+
+        <ONOS4cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4cli>
+
+        <ONOS5cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5cli>
+
+        <ONOS6cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6cli>
+
+        <ONOS7cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</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/SCPF/SCPFflowTp1g/__init__.py b/TestON/tests/SCPF/SCPFflowTp1g/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFflowTp1g/__init__.py
diff --git a/TestON/tests/SCPF/SCPFhostLat/README b/TestON/tests/SCPF/SCPFhostLat/README
new file mode 100644
index 0000000..afeb8db
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFhostLat/README
@@ -0,0 +1,12 @@
+Host LATENCY
+
+Summary: This is a performance test suite to measure the time it takes ONOS
+        to recognize a host going up and down.
+
+Pre-requisites: To run out-of-the box this test requires 7 NODES.
+    OC1->OC7 must be set before initiating the test. Passwordless login
+    must be set from TestStation "sdn" root user. The 7 NODES must have
+    their clocks synced to TestStation via ptpd and be accurate to the
+    millisecond. You will also need the Wireshark disector to see openflow packets.
+
+NOTE: Only scale sizes 1,3,5 and 7 will be functional
diff --git a/TestON/tests/SCPF/SCPFhostLat/SCPFhostLat.params b/TestON/tests/SCPF/SCPFhostLat/SCPFhostLat.params
new file mode 100644
index 0000000..9bd9e6b
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFhostLat/SCPFhostLat.params
@@ -0,0 +1,52 @@
+<PARAMS>
+    <testcases>0,1,2,11,20,1,2,11,20,1,2,11,20,1,2,11,20</testcases>
+
+    <SCALE>1,3,5,7</SCALE>
+
+    <ENV>
+        <cellName>topo_perf_test</cellName>
+        <cellApps>drivers,metrics,openflow</cellApps>
+    </ENV>
+
+    <DEPENDENCY>
+        <path>/tests/SCPFhostLat/dependencies/</path>
+        <topology>topo-perf-1h1s.py</topology>
+    </DEPENDENCY>
+
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
+
+    <CTRL>
+        <port>6653</port>
+    </CTRL>
+
+    <SLEEP>
+        <startup>10</startup>
+        <install>10</install>
+        <measurement>5</measurement>
+        <timeout>10</timeout>
+    </SLEEP>
+
+    <TSHARK>
+        <tsharkPath>/tmp/hostLatTshark</tsharkPath>
+        <tsharkPacketIn>OF 1.3 150 of_packet_in</tsharkPacketIn>
+    </TSHARK>
+
+    <TEST>
+        # Number of times to iterate each case
+        <numIter>25</numIter>
+        # Number of iterations to ignore initially( warm up )
+        <iterIgnore>5</iterIgnore>
+        <singleSwThreshold>0,1000</singleSwThreshold>
+        <hostTimestamp>topologyHostEventTimestamp</hostTimestamp>
+    </TEST>
+
+    <DATABASE>
+        <file>/tmp/HostAddLatency</file>
+        <nic>1gig</nic>
+        <node>baremetal</node>
+    </DATABASE>
+
+</PARAMS>
diff --git a/TestON/tests/SCPF/SCPFhostLat/SCPFhostLat.py b/TestON/tests/SCPF/SCPFhostLat/SCPFhostLat.py
new file mode 100644
index 0000000..c24b6a7
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFhostLat/SCPFhostLat.py
@@ -0,0 +1,355 @@
+"""
+    SCPFhostLat
+    This test will test the host found latency.
+    Host will arping a ip address, tshark will caputure the package time, then compare with the topology event timestamp.
+    Test will run with 1 node from start, and scale up to 7 nodes.
+    The event timestamp will only greb the latest one, then calculate average and standar dev.
+
+    yunpeng@onlab.us
+"""
+class SCPFhostLat:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE0( self, main):
+        import sys
+        import json
+        import time
+        import os
+        import imp
+
+        main.case( "Constructing test variables and building ONOS package" )
+        main.step( "Constructing test variables" )
+        stepResult = main.FALSE
+
+        # Test variables
+        main.testOnDirectory = os.path.dirname( os.getcwd ( ) )
+        main.cellName = main.params[ 'ENV' ][ 'cellName' ]
+        main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+        main.scale = ( main.params[ 'SCALE' ] ).split( "," )
+        main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
+        main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+        main.installSleep = int( main.params[ 'SLEEP' ][ 'install' ] )
+        main.measurementSleep = int( main.params['SLEEP']['measurement'])
+        main.timeout = int( main.params['SLEEP']['timeout'] )
+        main.dbFileName = main.params['DATABASE']['file']
+        main.cellData = {} # for creating cell file
+
+        # Tshark params
+        main.tsharkResultPath = main.params['TSHARK']['tsharkPath']
+        main.tsharkPacketIn = main.params['TSHARK']['tsharkPacketIn']
+
+        main.numlter = main.params['TEST']['numIter']
+        main.iterIgnore = int(main.params['TEST']['iterIgnore'])
+        main.hostTimestampKey = main.params['TEST']['hostTimestamp']
+        main.thresholdStr = main.params['TEST']['singleSwThreshold']
+        main.thresholdObj = main.thresholdStr.split(',')
+        main.thresholdMin = int(main.thresholdObj[0])
+        main.thresholdMax = int(main.thresholdObj[1])
+        main.threadID = 0
+
+        main.CLIs = []
+        main.ONOSip = []
+        main.maxNumBatch = 0
+        main.ONOSip = main.ONOSbench.getOnosIps()
+        main.log.info(main.ONOSip)
+        main.setupSkipped = False
+
+        gitBranch = main.params[ 'GIT' ][ 'branch' ]
+        gitPull = main.params[ 'GIT' ][ 'pull' ]
+        nic = main.params['DATABASE']['nic']
+        node = main.params['DATABASE']['node']
+        nic = main.params['DATABASE']['nic']
+        node = main.params['DATABASE']['node']
+        stepResult = main.TRUE
+
+        main.log.info("Cresting DB file")
+        with open(main.dbFileName, "w+") as dbFile:
+            dbFile.write("")
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="environment set up successfull",
+                                 onfail="environment set up Failed" )
+
+    def CASE1( self ):
+        # main.scale[ 0 ] determines the current number of ONOS controller
+        main.CLIs = []
+        main.numCtrls = int( main.scale[ 0 ] )
+        main.log.info( "Creating list of ONOS cli handles" )
+        for i in range(main.numCtrls):
+            main.CLIs.append( getattr( main, 'ONOScli%s' % (i+1) ) )
+
+        main.log.info(main.CLIs)
+        if not main.CLIs:
+            main.log.error( "Failed to create the list of ONOS cli handles" )
+            main.cleanup()
+            main.exit()
+
+        main.commit = main.ONOSbench.getVersion(report=True)
+        main.commit = main.commit.split(" ")[1]
+
+        if gitPull == 'True':
+            if not main.startUp.onosBuild( main, gitBranch ):
+                main.log.error( "Failed to build ONOS" )
+                main.cleanup()
+                main.exit()
+        else:
+            main.log.warn( "Did not pull new code so skipping mvn " +
+                           "clean install" )
+        with open(main.dbFileName, "a") as dbFile:
+            temp = "'" + main.commit + "',"
+            temp += "'" + nic + "',"
+            dbFile.write(temp)
+            dbFile.close()
+
+    def CASE2( self, main ):
+        """
+        - Uninstall ONOS cluster
+        - Verify ONOS start up
+        - Install ONOS cluster
+        - Connect to cli
+        """
+        main.log.info( "Starting up %s node(s) ONOS cluster" % main.numCtrls)
+        main.log.info( "Safety check, killing all ONOS processes" +
+                       " before initiating environment setup" )
+
+        for i in range( main.numCtrls ):
+            main.ONOSbench.onosDie( main.ONOSip[ i ] )
+
+        main.log.info( "NODE COUNT = %s" % main.numCtrls)
+
+        tempOnosIp = []
+        for i in range( main.numCtrls ):
+            tempOnosIp.append( main.ONOSip[i] )
+
+        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
+                                       "temp",
+                                       main.Mininet1.ip_address,
+                                       main.apps,
+                                       tempOnosIp )
+
+        main.step( "Apply cell to environment" )
+        cellResult = main.ONOSbench.setCell( "temp" )
+        verifyResult = main.ONOSbench.verifyCell()
+        stepResult = cellResult and verifyResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully applied cell to " + \
+                                        "environment",
+                                 onfail="Failed to apply cell to environment " )
+
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.onosPackage()
+        stepResult = packageResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully created ONOS package",
+                                 onfail="Failed to create ONOS package" )
+
+        main.step( "Uninstall ONOS package on all Nodes" )
+        uninstallResult = main.TRUE
+        for i in range( int( main.numCtrls ) ):
+            main.log.info( "Uninstalling package on ONOS Node IP: " + main.ONOSip[i] )
+            u_result = main.ONOSbench.onosUninstall( main.ONOSip[i] )
+            utilities.assert_equals( expect=main.TRUE, actual=u_result,
+                                     onpass="Test step PASS",
+                                     onfail="Test step FAIL" )
+            uninstallResult = ( uninstallResult and u_result )
+
+        main.step( "Install ONOS package on all Nodes" )
+        installResult = main.TRUE
+        for i in range( int( main.numCtrls ) ):
+            main.log.info( "Installing package on ONOS Node IP: " + main.ONOSip[i] )
+            i_result = main.ONOSbench.onosInstall( node=main.ONOSip[i] )
+            utilities.assert_equals( expect=main.TRUE, actual=i_result,
+                                     onpass="Test step PASS",
+                                     onfail="Test step FAIL" )
+            installResult = installResult and i_result
+        time.sleep( main.startUpSleep )
+        main.step( "Verify ONOS nodes UP status" )
+        statusResult = main.TRUE
+        for i in range( int( main.numCtrls ) ):
+            main.log.info( "ONOS Node " + main.ONOSip[i] + " status:" )
+            onos_status = main.ONOSbench.onosStatus( node=main.ONOSip[i] )
+            utilities.assert_equals( expect=main.TRUE, actual=onos_status,
+                                     onpass="Test step PASS",
+                                     onfail="Test step FAIL" )
+            statusResult = ( statusResult and onos_status )
+
+        main.step( "Start ONOS CLI on all nodes" )
+        cliResult = main.TRUE
+        main.log.step(" Start ONOS cli using thread ")
+        time.sleep( main.startUpSleep )
+        startCliResult  = main.TRUE
+        pool = []
+
+        for i in range( int( main.numCtrls) ):
+            t = main.Thread( target=main.CLIs[i].startOnosCli,
+                             threadID=main.threadID,
+                             name="startOnosCli",
+                             args=[ main.ONOSip[i] ],
+                             kwargs = {"onosStartTimeout":main.timeout} )
+            pool.append(t)
+            t.start()
+            main.threadID = main.threadID + 1
+        for t in pool:
+            t.join()
+            startCliResult = startCliResult and t.result
+        time.sleep( main.startUpSleep )
+
+    def CASE11( self, main ):
+        main.log.info( "set and configure Application" )
+        import json
+        import time
+        time.sleep(main.startUpSleep)
+        main.step( "Activating org.onosproject.proxyarp" )
+        appStatus = utilities.retry( main.ONOSrest1.activateApp,
+                                     main.FALSE,
+                                     ['org.onosproject.proxyarp'],
+                                     sleep=3,
+                                     attempts=3 )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=appStatus,
+                                 onpass="Successfully activated proxyarp",
+                                 onfail="Failed to activated proxyarp")
+
+        main.step( "Set up Default Topology Provider" )
+        appStatus = main.TRUE
+        configName = 'org.onosproject.net.topology.impl.DefaultTopologyProvider'
+        configParam = 'maxEvents'
+        appStatus = appStatus and main.CLIs[0].setCfg(  configName, configParam,'1' )
+        configParam = 'maxBatchMs'
+        appStatus = appStatus and main.CLIs[0].setCfg( configName, configParam, '0')
+        configParam = 'maxIdleMs'
+        appStatus = appStatus and main.CLIs[0].setCfg( configName, configParam,'0' )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=appStatus,
+                                 onpass="Successfully set DefaultTopologyProvider",
+                                 onfail="Failed to set DefaultTopologyProvider" )
+
+        time.sleep(main.startUpSleep)
+        main.step('Starting mininet topology')
+        mnStatus = main.Mininet1.startNet(args='--topo=linear,1')
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=mnStatus,
+                                 onpass="Successfully started Mininet",
+                                 onfail="Failed to activate Mininet" )
+        main.step("Assinging masters to switches")
+        switches = main.Mininet1.getSwitches()
+        swStatus = main.Mininet1.assignSwController( sw=switches.keys(), ip=main.ONOSip[0] )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=swStatus,
+                                 onpass="Successfully assigned switches to masters",
+                                 onfail="Failed assign switches to masters" )
+
+        time.sleep(main.startUpSleep)
+
+    def CASE20(self, main):
+        """
+        host1 send arping package and measure latency
+
+        There are only 1 levels of latency measurements to this test:
+        1 ) ARPING-to-device measurement: Measurement the time from host1
+        send apring package to onos processing the host event
+
+        """
+        import time
+        import subprocess
+        import json
+        import requests
+        import os
+        import numpy
+
+        # Host adding measurement
+        assertion = main.TRUE
+
+        main.log.report('Latency of adding one host to ONOS')
+        main.log.report('First ' + str(main.iterIgnore) + ' iterations ignored' + ' for jvm warmup time')
+        main.log.report('Total iterations of test: ' + str(main.numlter))
+
+        addingHostTime = []
+        metricsResultList = []
+        for i in range(0, int(main.numlter)):
+            main.log.info('Clean up data file')
+            with open(main.tsharkResultPath, "w") as dbFile:
+                dbFile.write("")
+
+            main.log.info('Starting tshark capture')
+            main.ONOSbench.tsharkGrep(main.tsharkPacketIn, main.tsharkResultPath)
+            time.sleep(main.measurementSleep)
+
+            main.log.info('host 1 arping...')
+            main.Mininet1.arping(srcHost='h1', dstHost='10.0.0.2')
+
+            time.sleep(main.measurementSleep)
+
+            main.log.info('Stopping all Tshark processes')
+            main.ONOSbench.tsharkStop()
+
+            time.sleep(main.measurementSleep)
+
+            # Get tshark output
+            with open(main.tsharkResultPath, "r") as resultFile:
+                resultText = resultFile.readline()
+                main.log.info('Capture result:' + resultText)
+                resultText = resultText.split(' ')
+                if len(resultText) > 1:
+                    tsharkResultTime = float(resultText[1]) * 1000.0
+                else:
+                    main.log.error('Tshark output file for packet_in' + ' returned unexpected results')
+                    hostTime = 0
+                    caseResult = main.FALSE
+                resultFile.close()
+            # Compare the timestemps, and get the lowest one.
+            temp = 0;
+            # Get host event timestamps from each nodes
+            for node in range (0, main.numCtrls):
+                metricsResult = json.loads(main.CLIs[node].topologyEventsMetrics())
+                metricsResult = metricsResult.get(main.hostTimestampKey).get("value")
+                main.log.info("ONOS topology event matrics timestemp: {}".format(str(metricsResult)) )
+
+                if temp < metricsResult:
+                    temp = metricsResult
+                metricsResult = temp
+
+            addingHostTime.append(float(metricsResult) - tsharkResultTime)
+            main.log.info("Result of this iteration: {}".format( str( float(metricsResult) - tsharkResultTime) ))
+            # gethost to remove
+            gethost = main.ONOSrest1.hosts()
+            HosttoRemove = []
+            HosttoRemove.append( json.loads( gethost[1:len(gethost)-1] ).get('id') )
+            main.CLIs[0].removeHost(HosttoRemove)
+
+        main.log.info("Result List: {}".format(addingHostTime))
+
+        # calculate average latency from each nodes
+        averageResult = numpy.average(addingHostTime)
+        main.log.info("Average Latency: {}".format(averageResult))
+
+        # calculate std
+        stdResult = numpy.std(addingHostTime)
+        main.log.info("std: {}".format(stdResult))
+
+        # write to DB file
+        main.log.info("Writing results to DS file")
+        with open(main.dbFileName, "a") as dbFile:
+            # Scale number
+            temp = str(main.numCtrls)
+            temp += ",'" + "baremetal1" + "'"
+            # average latency
+            temp += "," + str( averageResult )
+            # std of latency
+            temp += "," + str(stdResult)
+            temp += "\n"
+            dbFile.write( temp )
+
+        assertion = main.TRUE
+
+        utilities.assert_equals(expect=main.TRUE, actual=assertion,
+                onpass='Host latency test successful',
+                onfail='Host latency test failed')
+
+        main.Mininet1.stopNet()
+        del main.scale[0]
diff --git a/TestON/tests/SCPF/SCPFhostLat/SCPFhostLat.topo b/TestON/tests/SCPF/SCPFhostLat/SCPFhostLat.topo
new file mode 100644
index 0000000..382d60f
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFhostLat/SCPFhostLat.topo
@@ -0,0 +1,112 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+                <home>~/onos</home>
+                <nodes>7</nodes> 
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOScli1>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli1>
+
+        <ONOScli2>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli2>
+
+        <ONOScli3>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli3>
+
+        <ONOScli4>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli4>
+
+        <ONOScli5>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli5>
+
+        <ONOScli6>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli6>
+
+        <ONOScli7>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>8</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli7>
+
+        <ONOS1>
+            <host>OC1</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>9</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1>
+
+        <Mininet1>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>MininetCliDriver</type>
+            <connect_order>16</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </Mininet1>
+
+        <ONOSrest1>
+            <host>OC1</host>
+            <port>8181</port>
+            <user>onos</user>
+            <password>rocks</password>
+            <type>OnosRestDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENT>
+            </COMPONENT>
+        </ONOSrest1>
+
+    </COMPONENT>
+
+</TOPOLOGY>
diff --git a/TestON/tests/SCPF/SCPFhostLat/__init__.py b/TestON/tests/SCPF/SCPFhostLat/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFhostLat/__init__.py
diff --git a/TestON/tests/SCPF/SCPFintentEventTp/README b/TestON/tests/SCPF/SCPFintentEventTp/README
new file mode 100644
index 0000000..30a2549
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentEventTp/README
@@ -0,0 +1,28 @@
+INTENT EVENT THROUGHPUT
+
+Summary: This is a performance test suite to test the intent
+    throughput capabilities of ONOS with various controller cluster sizes.
+
+Pre-requisites: To run out-of-the box this test requires 7 NODES. OC1->OC7
+    must be set before initiating the test. Passwordless login must be set
+    from TestStation "sdn" root user.
+
+***If you wish to run this test with less than 7 nodes the following
+    alterations must be made:
+
+NOTE: Only scale sizes 1,3,5 and 7 will be functional
+
+Modifying .params file:
+-- Remove any values in the comma separated list in the
+    <scale> tag that are above your desired cluster size.
+
+-- Remove one instance of “1,2” from the <testcases>
+    tag for each value you removed from <scale> (case 1 and 2 are each
+    called once for each scale value)
+
+-- Change the value in the <max> tag to your desired scale size (1,3, or 5)
+
+Modifying .topo file:
+-- Change the <ONOSbench/COMPONENTS/nodes> tag to your desired scale size
+
+-- Remove all unneeded <ONOS#cli> tags and their contents
diff --git a/TestON/tests/SCPF/SCPFintentEventTp/SCPFintentEventTp.params b/TestON/tests/SCPF/SCPFintentEventTp/SCPFintentEventTp.params
new file mode 100644
index 0000000..c7c156c
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentEventTp/SCPFintentEventTp.params
@@ -0,0 +1,71 @@
+<PARAMS>
+
+    <testcases>1,2,1,2,1,2,1,2,1,2,1,2,1,2</testcases>
+
+    <debugMode></debugMode>  #nothing means false
+
+    <ENV>
+    <cellName>intentTP</cellName>
+    <cellApps>drivers,null,intentperf</cellApps>
+    </ENV>
+
+    <SCALE>1,3,3,5,5,7,7</SCALE>
+    <max>7</max>
+
+    <GIT>
+        <autopull>off</autopull>
+        <checkout>master</checkout>
+    </GIT>
+
+    <CTRL>
+        <USER>sdn</USER>
+
+        <ip1>OC1</ip1>
+        <port1>6653</port1>
+
+        <ip2>OC2</ip2>
+        <port2>6653</port2>
+
+        <ip3>OC3</ip3>
+        <port3>6653</port3>
+
+        <ip4>OC4</ip4>
+        <port4>6653</port4>
+
+        <ip5>OC5</ip5>
+        <port5>6653</port5>
+
+        <ip6>OC6</ip6>
+        <port6>6653</port6>
+
+         <ip7>OC7</ip7>
+        <port7>6653</port7>
+    </CTRL>
+
+    <MN><ip1>OCN</ip1></MN>
+
+    <BENCH>
+        <user>sdn</user>
+        <ip1>OCN</ip1>
+    </BENCH>
+
+    <TEST>
+        <loadFrom>1,1,1,1,1,1,1</loadFrom>                                     #generate load on server, 1 = generator on
+        <numSwitches>10,10,10,10,10,10,10</numSwitches>
+        <skipCleanInstall>yes</skipCleanInstall>
+        <duration>400</duration>
+        <log_interval>20</log_interval>
+        <numKeys>40000</numKeys>
+        <cyclePeriod>1000</cyclePeriod>
+        <neighbors>0,a</neighbors>           #a == all nodes (-1)
+        <flowRuleBUEnabled>true</flowRuleBUEnabled>
+        <skipReleaseResourcesOnWithdrawal>true</skipReleaseResourcesOnWithdrawal>
+    </TEST>
+
+    <METRICS>
+        <intents_rate>intents-events-metrics|grep "Intent Installed Events"|cut -d ' ' -f7</intents_rate>
+        <intents_withdrawn>intents-events-metrics|grep "Intent Withdrawn Events"|cut -d ' ' -f7</intents_withdrawn>
+        <intents_failed>intents-events-metrics|grep "Intent Failed Events"|cut -d ' ' -f7</intents_failed>
+    </METRICS>
+
+</PARAMS>
diff --git a/TestON/tests/SCPF/SCPFintentEventTp/SCPFintentEventTp.py b/TestON/tests/SCPF/SCPFintentEventTp/SCPFintentEventTp.py
new file mode 100644
index 0000000..385d9e6
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentEventTp/SCPFintentEventTp.py
@@ -0,0 +1,323 @@
+# ScaleOutTemplate
+#
+# CASE1 starts number of nodes specified in param file
+#
+# cameron@onlab.us
+
+import sys
+import os.path
+import time
+
+
+class SCPFintentEventTp:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):
+        import sys
+        import os.path
+        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' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+        MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+        maxNodes = int(main.params[ 'max' ])
+        main.maxNodes = maxNodes
+        skipMvn = main.params[ 'TEST' ][ 'skipCleanInstall' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        numSwitches = (main.params[ 'TEST' ][ 'numSwitches' ]).split(",")
+        flowRuleBU = main.params[ 'TEST' ][ 'flowRuleBUEnabled' ]
+        skipRelRsrc = main.params[ 'TEST'][ 'skipReleaseResourcesOnWithdrawal']
+        homeDir = os.path.expanduser('~')
+
+        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 = main.ONOSbench.getOnosIps()
+            print ONOSIp
+            print main.ONOSbench.onosIps.values()
+
+            scale = (main.params[ 'SCALE' ]).split(",")
+            clusterCount = int(scale[0])
+
+            #Populate ONOSIp with ips from params
+            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" )
+
+            main.log.step("Grabbing commit number")
+            commit = main.ONOSbench.getVersion()
+            commit = (commit.split(" "))[1]
+
+            main.log.step("Creating results file")
+            resultsDB = open("/tmp/IntentEventTPDB", "w+")
+            resultsDB.close()
+
+        # -- END OF INIT SECTION --#
+
+        main.log.step("Adjusting scale")
+        print str(scale)
+        print str(ONOSIp)
+        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 environment setup")
+        for node in range(maxNodes):
+            main.ONOSbench.onosDie(ONOSIp[node])
+
+        MN1Ip = ONOSIp[len(ONOSIp) -1]
+        BENCHIp = ONOSIp[len(ONOSIp) -2]
+
+        #Uninstall everywhere
+        main.log.step( "Cleaning Enviornment..." )
+        for i in range(maxNodes):
+            main.log.info(" Uninstalling ONOS " + str(i) )
+            main.ONOSbench.onosUninstall( ONOSIp[i] )
+        main.log.info("Sleep 10 second for uninstall to settle...")
+        time.sleep(10)
+        main.ONOSbench.handle.sendline(" ")
+        main.ONOSbench.handle.expect(":~")
+
+        #construct the cell file
+        main.log.info("Creating cell file")
+        cellIp = []
+        for node in range (clusterCount):
+            cellIp.append(ONOSIp[node])
+
+        main.ONOSbench.createCellFile("localhost",cellName,MN1Ip,str(Apps), cellIp)
+
+        main.step( "Set Cell" )
+        main.ONOSbench.setCell(cellName)
+
+        myDistribution = []
+        for node in range (clusterCount):
+            myDistribution.append(numSwitches[node])
+
+        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(clusterCount):
+            main.log.info("Starting ONOS " + str(node) + " at IP: " + ONOSIp[node])
+            main.ONOSbench.onosInstall( ONOSIp[node])
+
+        for node in range(clusterCount):
+            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")
+
+        time.sleep(20)
+
+        main.ONOSbench.onosCfgSet( ONOSIp[0], "org.onosproject.store.flow.impl.NewDistributedFlowRuleStore", "backupEnabled " + str(flowRuleBU))
+        main.ONOSbench.onosCfgSet( ONOSIp[0], "org.onosproject.net.intent.impl.IntentManager", "skipReleaseResourcesOnWithdrawal " + skipRelRsrc)
+        devices = int(clusterCount)*10
+
+        main.log.step("Setting up null provider")
+        for i in range(3):
+            main.ONOSbench.onosCfgSet( ONOSIp[0], "org.onosproject.provider.nil.NullProviders", "deviceCount " + str(devices))
+            main.ONOSbench.onosCfgSet( ONOSIp[0], "org.onosproject.provider.nil.NullProviders", "topoShape linear")
+            main.ONOSbench.onosCfgSet( ONOSIp[0], "org.onosproject.provider.nil.NullProviders", "enabled true")
+            time.sleep(5)
+
+            main.ONOSbench.handle.sendline("onos $OC1 summary")
+            main.ONOSbench.handle.expect(":~")
+
+            before = main.ONOSbench.handle.before
+            if ("devices=" + str(devices)) in before:
+                break
+
+        main.ONOSbench.handle.sendline("""onos $OC1 "balance-masters" """)
+        main.ONOSbench.handle.expect(":~")
+        print main.ONOSbench.handle.before
+
+        for i in range(3):
+            passed = main.ONOSbench.verifySummary( ONOSIp[0] )
+            if passed:
+                main.log.info("Clusters have converged")
+                break
+            else:
+                main.log.error("Clusters have not converged, retying...")
+            time.sleep(3)
+
+        main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"])
+
+    def CASE2( self, main ):
+        import time
+        import json
+        import string
+        import csv
+        import numpy
+        import os.path
+
+        global currentNeighbors
+        neighbors = []
+
+        try:
+            currentNeighbors
+        except:
+            currentNeighbors = "0"
+            neighbors = ['0']
+        else:
+            if currentNeighbors == "r":      #reset
+                currentNeighbors = "a"
+                neighbors = ['0']
+            else:
+                currentNeighbors = "r"
+                neighbors = ['a']
+
+        if clusterCount == 1:
+            currentNeighbors = "r"
+
+        main.log.info("Cluster Count = " + str(clusterCount))
+
+        intentsRate = main.params['METRICS']['intents_rate']
+        intentsWithdrawn = main.params[ 'METRICS' ][ 'intents_withdrawn' ]
+        intentsFailed  = main.params[ 'METRICS' ][ 'intents_failed' ]
+        testDuration = main.params[ 'TEST' ][ 'duration' ]
+        logInterval = main.params[ 'TEST' ][ 'log_interval' ]
+        debug = main.params[ 'debugMode' ]
+        numKeys = main.params[ 'TEST' ][ 'numKeys' ]
+        cyclePeriod = main.params[ 'TEST' ][ 'cyclePeriod' ]
+        #neighbors = (main.params[ 'TEST' ][ 'neighbors' ]).split(",")
+        metricList = [intentsRate, intentsWithdrawn, intentsFailed]
+
+        for n in range(0, len(neighbors)):
+            if neighbors[n] == 'a':
+                neighbors[n] = str(clusterCount -1)
+                if int(clusterCount) == 1:
+                    neighbors = neighbors.pop()
+
+        for n in neighbors:
+            main.log.info("Run with " + n + " neighbors")
+            time.sleep(5)
+            main.ONOSbench.handle.sendline("onos $OC1 cfg set org.onosproject.intentperf.IntentPerfInstaller numKeys " + numKeys )
+            main.ONOSbench.handle.expect(":~")
+            main.ONOSbench.handle.sendline("onos $OC1 cfg set org.onosproject.intentperf.IntentPerfInstaller numNeighbors " + n )
+            main.ONOSbench.handle.expect(":~")
+            main.ONOSbench.handle.sendline("onos $OC1 cfg set org.onosproject.intentperf.IntentPerfInstaller cyclePeriod " + cyclePeriod )
+            main.ONOSbench.handle.expect(":~")
+
+            cmd = "onos $OC1 intent-perf-start"
+            main.ONOSbench.handle.sendline(cmd)
+            main.ONOSbench.handle.expect(":~")
+            main.log.info("Starting ONOS (all nodes)  intent-perf from $OC1" )
+
+            main.log.info( "Starting test loop for " + str(testDuration) + " seconds...\n" )
+            stop = time.time() + float( testDuration )
+
+            while time.time() < stop:
+                time.sleep( float( logInterval ) )
+                groupResult = []
+                for node in range (1, clusterCount + 1):
+                    groupResult.append(0)
+
+                    cmd = " onos-ssh $OC" + str(node) +  """ cat /opt/onos/log/karaf.log | grep "Throughput:" | tail -1  """
+                    main.log.info("COMMAND: " + str(cmd))
+
+                    x = 0
+                    while True:
+                        main.ONOSbench.handle.sendline(cmd)
+                        time.sleep(6)
+                        main.ONOSbench.handle.expect(":~")
+                        raw = main.ONOSbench.handle.before
+                        if "OVERALL=" in raw:
+                            break
+                        x += 1
+                        if x > 10:
+                            main.log.error("Expected output not being recieved... continuing")
+                            break
+                        time.sleep(2)
+
+                    raw = raw.splitlines()
+                    splitResults = []
+                    for line in raw:
+                        splitResults.extend(line.split(" "))
+
+                    myResult = "--"
+                    for field in splitResults:
+                        if "OVERALL" in field:
+                            myResult = field
+
+                    if myResult == "--":
+                        main.log.error("Parsing/Pexpect error\n" + str(splitResults))
+
+                    myResult = myResult.replace(";", "")
+                    myResult = myResult.replace("OVERALL=","")
+                    myResult = float(myResult)
+                    groupResult[len(groupResult) -1] = myResult
+
+                    main.log.info("Node " + str(node) + " overall rate: " + str(myResult))
+
+                clusterTotal = str(numpy.sum(groupResult))
+                main.log.report("Results from this round of polling: " + str(groupResult))
+                main.log.report("Cluster Total: " + clusterTotal + "\n")
+
+            cmd = "onos $OC1 intent-perf-stop"
+            main.ONOSbench.handle.sendline(cmd)
+            main.ONOSbench.handle.expect(":~")
+            main.log.info("Stopping intentperf" )
+
+            with open("/tmp/IntentEventTPDB", "a") as resultsDB:
+                for node in groupResult:
+                    resultString = "'" + commit + "',"
+                    resultString += "'1gig',"
+                    resultString += str(clusterCount) + ","
+                    resultString += "'baremetal" + str(int(groupResult.index(node)) + 1) + "',"
+                    resultString += n + ","
+                    resultString += str(node) + ","
+                    resultString += str(0) + "\n" #no stddev
+                    resultsDB.write(resultString)
+
+            resultsDB.close()
+
+            main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"])
+
diff --git a/TestON/tests/SCPF/SCPFintentEventTp/SCPFintentEventTp.topo b/TestON/tests/SCPF/SCPFintentEventTp/SCPFintentEventTp.topo
new file mode 100644
index 0000000..3a1c9f9
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentEventTp/SCPFintentEventTp.topo
@@ -0,0 +1,147 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+                <home>~/onos</home>
+                <nodes>7</nodes>
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOS1cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1cli>
+
+        <ONOS2cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2cli>
+
+        <ONOS3cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3cli>
+
+        <ONOS4cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4cli>
+
+        <ONOS5cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5cli>
+
+        <ONOS6cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6cli>
+
+        <ONOS7cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</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/SCPF/SCPFintentEventTp/__init__.py b/TestON/tests/SCPF/SCPFintentEventTp/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentEventTp/__init__.py
diff --git a/TestON/tests/SCPF/SCPFintentEventTpWithFlowObj/README b/TestON/tests/SCPF/SCPFintentEventTpWithFlowObj/README
new file mode 100644
index 0000000..30a2549
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentEventTpWithFlowObj/README
@@ -0,0 +1,28 @@
+INTENT EVENT THROUGHPUT
+
+Summary: This is a performance test suite to test the intent
+    throughput capabilities of ONOS with various controller cluster sizes.
+
+Pre-requisites: To run out-of-the box this test requires 7 NODES. OC1->OC7
+    must be set before initiating the test. Passwordless login must be set
+    from TestStation "sdn" root user.
+
+***If you wish to run this test with less than 7 nodes the following
+    alterations must be made:
+
+NOTE: Only scale sizes 1,3,5 and 7 will be functional
+
+Modifying .params file:
+-- Remove any values in the comma separated list in the
+    <scale> tag that are above your desired cluster size.
+
+-- Remove one instance of “1,2” from the <testcases>
+    tag for each value you removed from <scale> (case 1 and 2 are each
+    called once for each scale value)
+
+-- Change the value in the <max> tag to your desired scale size (1,3, or 5)
+
+Modifying .topo file:
+-- Change the <ONOSbench/COMPONENTS/nodes> tag to your desired scale size
+
+-- Remove all unneeded <ONOS#cli> tags and their contents
diff --git a/TestON/tests/SCPF/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.params b/TestON/tests/SCPF/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.params
new file mode 100644
index 0000000..729e3ef
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.params
@@ -0,0 +1,71 @@
+<PARAMS>
+
+    <testcases>1,3,2,1,3,2,1,3,2,1,3,2,1,3,2,1,3,2,1,3,2</testcases>
+
+    <debugMode></debugMode>  #nothing means false
+
+    <ENV>
+    <cellName>intentTP</cellName>
+    <cellApps>drivers,null,intentperf</cellApps>
+    </ENV>
+
+    <SCALE>1,3,3,5,5,7,7</SCALE>
+    <max>7</max>
+
+    <GIT>
+        <autopull>off</autopull>
+        <checkout>master</checkout>
+    </GIT>
+
+    <CTRL>
+        <USER>sdn</USER>
+
+        <ip1>OC1</ip1>
+        <port1>6653</port1>
+
+        <ip2>OC2</ip2>
+        <port2>6653</port2>
+
+        <ip3>OC3</ip3>
+        <port3>6653</port3>
+
+        <ip4>OC4</ip4>
+        <port4>6653</port4>
+
+        <ip5>OC5</ip5>
+        <port5>6653</port5>
+
+        <ip6>OC6</ip6>
+        <port6>6653</port6>
+
+         <ip7>OC7</ip7>
+        <port7>6653</port7>
+    </CTRL>
+
+    <MN><ip1>OCN</ip1></MN>
+
+    <BENCH>
+        <user>sdn</user>
+        <ip1>OCN</ip1>
+    </BENCH>
+
+    <TEST>
+        <loadFrom>1,1,1,1,1,1,1</loadFrom>                                     #generate load on server, 1 = generator on
+        <numSwitches>10,10,10,10,10,10,10</numSwitches>
+        <skipCleanInstall>yes</skipCleanInstall>
+        <duration>400</duration>
+        <log_interval>10</log_interval>
+        <numKeys>40000</numKeys>
+        <cyclePeriod>1000</cyclePeriod>
+        <neighbors>0,a</neighbors>           #a == all nodes (-1)
+        <flowRuleBUEnabled>true</flowRuleBUEnabled>
+        <skipReleaseResourcesOnWithdrawal>true</skipReleaseResourcesOnWithdrawal>
+    </TEST>
+
+    <METRICS>
+        <intents_rate>intents-events-metrics|grep "Intent Installed Events"|cut -d ' ' -f7</intents_rate>
+        <intents_withdrawn>intents-events-metrics|grep "Intent Withdrawn Events"|cut -d ' ' -f7</intents_withdrawn>
+        <intents_failed>intents-events-metrics|grep "Intent Failed Events"|cut -d ' ' -f7</intents_failed>
+    </METRICS>
+
+</PARAMS>
diff --git a/TestON/tests/SCPF/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.py b/TestON/tests/SCPF/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.py
new file mode 100644
index 0000000..f3cd037
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.py
@@ -0,0 +1,335 @@
+# ScaleOutTemplate
+#
+# CASE1 starts number of nodes specified in param file
+#
+# cameron@onlab.us
+
+import sys
+import os.path
+import time
+
+
+class SCPFintentEventTpWithFlowObj:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):
+        import sys
+        import os.path
+        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' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+        MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+        maxNodes = int(main.params[ 'max' ])
+        main.maxNodes = maxNodes
+        skipMvn = main.params[ 'TEST' ][ 'skipCleanInstall' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        numSwitches = (main.params[ 'TEST' ][ 'numSwitches' ]).split(",")
+        flowRuleBU = main.params[ 'TEST' ][ 'flowRuleBUEnabled' ]
+        skipRelRsrc = main.params[ 'TEST'][ 'skipReleaseResourcesOnWithdrawal']
+        homeDir = os.path.expanduser('~')
+
+        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 = main.ONOSbench.getOnosIps()
+            print ONOSIp
+            print main.ONOSbench.onosIps.values()
+
+            scale = (main.params[ 'SCALE' ]).split(",")
+            clusterCount = int(scale[0])
+
+            #Populate ONOSIp with ips from params
+            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" )
+
+            main.log.step("Grabbing commit number")
+            commit = main.ONOSbench.getVersion()
+            commit = (commit.split(" "))[1]
+
+            main.log.step("Creating results file")
+            # Create results file with flow object
+            flowObjResultsDB = open("/tmp/IntentEventTPflowObjDB", "w+")
+            flowObjResultsDB.close()
+
+        # -- END OF INIT SECTION --#
+
+        main.log.step("Adjusting scale")
+        print str(scale)
+        print str(ONOSIp)
+        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 environment setup")
+        for node in range(maxNodes):
+            main.ONOSbench.onosDie(ONOSIp[node])
+
+        MN1Ip = ONOSIp[len(ONOSIp) -1]
+        BENCHIp = ONOSIp[len(ONOSIp) -2]
+
+        #Uninstall everywhere
+        main.log.step( "Cleaning Enviornment..." )
+        for i in range(maxNodes):
+            main.log.info(" Uninstalling ONOS " + str(i) )
+            main.ONOSbench.onosUninstall( ONOSIp[i] )
+        main.log.info("Sleep 10 second for uninstall to settle...")
+        time.sleep(10)
+        main.ONOSbench.handle.sendline(" ")
+        main.ONOSbench.handle.expect(":~")
+
+        #construct the cell file
+        main.log.info("Creating cell file")
+        cellIp = []
+        for node in range (clusterCount):
+            cellIp.append(ONOSIp[node])
+
+        main.ONOSbench.createCellFile("localhost",cellName,MN1Ip,str(Apps), cellIp)
+
+        main.step( "Set Cell" )
+        main.ONOSbench.setCell(cellName)
+
+        myDistribution = []
+        for node in range (clusterCount):
+            myDistribution.append(numSwitches[node])
+
+        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(clusterCount):
+            main.log.info("Starting ONOS " + str(node) + " at IP: " + ONOSIp[node])
+            main.ONOSbench.onosInstall( ONOSIp[node])
+
+        for node in range(clusterCount):
+            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")
+
+        time.sleep(20)
+
+        main.ONOSbench.onosCfgSet( ONOSIp[0], "org.onosproject.store.flow.impl.NewDistributedFlowRuleStore", "backupEnabled " + str(flowRuleBU))
+        main.ONOSbench.onosCfgSet( ONOSIp[0], "org.onosproject.net.intent.impl.IntentManager", "skipReleaseResourcesOnWithdrawal " + skipRelRsrc)
+        devices = int(clusterCount)*10
+
+        main.log.step("Setting up null provider")
+        for i in range(3):
+            main.ONOSbench.onosCfgSet( ONOSIp[0], "org.onosproject.provider.nil.NullProviders", "deviceCount " + str(devices))
+            main.ONOSbench.onosCfgSet( ONOSIp[0], "org.onosproject.provider.nil.NullProviders", "topoShape linear")
+            main.ONOSbench.onosCfgSet( ONOSIp[0], "org.onosproject.provider.nil.NullProviders", "enabled true")
+            time.sleep(5)
+
+            main.ONOSbench.handle.sendline("onos $OC1 summary")
+            main.ONOSbench.handle.expect(":~")
+
+            before = main.ONOSbench.handle.before
+            if ("devices=" + str(devices)) in before:
+                break
+
+        main.ONOSbench.handle.sendline("""onos $OC1 "balance-masters" """)
+        main.ONOSbench.handle.expect(":~")
+        print main.ONOSbench.handle.before
+
+        for i in range(3):
+            passed = main.ONOSbench.verifySummary( ONOSIp[0] )
+            if passed:
+                main.log.info("Clusters have converged")
+                break
+            else:
+                main.log.error("Clusters have not converged, retying...")
+            time.sleep(3)
+
+        main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"])
+
+    def CASE2( self, main ):
+        import time
+        import json
+        import string
+        import csv
+        import numpy
+        import os.path
+
+        global currentNeighbors
+        neighbors = []
+
+        try:
+            currentNeighbors
+        except:
+            currentNeighbors = "0"
+            neighbors = ['0']
+        else:
+            if currentNeighbors == "r":      #reset
+                currentNeighbors = "a"
+                neighbors = ['0']
+            else:
+                currentNeighbors = "r"
+                neighbors = ['a']
+
+        if clusterCount == 1:
+            currentNeighbors = "r"
+
+        main.log.info("Cluster Count = " + str(clusterCount))
+
+        intentsRate = main.params['METRICS']['intents_rate']
+        intentsWithdrawn = main.params[ 'METRICS' ][ 'intents_withdrawn' ]
+        intentsFailed  = main.params[ 'METRICS' ][ 'intents_failed' ]
+        testDuration = main.params[ 'TEST' ][ 'duration' ]
+        logInterval = main.params[ 'TEST' ][ 'log_interval' ]
+        debug = main.params[ 'debugMode' ]
+        numKeys = main.params[ 'TEST' ][ 'numKeys' ]
+        cyclePeriod = main.params[ 'TEST' ][ 'cyclePeriod' ]
+        #neighbors = (main.params[ 'TEST' ][ 'neighbors' ]).split(",")
+        metricList = [intentsRate, intentsWithdrawn, intentsFailed]
+
+        for n in range(0, len(neighbors)):
+            if neighbors[n] == 'a':
+                neighbors[n] = str(clusterCount -1)
+                if int(clusterCount) == 1:
+                    neighbors = neighbors.pop()
+
+        for n in neighbors:
+            main.log.info("Run with " + n + " neighbors")
+            time.sleep(5)
+            main.ONOSbench.handle.sendline("onos $OC1 cfg set org.onosproject.intentperf.IntentPerfInstaller numKeys " + numKeys )
+            main.ONOSbench.handle.expect(":~")
+            main.ONOSbench.handle.sendline("onos $OC1 cfg set org.onosproject.intentperf.IntentPerfInstaller numNeighbors " + n )
+            main.ONOSbench.handle.expect(":~")
+            main.ONOSbench.handle.sendline("onos $OC1 cfg set org.onosproject.intentperf.IntentPerfInstaller cyclePeriod " + cyclePeriod )
+            main.ONOSbench.handle.expect(":~")
+
+            cmd = "onos $OC1 intent-perf-start"
+            main.ONOSbench.handle.sendline(cmd)
+            main.ONOSbench.handle.expect(":~")
+            main.log.info("Starting ONOS (all nodes)  intent-perf from $OC1" )
+
+            main.log.info( "Starting test loop for " + str(testDuration) + " seconds...\n" )
+            stop = time.time() + float( testDuration )
+
+            while time.time() < stop:
+                time.sleep( float( logInterval ) )
+                groupResult = []
+                for node in range (1, clusterCount + 1):
+                    groupResult.append(0)
+
+                    cmd = " onos-ssh $OC" + str(node) +  """ cat /opt/onos/log/karaf.log | grep "Throughput:" | tail -1  """
+                    main.log.info("COMMAND: " + str(cmd))
+
+                    x = 0
+                    while True:
+                        main.ONOSbench.handle.sendline(cmd)
+                        time.sleep(6)
+                        main.ONOSbench.handle.expect(":~")
+                        raw = main.ONOSbench.handle.before
+                        if "OVERALL=" in raw:
+                            break
+                        x += 1
+                        if x > 10:
+                            main.log.error("Expected output not being recieved... continuing")
+                            break
+                        time.sleep(2)
+
+                    raw = raw.splitlines()
+                    splitResults = []
+                    for line in raw:
+                        splitResults.extend(line.split(" "))
+
+                    myResult = "--"
+                    for field in splitResults:
+                        if "OVERALL" in field:
+                            myResult = field
+
+                    if myResult == "--":
+                        main.log.error("Parsing/Pexpect error\n" + str(splitResults))
+
+                    myResult = myResult.replace(";", "")
+                    myResult = myResult.replace("OVERALL=","")
+                    myResult = float(myResult)
+                    groupResult[len(groupResult) -1] = myResult
+
+                    main.log.info("Node " + str(node) + " overall rate: " + str(myResult))
+
+                clusterTotal = str(numpy.sum(groupResult))
+                main.log.report("Results from this round of polling: " + str(groupResult))
+                main.log.report("Cluster Total: " + clusterTotal + "\n")
+
+            cmd = "onos $OC1 intent-perf-stop"
+            main.ONOSbench.handle.sendline(cmd)
+            main.ONOSbench.handle.expect(":~")
+            main.log.info("Stopping intentperf" )
+
+            with open("/tmp/IntentEventTPflowObjDB", "a") as resultsDB:
+                for node in groupResult:
+                    resultString = "'" + commit + "',"
+                    resultString += "'1gig',"
+                    resultString += str(clusterCount) + ","
+                    resultString += "'baremetal" + str(int(groupResult.index(node)) + 1) + "',"
+                    resultString += n + ","
+                    resultString += str(node) + ","
+                    resultString += str(0) + "\n" #no stddev
+                    resultsDB.write(resultString)
+            resultsDB.close()
+            main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"])
+
+    def CASE3( self, main ):
+        main.step("Set Intent Compiler use Flow Object")
+        stepResult = utilities.retry( main.ONOSbench.onosCfgSet,
+                                      main.FALSE,
+                                      args=[ ONOSIp[0],
+                                        "org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator",
+                                        "useFlowObjectives true" ],
+                                      sleep=3,
+                                      attempts=3 )
+        utilities.assert_equals( expect = main.TRUE,
+                                  actual = stepResult,
+                                  onpass = "Successfully set Intent compiler use Flow object",
+                                  onfail = "Failed to set up" )
diff --git a/TestON/tests/SCPF/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.topo b/TestON/tests/SCPF/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.topo
new file mode 100644
index 0000000..915d033
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentEventTpWithFlowObj/SCPFintentEventTpWithFlowObj.topo
@@ -0,0 +1,147 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+                <home>~/onos</home>
+                <nodes>7</nodes> 
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOS1cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1cli>
+
+        <ONOS2cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2cli>
+
+        <ONOS3cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3cli>
+
+        <ONOS4cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4cli>
+
+        <ONOS5cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5cli>
+
+        <ONOS6cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6cli>
+
+        <ONOS7cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</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/SCPF/SCPFintentEventTpWithFlowObj/__init__.py b/TestON/tests/SCPF/SCPFintentEventTpWithFlowObj/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentEventTpWithFlowObj/__init__.py
diff --git a/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/README b/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/README
new file mode 100644
index 0000000..6f7e09a
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/README
@@ -0,0 +1,30 @@
+INTENT INSTALL/WITHDRAW LATENCY
+
+Summary: This is a performance test designed to benchmark the
+    latency of installing intents and withdrawing intents. (intent
+    install and intent withdraw are separate operations with
+    independent time data)
+
+Pre-requisites: To run out-of-the box this test requires 7 NODES.
+    OC1->OC7 must be set before initiating the test. Passwordless
+    login must be set from TestStation "sdn" root user.
+
+***If you wish to run this test with less than 7 nodes the
+    following alterations must be made:
+
+NOTE: Only scale sizes 1,3,5 and 7 will be functional
+
+Modifying .params file:
+-- Remove any values in the comma separated list in the <scale>
+    tag that are above your desired cluster size.
+
+-- Remove one instance of “1,2” from the <testcases> tag for each
+    value you removed from <scale> (case 1 and 2 are each called
+    once for each scale value)
+
+-- Change the value in the <max> tag to your desired scale size (1,3,5)
+
+Modifying .topo file:
+-- Change the <ONOSbench/COMPONENTS/nodes> tag to your desired scale size
+
+-- Remove all unneeded <ONOS#cli> tags and their contents
diff --git a/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/SCPFintentInstallWithdrawLat.params b/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/SCPFintentInstallWithdrawLat.params
new file mode 100644
index 0000000..71f48fe
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/SCPFintentInstallWithdrawLat.params
@@ -0,0 +1,66 @@
+<PARAMS>
+
+    <testcases>1,2,1,2,1,2,1,2</testcases>
+
+    <SCALE>1,3,5,7</SCALE>
+    <max>7</max>
+
+    <ENV>
+        <cellName>IntentInstallWithdrawCell</cellName>
+        <cellApps>drivers,null</cellApps>
+    </ENV>
+
+    <TEST>
+        <skipCleanInstall>yes</skipCleanInstall>
+        <switchCount>7</switchCount>
+        <warmUp>5</warmUp>
+        <sampleSize>20</sampleSize>
+        <wait></wait>
+        <intents>1,100,1000</intents>                       #list format, will be split on ','
+        <debug>True</debug>                                        #"True" for true
+    </TEST>
+
+    <GIT>
+        <autopull>off</autopull>
+        <checkout>master</checkout>
+    </GIT>
+
+    <CTRL>
+        <USER>sdn</USER>
+
+        <ip1>OC1</ip1>
+        <port1>6653</port1>
+
+        <ip2>OC2</ip2>
+        <port2>6653</port2>
+
+        <ip3>OC3</ip3>
+        <port3>6653</port3>
+
+        <ip4>OC4</ip4>
+        <port4>6653</port4>
+
+        <ip5>OC5</ip5>
+        <port5>6653</port5>
+
+        <ip6>OC6</ip6>
+        <port6>6653</port6>
+
+        <ip7>OC7</ip7>
+        <port7>6653</port7>
+
+    </CTRL>
+
+    <MN>
+        <ip1>localhost</ip1>
+    </MN>
+
+    <BENCH>
+        <user>sdn</user>
+        <ip1>localhost</ip1>
+    </BENCH>
+
+    <JSON>
+    </JSON>
+
+</PARAMS>
diff --git a/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/SCPFintentInstallWithdrawLat.py b/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/SCPFintentInstallWithdrawLat.py
new file mode 100644
index 0000000..325cdbf
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/SCPFintentInstallWithdrawLat.py
@@ -0,0 +1,273 @@
+# ScaleOutTemplate
+#
+# CASE1 starts number of nodes specified in param file
+#
+# cameron@onlab.us
+
+import sys
+import os.path
+
+
+class SCPFintentInstallWithdrawLat:
+
+    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' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+        MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+        main.maxNodes = int(main.params[ 'max' ])
+        skipMvn = main.params[ 'TEST' ][ 'skipCleanInstall' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        switchCount = main.params[ 'TEST' ][ 'switchCount' ]
+
+        # -- 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())
+
+            #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("/tmp/IntentInstallWithdrawLatDB", "w+")
+            resultsDB.close()
+
+        # -- END OF INIT SECTION --#
+
+        clusterCount = int(scale[0])
+        scale.remove(scale[0])
+
+        #kill off all onos processes
+        main.log.step("Safety check, killing all ONOS processes")
+        main.log.step("before initiating environment setup")
+        for node in range(1, main.maxNodes + 1):
+            main.ONOSbench.onosDie(ONOSIp[node])
+
+        #Uninstall everywhere
+        main.log.step( "Cleaning Enviornment..." )
+        for i in range(1, main.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( "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!" )
+
+        main.ONOS1cli.startOnosCli( ONOSIp[1] )
+        main.log.info("Startup sequence complete")
+
+        time.sleep(30)
+
+        for i in range(3):
+            main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.provider.nil.NullProviders", ("deviceCount " + str(switchCount)) )
+            main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "topoShape linear")
+            main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "enabled true")
+            if main.ONOSbench.verifySummary(ONOSIp[1], switchCount):
+                break
+            else:
+                print "Failed- looping"
+
+        main.ONOSbench.handle.sendline("""onos $OC1 "balance-masters" """)
+        main.ONOSbench.handle.expect(":~")
+        main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"])
+
+    def CASE2( self, main ):
+
+        import time
+        import numpy
+
+        testStatus = "pass"
+        sampleSize = int(main.params[ 'TEST' ][ 'sampleSize' ])
+        warmUp = int(main.params[ 'TEST' ][ 'warmUp' ])
+        intentsList = (main.params[ 'TEST' ][ 'intents' ]).split(",")
+        switchCount = int(main.params[ 'TEST' ][ 'switchCount' ])
+        debug = main.params[ 'TEST' ][ 'switchCount' ]
+        for i in range(0,len(intentsList)):
+            intentsList[i] = int(intentsList[i])
+
+        ######################
+        debug = True
+        ######################
+
+        linkCount = 0
+        for i in range(0,10):
+            main.ONOSbench.handle.sendline("onos $OC1 links|wc -l")
+            main.ONOSbench.handle.expect(":~")
+            linkCount = main.ONOSbench.handle.before
+            if debug: main.log.info("Link Count check: " + linkCount)
+            if str((switchCount*2)-2) in linkCount:
+                break
+            time.sleep(2)
+
+        links = "--"
+        for i in range(8):
+            if debug: main.log.info("top of loop")
+            main.ONOSbench.handle.sendline("onos $OC1 links")
+            main.ONOSbench.handle.expect(":~")
+            links = main.ONOSbench.handle.before
+            if "=null:" in links:
+                break
+            if debug: main.log.info(str(links))
+            if i > 3:
+                main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"], "d")
+            if i == 7:
+                main.log.error("link data missing")
+            time.sleep(3)
+
+        links = links.splitlines()
+        templinks = links
+
+        tempDevices = []
+        for line in links:
+            temp = line.split(" ")
+            temp[0].replace("src=","")
+            temp[0] = (temp[0].split("/"))[0]
+            tempDevices.append(temp[0])
+
+        tempDevices.sort()
+        devices = []
+        for i in tempDevices:
+            if "src=null" in i:
+                devices.append(i.replace("src=", ""))
+        if debug: main.log.info(str(devices))
+
+        ingress = devices[0]
+        egress = devices.pop()
+        if debug: main.log.info(ingress)
+        if debug: main.log.info(egress)
+
+        for intentSize in intentsList:
+            cmd = "onos $OC1 push-test-intents "
+            cmd += ingress + "/6 "
+            cmd += egress + "/5 "
+            cmd += str(intentSize) + " 1"
+            installed = []
+            withdrawn = []
+            testStatus = ""
+
+            for run in range(0, (warmUp + sampleSize)):
+                if run > warmUp:
+                    time.sleep(5)
+
+                myRawResult = "--"
+
+                main.ONOSbench.handle.sendline(cmd)
+                main.ONOSbench.handle.expect(":~")
+                myRawResult = main.ONOSbench.handle.before
+
+                if debug: main.log.info(myRawResult)
+
+                if run >= warmUp:
+                    myRawResult = myRawResult.splitlines()
+                    for line in myRawResult:
+                        if "Failure:" in line:
+                            main.log.error("INTENT TEST FAILURE, ABORTING TESTCASE")
+                            testStatus = "fail"
+                            break
+
+                        if "install" in line:
+                            installed.append(int(line.split(" ")[5]))
+
+                        if "withdraw" in line:
+                            withdrawn.append(int(line.split(" ")[5]))
+
+                if testStatus == "fail":
+                    main.log.info("Installed: " + str(installed))
+                    main.log.info("Withdrawn: " + str(withdrawn))
+                    main.log.info("Scale: " + str(clusterCount))
+                    main.log.info("Warmup: " + str(warmUp) + " SampleSize: " + str(sampleSize))
+                    main.log.info("Run: " + str(run))
+                    main.log.error("Skipping test case")
+                    main.skipCase()
+
+            main.log.report("----------------------------------------------------")
+            main.log.report("Scale: " + str(clusterCount) + "\tIntent batch size: " + str(intentSize))
+            main.log.report("Data samples: " + str(sampleSize) + "\tWarm up tests: " + str(warmUp))
+            main.log.report("Installed average: " + str(numpy.mean(installed)))
+            main.log.report("Installed standard deviation: " + str(numpy.std(installed)))
+            main.log.report("Withdraw average: " + str(numpy.mean(withdrawn)))
+            main.log.report("Withdraw standard deviation: " + str(numpy.std(withdrawn)))
+            main.log.report("     ")
+
+            resultString = "'" + commit + "',"
+            resultString += str(clusterCount) + ","
+            resultString += str(intentSize) + ","
+            resultString += str(numpy.mean(installed)) + ","
+            resultString += str(numpy.std(installed)) + ","
+            resultString += str(numpy.mean(withdrawn)) + ","
+            resultString += str(numpy.std(withdrawn)) + "\n"
+            resultsDB = open("/tmp/IntentInstallWithdrawLatDB", "a")
+            resultsDB.write(resultString)
+            resultsDB.close()
+
+            main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"])
+            time.sleep(20)
diff --git a/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/SCPFintentInstallWithdrawLat.topo b/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/SCPFintentInstallWithdrawLat.topo
new file mode 100644
index 0000000..915d033
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/SCPFintentInstallWithdrawLat.topo
@@ -0,0 +1,147 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+                <home>~/onos</home>
+                <nodes>7</nodes> 
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOS1cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1cli>
+
+        <ONOS2cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2cli>
+
+        <ONOS3cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3cli>
+
+        <ONOS4cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4cli>
+
+        <ONOS5cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5cli>
+
+        <ONOS6cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6cli>
+
+        <ONOS7cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</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/SCPF/SCPFintentInstallWithdrawLat/__init__.py b/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/__init__.py
diff --git a/TestON/tests/SCPF/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.params b/TestON/tests/SCPF/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.params
new file mode 100644
index 0000000..71f48fe
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.params
@@ -0,0 +1,66 @@
+<PARAMS>
+
+    <testcases>1,2,1,2,1,2,1,2</testcases>
+
+    <SCALE>1,3,5,7</SCALE>
+    <max>7</max>
+
+    <ENV>
+        <cellName>IntentInstallWithdrawCell</cellName>
+        <cellApps>drivers,null</cellApps>
+    </ENV>
+
+    <TEST>
+        <skipCleanInstall>yes</skipCleanInstall>
+        <switchCount>7</switchCount>
+        <warmUp>5</warmUp>
+        <sampleSize>20</sampleSize>
+        <wait></wait>
+        <intents>1,100,1000</intents>                       #list format, will be split on ','
+        <debug>True</debug>                                        #"True" for true
+    </TEST>
+
+    <GIT>
+        <autopull>off</autopull>
+        <checkout>master</checkout>
+    </GIT>
+
+    <CTRL>
+        <USER>sdn</USER>
+
+        <ip1>OC1</ip1>
+        <port1>6653</port1>
+
+        <ip2>OC2</ip2>
+        <port2>6653</port2>
+
+        <ip3>OC3</ip3>
+        <port3>6653</port3>
+
+        <ip4>OC4</ip4>
+        <port4>6653</port4>
+
+        <ip5>OC5</ip5>
+        <port5>6653</port5>
+
+        <ip6>OC6</ip6>
+        <port6>6653</port6>
+
+        <ip7>OC7</ip7>
+        <port7>6653</port7>
+
+    </CTRL>
+
+    <MN>
+        <ip1>localhost</ip1>
+    </MN>
+
+    <BENCH>
+        <user>sdn</user>
+        <ip1>localhost</ip1>
+    </BENCH>
+
+    <JSON>
+    </JSON>
+
+</PARAMS>
diff --git a/TestON/tests/SCPF/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.py b/TestON/tests/SCPF/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.py
new file mode 100644
index 0000000..ec47721
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.py
@@ -0,0 +1,274 @@
+# ScaleOutTemplate
+#
+# CASE1 starts number of nodes specified in param file
+#
+# cameron@onlab.us
+
+import sys
+import os.path
+
+
+class SCPFintentInstallWithdrawLatWithFlowObj:
+
+    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' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+        MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+        main.maxNodes = int(main.params[ 'max' ])
+        skipMvn = main.params[ 'TEST' ][ 'skipCleanInstall' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        switchCount = main.params[ 'TEST' ][ 'switchCount' ]
+
+        # -- 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())
+
+            #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("/tmp/IntentInstallWithdrawLatDBWFO", "w+")
+            resultsDB.close()
+
+        # -- END OF INIT SECTION --#
+
+        clusterCount = int(scale[0])
+        scale.remove(scale[0])
+
+        #kill off all onos processes
+        main.log.step("Safety check, killing all ONOS processes")
+        main.log.step("before initiating environment setup")
+        for node in range(1, main.maxNodes + 1):
+            main.ONOSbench.onosDie(ONOSIp[node])
+
+        #Uninstall everywhere
+        main.log.step( "Cleaning Enviornment..." )
+        for i in range(1, main.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( "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!" )
+
+        main.ONOS1cli.startOnosCli( ONOSIp[1] )
+        main.log.info("Startup sequence complete")
+
+        time.sleep(30)
+
+        for i in range(3):
+            main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.provider.nil.NullProviders", ("deviceCount " + str(switchCount)) )
+            main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "topoShape linear")
+            main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "enabled true")
+            main.ONOS1cli.setCfg( "org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator"," useFlowObjectives","true" )
+            if main.ONOSbench.verifySummary(ONOSIp[1], switchCount):
+                break
+            else:
+                print "Failed- looping"
+
+        main.ONOSbench.handle.sendline("""onos $OC1 "balance-masters" """)
+        main.ONOSbench.handle.expect(":~")
+        main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"])
+
+    def CASE2( self, main ):
+
+        import time
+        import numpy
+
+        testStatus = "pass"
+        sampleSize = int(main.params[ 'TEST' ][ 'sampleSize' ])
+        warmUp = int(main.params[ 'TEST' ][ 'warmUp' ])
+        intentsList = (main.params[ 'TEST' ][ 'intents' ]).split(",")
+        switchCount = int(main.params[ 'TEST' ][ 'switchCount' ])
+        debug = main.params[ 'TEST' ][ 'switchCount' ]
+        for i in range(0,len(intentsList)):
+            intentsList[i] = int(intentsList[i])
+
+        ######################
+        debug = True
+        ######################
+
+        linkCount = 0
+        for i in range(0,10):
+            main.ONOSbench.handle.sendline("onos $OC1 links|wc -l")
+            main.ONOSbench.handle.expect(":~")
+            linkCount = main.ONOSbench.handle.before
+            if debug: main.log.info("Link Count check: " + linkCount)
+            if str((switchCount*2)-2) in linkCount:
+                break
+            time.sleep(2)
+
+        links = "--"
+        for i in range(8):
+            if debug: main.log.info("top of loop")
+            main.ONOSbench.handle.sendline("onos $OC1 links")
+            main.ONOSbench.handle.expect(":~")
+            links = main.ONOSbench.handle.before
+            if "=null:" in links:
+                break
+            if debug: main.log.info(str(links))
+            if i > 3:
+                main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"], "d")
+            if i == 7:
+                main.log.error("link data missing")
+            time.sleep(3)
+
+        links = links.splitlines()
+        templinks = links
+
+        tempDevices = []
+        for line in links:
+            temp = line.split(" ")
+            temp[0].replace("src=","")
+            temp[0] = (temp[0].split("/"))[0]
+            tempDevices.append(temp[0])
+
+        tempDevices.sort()
+        devices = []
+        for i in tempDevices:
+            if "src=null" in i:
+                devices.append(i.replace("src=", ""))
+        if debug: main.log.info(str(devices))
+
+        ingress = devices[0]
+        egress = devices.pop()
+        if debug: main.log.info(ingress)
+        if debug: main.log.info(egress)
+
+        for intentSize in intentsList:
+            cmd = "onos $OC1 push-test-intents "
+            cmd += ingress + "/6 "
+            cmd += egress + "/5 "
+            cmd += str(intentSize) + " 1"
+            installed = []
+            withdrawn = []
+            testStatus = ""
+
+            for run in range(0, (warmUp + sampleSize)):
+                if run > warmUp:
+                    time.sleep(5)
+
+                myRawResult = "--"
+
+                main.ONOSbench.handle.sendline(cmd)
+                main.ONOSbench.handle.expect(":~")
+                myRawResult = main.ONOSbench.handle.before
+
+                if debug: main.log.info(myRawResult)
+
+                if run >= warmUp:
+                    myRawResult = myRawResult.splitlines()
+                    for line in myRawResult:
+                        if "Failure:" in line:
+                            main.log.error("INTENT TEST FAILURE, ABORTING TESTCASE")
+                            testStatus = "fail"
+                            break
+
+                        if "install" in line:
+                            installed.append(int(line.split(" ")[5]))
+
+                        if "withdraw" in line:
+                            withdrawn.append(int(line.split(" ")[5]))
+
+                if testStatus == "fail":
+                    main.log.info("Installed: " + str(installed))
+                    main.log.info("Withdrawn: " + str(withdrawn))
+                    main.log.info("Scale: " + str(clusterCount))
+                    main.log.info("Warmup: " + str(warmUp) + " SampleSize: " + str(sampleSize))
+                    main.log.info("Run: " + str(run))
+                    main.log.error("Skipping test case")
+                    main.skipCase()
+
+            main.log.report("----------------------------------------------------")
+            main.log.report("Scale: " + str(clusterCount) + "\tIntent batch size: " + str(intentSize))
+            main.log.report("Data samples: " + str(sampleSize) + "\tWarm up tests: " + str(warmUp))
+            main.log.report("Installed average: " + str(numpy.mean(installed)))
+            main.log.report("Installed standard deviation: " + str(numpy.std(installed)))
+            main.log.report("Withdraw average: " + str(numpy.mean(withdrawn)))
+            main.log.report("Withdraw standard deviation: " + str(numpy.std(withdrawn)))
+            main.log.report("     ")
+
+            resultString = "'" + commit + "',"
+            resultString += str(clusterCount) + ","
+            resultString += str(intentSize) + ","
+            resultString += str(numpy.mean(installed)) + ","
+            resultString += str(numpy.std(installed)) + ","
+            resultString += str(numpy.mean(withdrawn)) + ","
+            resultString += str(numpy.std(withdrawn)) + "\n"
+            resultsDB = open("/tmp/IntentInstallWithdrawLatDBWFO", "a")
+            resultsDB.write(resultString)
+            resultsDB.close()
+
+            main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"])
+            time.sleep(20)
diff --git a/TestON/tests/SCPF/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.topo b/TestON/tests/SCPF/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.topo
new file mode 100644
index 0000000..915d033
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentInstallWithdrawLatWithFlowObj/SCPFintentInstallWithdrawLatWithFlowObj.topo
@@ -0,0 +1,147 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+                <home>~/onos</home>
+                <nodes>7</nodes> 
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOS1cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1cli>
+
+        <ONOS2cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2cli>
+
+        <ONOS3cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3cli>
+
+        <ONOS4cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4cli>
+
+        <ONOS5cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5cli>
+
+        <ONOS6cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6cli>
+
+        <ONOS7cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</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/SCPF/SCPFintentInstallWithdrawLatWithFlowObj/__init__.py b/TestON/tests/SCPF/SCPFintentInstallWithdrawLatWithFlowObj/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentInstallWithdrawLatWithFlowObj/__init__.py
diff --git a/TestON/tests/SCPF/SCPFintentRerouteLat/README b/TestON/tests/SCPF/SCPFintentRerouteLat/README
new file mode 100644
index 0000000..26b551b
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentRerouteLat/README
@@ -0,0 +1,29 @@
+INTENT REROUTE LATENCY
+
+Summary: This is a performance test designed to benchmark the
+    intent reroute speed of ONOS at various controller cluster sizes.
+
+Pre-requisites: To run out-of-the box this test requires 7 NODES.
+    OC1->OC7 must be set before initiating the test. Passwordless login
+    must be set from TestStation "sdn" root user.
+
+***If you wish to run this test with less than 7 nodes the
+    following alterations must be made:
+
+NOTE: Only scale sizes 1,3,5 and 7 will be functional
+
+Modifying .params file:
+-- Remove any values in the comma separated list in
+    the <scale> tag that are above your desired cluster size.
+
+-- Remove one instance of “1,2” from the <testcases> tag for
+    each value you removed from <scale> (case1 and 2 are each
+    called once for each scale value)
+
+-- Change the value in the <max> tag to your desired scale size (1,3,5)
+
+Modifying .topo file:
+-- Change the <ONOSbench/COMPONENTS/nodes> tag to
+    your desired scale size
+
+-- Remove all unneeded <ONOS#cli> tags and their contents
diff --git a/TestON/tests/SCPF/SCPFintentRerouteLat/SCPFintentRerouteLat.params b/TestON/tests/SCPF/SCPFintentRerouteLat/SCPFintentRerouteLat.params
new file mode 100644
index 0000000..3799982
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentRerouteLat/SCPFintentRerouteLat.params
@@ -0,0 +1,79 @@
+<PARAMS>
+
+    <testcases>1,2,1,2,1,2,1,2</testcases>
+
+    <SCALE>1,3,5,7</SCALE>
+    <max>7</max>
+
+    <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>sdn</USER>
+
+        <ip1>OC1</ip1>
+        <port1>6653</port1>
+
+        <ip2>OC2</ip2>
+        <port2>6653</port2>
+
+        <ip3>OC3</ip3>
+        <port3>6653</port3>
+
+        <ip4>OC4</ip4>
+        <port4>6653</port4>
+
+        <ip5>OC5</ip5>
+        <port5>6653</port5>
+
+        <ip6>OC6</ip6>
+        <port6>6653</port6>
+
+        <ip7>OC7</ip7>
+        <port7>6653</port7>
+
+    </CTRL>
+
+    <MN>
+        <ip1>localhost</ip1>
+    </MN>
+
+    <BENCH>
+        <user>sdn</user>
+        <ip1>localhost</ip1>
+    </BENCH>
+
+    <JSON>
+    </JSON>
+
+</PARAMS>
diff --git a/TestON/tests/SCPF/SCPFintentRerouteLat/SCPFintentRerouteLat.py b/TestON/tests/SCPF/SCPFintentRerouteLat/SCPFintentRerouteLat.py
new file mode 100644
index 0000000..7d70d7f
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentRerouteLat/SCPFintentRerouteLat.py
@@ -0,0 +1,419 @@
+# 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' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+        main.maxNodes = int(main.params[ 'max' ])
+        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("/tmp/IntentRerouteLatDB", "w+")
+            resultsDB.close()
+
+        # -- END OF INIT SECTION --#
+
+        clusterCount = int(scale[0])
+        scale.remove(scale[0])
+
+        #kill off all onos processes
+        main.log.step("Safety check, killing all ONOS processes")
+        main.log.step("before initiating environment setup")
+        for node in range(1, main.maxNodes + 1):
+            main.ONOSbench.onosDie(ONOSIp[node])
+
+        #Uninstall everywhere
+        main.log.step( "Cleaning Enviornment..." )
+        for i in range(1, main.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()
+
+        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)
+
+                if debug: main.log.debug("raw: " + raw)
+
+                temp = raw.splitlines()
+
+                if debug: main.log.debug("temp (after splitlines): " + str(temp))
+
+                # Since the string is deterministic the date is always the 3rd element.
+                # However, if the data were grepping for in the onos log changes then this will
+                # not work. This is why we print out the raw and temp string so we can visually
+                # check if everything is in the correct order. temp should like this:
+                # temp = ['/onos$ onos-ssh $OC1 cat /opt/onos/log/karaf.log | grep Top ', 
+                #         'ologyManager| tail -1', '2015-10-15 12:03:33,736 ... ]
+                temp = temp[2]
+
+                if debug: main.log.debug("temp (checking for date): " + str(temp))
+
+                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("/tmp/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/SCPF/SCPFintentRerouteLat/SCPFintentRerouteLat.topo b/TestON/tests/SCPF/SCPFintentRerouteLat/SCPFintentRerouteLat.topo
new file mode 100644
index 0000000..915d033
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentRerouteLat/SCPFintentRerouteLat.topo
@@ -0,0 +1,147 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+                <home>~/onos</home>
+                <nodes>7</nodes> 
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOS1cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1cli>
+
+        <ONOS2cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2cli>
+
+        <ONOS3cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3cli>
+
+        <ONOS4cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4cli>
+
+        <ONOS5cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5cli>
+
+        <ONOS6cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6cli>
+
+        <ONOS7cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</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/SCPF/SCPFintentRerouteLat/__init__.py b/TestON/tests/SCPF/SCPFintentRerouteLat/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentRerouteLat/__init__.py
diff --git a/TestON/tests/SCPF/SCPFintentRerouteLatWithFlowObj/README b/TestON/tests/SCPF/SCPFintentRerouteLatWithFlowObj/README
new file mode 100644
index 0000000..26b551b
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentRerouteLatWithFlowObj/README
@@ -0,0 +1,29 @@
+INTENT REROUTE LATENCY
+
+Summary: This is a performance test designed to benchmark the
+    intent reroute speed of ONOS at various controller cluster sizes.
+
+Pre-requisites: To run out-of-the box this test requires 7 NODES.
+    OC1->OC7 must be set before initiating the test. Passwordless login
+    must be set from TestStation "sdn" root user.
+
+***If you wish to run this test with less than 7 nodes the
+    following alterations must be made:
+
+NOTE: Only scale sizes 1,3,5 and 7 will be functional
+
+Modifying .params file:
+-- Remove any values in the comma separated list in
+    the <scale> tag that are above your desired cluster size.
+
+-- Remove one instance of “1,2” from the <testcases> tag for
+    each value you removed from <scale> (case1 and 2 are each
+    called once for each scale value)
+
+-- Change the value in the <max> tag to your desired scale size (1,3,5)
+
+Modifying .topo file:
+-- Change the <ONOSbench/COMPONENTS/nodes> tag to
+    your desired scale size
+
+-- Remove all unneeded <ONOS#cli> tags and their contents
diff --git a/TestON/tests/SCPF/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.params b/TestON/tests/SCPF/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.params
new file mode 100644
index 0000000..3799982
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.params
@@ -0,0 +1,79 @@
+<PARAMS>
+
+    <testcases>1,2,1,2,1,2,1,2</testcases>
+
+    <SCALE>1,3,5,7</SCALE>
+    <max>7</max>
+
+    <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>sdn</USER>
+
+        <ip1>OC1</ip1>
+        <port1>6653</port1>
+
+        <ip2>OC2</ip2>
+        <port2>6653</port2>
+
+        <ip3>OC3</ip3>
+        <port3>6653</port3>
+
+        <ip4>OC4</ip4>
+        <port4>6653</port4>
+
+        <ip5>OC5</ip5>
+        <port5>6653</port5>
+
+        <ip6>OC6</ip6>
+        <port6>6653</port6>
+
+        <ip7>OC7</ip7>
+        <port7>6653</port7>
+
+    </CTRL>
+
+    <MN>
+        <ip1>localhost</ip1>
+    </MN>
+
+    <BENCH>
+        <user>sdn</user>
+        <ip1>localhost</ip1>
+    </BENCH>
+
+    <JSON>
+    </JSON>
+
+</PARAMS>
diff --git a/TestON/tests/SCPF/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.py b/TestON/tests/SCPF/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.py
new file mode 100644
index 0000000..439ecef
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.py
@@ -0,0 +1,419 @@
+# ScaleOutTemplate
+#
+# CASE1 starts number of nodes specified in param file
+#
+# cameron@onlab.us
+
+import sys
+import os.path
+
+
+class SCPFintentRerouteLatWithFlowObj:
+
+    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' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+        main.maxNodes = int(main.params[ 'max' ])
+        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("/tmp/IntentRerouteLatDBWithFlowObj", "w+")
+            resultsDB.close()
+
+        # -- END OF INIT SECTION --#
+
+        clusterCount = int(scale[0])
+        scale.remove(scale[0])
+
+        #kill off all onos processes
+        main.log.step("Safety check, killing all ONOS processes")
+        main.log.step("before initiating environment setup")
+        for node in range(1, main.maxNodes + 1):
+            main.ONOSbench.onosDie(ONOSIp[node])
+
+        #Uninstall everywhere
+        main.log.step( "Cleaning Enviornment..." )
+        for i in range(1, main.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")
+            main.ONOSbench.onosCfgSet( ONOSIp[1], "org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator", "useFlowObjectives 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()
+
+        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)
+
+                if debug: main.log.debug("raw: " + raw)
+
+                temp = raw.splitlines()
+
+                if debug: main.log.debug("temp (after splitlines): " + str(temp))
+
+                # Since the string is deterministic the date is always the 3rd element.
+                # However, if the data were grepping for in the onos log changes then this will
+                # not work. This is why we print out the raw and temp string so we can visually
+                # check if everything is in the correct order. temp should like this:
+                # temp = ['/onos$ onos-ssh $OC1 cat /opt/onos/log/karaf.log | grep Top ', 
+                #         'ologyManager| tail -1', '2015-10-15 12:03:33,736 ... ]
+                temp = temp[2]
+
+                if debug: main.log.debug("temp (checking for date): " + str(temp))
+
+                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("/tmp/IntentRerouteLatDBWithFlowObj", "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/SCPF/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.topo b/TestON/tests/SCPF/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.topo
new file mode 100644
index 0000000..915d033
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentRerouteLatWithFlowObj/SCPFintentRerouteLatWithFlowObj.topo
@@ -0,0 +1,147 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+                <home>~/onos</home>
+                <nodes>7</nodes> 
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOS1cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1cli>
+
+        <ONOS2cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2cli>
+
+        <ONOS3cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3cli>
+
+        <ONOS4cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4cli>
+
+        <ONOS5cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5cli>
+
+        <ONOS6cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6cli>
+
+        <ONOS7cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</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/SCPF/SCPFintentRerouteLatWithFlowObj/__init__.py b/TestON/tests/SCPF/SCPFintentRerouteLatWithFlowObj/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFintentRerouteLatWithFlowObj/__init__.py
diff --git a/TestON/tests/SCPF/SCPFmaxIntents/Dependency/maxIntentFunctions.py b/TestON/tests/SCPF/SCPFmaxIntents/Dependency/maxIntentFunctions.py
new file mode 100644
index 0000000..268279c
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFmaxIntents/Dependency/maxIntentFunctions.py
@@ -0,0 +1,114 @@
+'''
+    Wrapper functions for maxIntent
+'''
+
+import json
+import time
+import pexpect
+
+def __init__( self ):
+    self.default = ""
+
+def getIntents( main, state="INSTALLED", sleep=1, timeout=120 ):
+    intents = 0
+    try:
+        cmd = "intents | grep " + state + " | wc -l"
+        main.log.info("Sending: " + cmd)
+        main.CLIs[0].handle.sendline(cmd)
+
+        time.sleep(sleep)
+
+        main.CLIs[0].handle.expect("onos>", timeout=timeout)
+        raw = main.CLIs[0].handle.before
+        intents = int(main.CLIs[0].handle.before.split()[7])
+        main.log.info(state + " intents: " + str(intents))
+    except pexpect.TIMEOUT:
+        main.log.exception("Timeout exception caught in getIntent")
+    return intents
+
+def getFlows( main, state="ADDED", sleep=1, timeout=120 ):
+    flows = 0
+    try:
+        cmd = "flows | grep " + state + " | wc -l"
+        main.log.info("Sending: " + cmd)
+        main.CLIs[0].handle.sendline(cmd)
+
+        time.sleep(sleep)
+
+        main.CLIs[0].handle.expect("onos>", timeout=timeout)
+        raw = main.CLIs[0].handle.before
+        flows = int(main.CLIs[0].handle.before.split()[7])
+        main.log.info(state + " flows: " + str(flows))
+    except pexpect.TIMEOUT:
+        main.log.exception("Timeout exception caught in getFlows")
+    return flows
+
+
+def pushIntents( main,
+                 switch,
+                 ingress,
+                 egress,
+                 batch,
+                 offset,
+                 sleep=1,
+                 options="",
+                 timeout=120):
+    '''
+        Pushes intents using the push-test-intents cli command.
+    '''
+    try:
+        cmd = "push-test-intents " + options + " " + switch + ingress + " " +\
+                switch + egress + " " + str(batch) + " " + str(offset)
+        main.log.info("Installing " + str(offset+batch) + " intents")
+        main.log.debug("Sending: " + cmd)
+        main.CLIs[0].handle.sendline(cmd)
+        time.sleep(sleep)
+        main.CLIs[0].handle.expect("onos>", timeout=timeout)
+
+        raw = main.CLIs[0].handle.before
+        if "Failure:" not in raw and "GC" not in raw:
+            return main.TRUE
+    except pexpect.TIMEOUT:
+        main.log.exception("Timeout exception caught in pushIntents")
+    return main.FALSE
+
+def verifyFlows( main, expectedFlows, state="ADDED", sleep=1, numcheck=10, timeout=120):
+    '''
+        This function returns main.TRUE if the number of expected flows are in
+        the specified state
+
+        @params
+            expectedFlows: the flows you expect to see in the specified state
+            state: the state of the flow to check for
+            sleep: how long it should sleep for each check
+            numcheck: how many times it should check
+            timeout: the timeout for pexpect
+    '''
+    cmd = "flows | grep " + state + " | wc -l"
+    for i in range(numcheck):
+        flows = getFlows( main, state, sleep, timeout )
+        if expectedFlows == flows:
+            return main.TRUE
+
+    return main.FALSE
+
+def verifyIntents( main, expectedIntents, state="INSTALLED", sleep=1, numcheck=10, timeout=120):
+    '''
+        This function returns main.TRUE if the number of expected intents are in
+        the specified state
+
+        @params
+            expectedFlows: the intents you expect to see in the specified state
+            state: the state of the intent to check for
+            sleep: how long it should sleep for each check
+            numcheck: how many times it should check
+            timeout: the timeout for pexpect
+    '''
+    cmd = "intents | grep " + state + " | wc -l"
+    for i in range(numcheck):
+        intents = getIntents( main, state, sleep, timeout )
+        if expectedIntents == intents:
+            return main.TRUE
+        time.sleep(sleep)
+
+    return main.FALSE
diff --git a/TestON/tests/SCPF/SCPFmaxIntents/Dependency/rerouteTopo.py b/TestON/tests/SCPF/SCPFmaxIntents/Dependency/rerouteTopo.py
new file mode 100755
index 0000000..a2fe9fe
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFmaxIntents/Dependency/rerouteTopo.py
@@ -0,0 +1,53 @@
+#!/usr/bin/python
+
+"""
+Custom topology for Mininet
+"""
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import Host, RemoteController
+from mininet.node import Node
+from mininet.link import TCLink
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+from mininet.util import dumpNodeConnections
+from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+
+class MyTopo( Topo ):
+
+    def __init__( self ):
+        # Initialize topology
+        Topo.__init__( self )
+
+        host1 = self.addHost('h1', ip='10.1.0.1/24')
+        host2 = self.addHost('h2', ip='10.1.0.2/24')
+        host3 = self.addHost('h3', ip='10.1.0.3/24')
+
+        s1 = self.addSwitch( 's1' )
+        s2 = self.addSwitch( 's2' )
+        s3 = self.addSwitch( 's3' )
+
+        self.addLink(s1, host1)
+        self.addLink(s2, host2)
+        self.addLink(s3, host3)
+
+        self.addLink(s1,s2)
+        self.addLink(s1,s3)
+        self.addLink(s2,s3)
+
+        topos = { 'mytopo': ( lambda: MyTopo() ) }
+
+# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS
+
+def setupNetwork():
+    "Create network"
+    topo = MyTopo()
+    network = Mininet(topo=topo, autoSetMacs=True, controller=None)
+    network.start()
+    CLI( network )
+    network.stop()
+
+if __name__ == '__main__':
+    setLogLevel('info')
+    #setLogLevel('debug')
+    setupNetwork()
diff --git a/TestON/tests/SCPF/SCPFmaxIntents/Dependency/startUp.py b/TestON/tests/SCPF/SCPFmaxIntents/Dependency/startUp.py
new file mode 100644
index 0000000..bf2a2b6
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFmaxIntents/Dependency/startUp.py
@@ -0,0 +1,38 @@
+"""
+    This wrapper function is use for starting up onos instance
+"""
+
+import time
+import os
+import json
+
+def onosBuild( main, gitBranch ):
+    """
+        This includes pulling ONOS and building it using maven install
+    """
+
+    buildResult = main.FALSE
+
+    # Git checkout a branch of ONOS
+    checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
+    # Does the git pull on the branch that was checked out
+    if not checkOutResult:
+        main.log.warn( "Failed to checked out " + gitBranch +
+                                           " branch")
+    else:
+        main.log.info( "Successfully checked out " + gitBranch +
+                                           " branch")
+    gitPullResult = main.ONOSbench.gitPull()
+    if gitPullResult == main.ERROR:
+        main.log.error( "Error pulling git branch" )
+    else:
+        main.log.info( "Successfully pulled " + gitBranch + " branch" )
+
+    # Maven clean install
+    buildResult = main.ONOSbench.cleanInstall()
+
+    return buildResult
+
+
+
+
diff --git a/TestON/tests/SCPF/SCPFmaxIntents/README b/TestON/tests/SCPF/SCPFmaxIntents/README
new file mode 100644
index 0000000..cb53df8
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFmaxIntents/README
@@ -0,0 +1,6 @@
+Summary:
+        This is a performance test suit, designed to test the upper limits
+        of onos and ovsdb with respect to installing intents and rerouting flows.
+NOTE:
+        This test is largely based on the hardware used to run onos and mininet.
+        Therefore, results will very test station to test station.
diff --git a/TestON/tests/SCPF/SCPFmaxIntents/SCPFmaxIntents.params b/TestON/tests/SCPF/SCPFmaxIntents/SCPFmaxIntents.params
new file mode 100755
index 0000000..56ad4d8
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFmaxIntents/SCPFmaxIntents.params
@@ -0,0 +1,103 @@
+<PARAMS>
+
+    # 1-init
+    # 2-setup
+    # 10-null provider setup
+    # 11-mininet setup
+    # 20-pushing intents, and rerouting intents if reroute is true
+    # 1,2,10,20,2,11,20,100
+    <testcases>1,2,10,20</testcases>
+
+    <reroute>False</reroute>
+
+    <SCALE>
+        <size>1</size>
+        <max>1</max>
+    </SCALE>
+
+    <DEPENDENCY>
+        <path>/tests/SCPFmaxIntents/dependencies/</path>
+        <wrapper1>startUp</wrapper1>
+        <wrapper2>maxIntentFunctions</wrapper2>
+        <topology>rerouteTopo.py</topology>
+    </DEPENDENCY>
+
+    <ENV>
+        <cellName>productionCell</cellName>
+        <cellApps>drivers</cellApps>
+    </ENV>
+
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
+
+    <CTRL>
+        <port>6653</port>
+    </CTRL>
+
+    <SLEEP>
+        <startup>3</startup>
+        <install>1</install>
+        <verify>5</verify>
+        <reroute>3</reroute>
+        # timeout for pexpect
+        <timeout>120</timeout>
+    </SLEEP>
+
+    <ATTEMPTS>
+        <verify>3</verify>
+        <push>3</push>
+    </ATTEMPTS>
+
+    <DATABASE>
+        <file>/tmp/MaxIntentDB</file>
+        <nic>1gig</nic>
+        <node>baremetal</node>
+    </DATABASE>
+
+    <LINK>
+        <ingress>0000000000000001/9</ingress>
+        <egress>0000000000000002/9</egress>
+    </LINK>
+
+    # CASE10
+    <NULL>
+        # CASE20
+        <PUSH>
+            <batch_size>1000</batch_size>
+            <min_intents>100000</min_intents>
+            <max_intents>1000000</max_intents>
+            <check_interval>100000</check_interval>
+        </PUSH>
+
+        # if reroute is true
+        <REROUTE>
+            <batch_size>1000</batch_size>
+            <min_intents>10000</min_intents>
+            <max_intents>10000</max_intents>
+            <check_interval>10000</check_interval>
+        </REROUTE>
+    </NULL>
+
+    # CASE11
+    <OVS>
+        # CASE20
+        <PUSH>
+            <batch_size>1000</batch_size>
+            <min_intents>10000</min_intents>
+            <max_intents>500000</max_intents>
+            <check_interval>10000</check_interval>
+        </PUSH>
+
+        # if reroute is true
+        <REROUTE>
+            <batch_size>1000</batch_size>
+            <min_intents>10000</min_intents>
+            <max_intents>500000</max_intents>
+            <check_interval>10000</check_interval>
+        </REROUTE>
+    </OVS>
+
+
+</PARAMS>
diff --git a/TestON/tests/SCPF/SCPFmaxIntents/SCPFmaxIntents.py b/TestON/tests/SCPF/SCPFmaxIntents/SCPFmaxIntents.py
new file mode 100644
index 0000000..4bca4da
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFmaxIntents/SCPFmaxIntents.py
@@ -0,0 +1,517 @@
+
+# This is a performance scale intent that test onos to see how many intents can
+# be installed and rerouted using the null provider and mininet.
+'''
+This test will not test on reroute and OVS!!!
+If you need test on reroute or OVS, change the params file
+
+Test information:
+    - BatchSize: 1000
+    - Minimum intents: 10,000
+    - Maximum Intents: 1,000,000
+    - Check Interval: 10,000
+    - Link:
+        - ingress: 0000000000000001/9
+        - egress: 0000000000000002/9
+    - Timeout: 120 Seconds
+'''
+
+class SCPFmaxIntents:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):
+        import time
+        import os
+        import imp
+
+        """
+        - Construct tests variables
+        - GIT ( optional )
+            - Checkout ONOS master branch
+            - Pull latest ONOS code
+        - Building ONOS ( optional )
+            - Install ONOS package
+            - Build ONOS package
+        - Set up cell
+            - Create cell file
+            - Set cell file
+            - Verify cell file
+        - Kill ONOS process
+        """
+
+        main.case( "Constructing test variables and building ONOS package" )
+        main.step( "Constructing test variables" )
+        stepResult = main.FALSE
+
+        # Test variables
+        main.testOnDirectory = os.path.dirname( os.getcwd ( ) )
+        main.dependencyPath = main.testOnDirectory + \
+                main.params['DEPENDENCY']['path']
+        main.cellName = main.params[ 'ENV' ][ 'cellName' ]
+        main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+        main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
+        main.scale = ( main.params[ 'SCALE' ][ 'size' ] ).split( "," )
+        main.maxNodes = int( main.params[ 'SCALE' ][ 'max' ] )
+        main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
+        main.timeout = int(main.params['SLEEP']['timeout'])
+        main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+        main.installSleep = int( main.params[ 'SLEEP' ][ 'install' ] )
+        main.verifySleep = int( main.params[ 'SLEEP' ][ 'verify' ] )
+        main.rerouteSleep = int ( main.params['SLEEP']['reroute'] )
+        main.verifyAttempts = int( main.params['ATTEMPTS']['verify'] )
+        main.ingress = main.params['LINK']['ingress']
+        main.egress = main.params['LINK']['egress']
+        main.dbFileName = main.params['DATABASE']['file']
+        main.cellData = {} # for creating cell file
+        main.reroute = main.params['reroute']
+        if main.reroute == "True":
+            main.reroute = True
+        else:
+            main.reroute = False
+        main.CLIs = []
+        main.ONOSip = []
+        main.maxNumBatch = 0
+        main.ONOSip = main.ONOSbench.getOnosIps()
+        main.log.info(main.ONOSip)
+        main.setupSkipped = False
+
+        wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
+        wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
+        gitBranch = main.params[ 'GIT' ][ 'branch' ]
+        gitPull = main.params[ 'GIT' ][ 'pull' ]
+        nic = main.params['DATABASE']['nic']
+        node = main.params['DATABASE']['node']
+        nic = main.params['DATABASE']['nic']
+        node = main.params['DATABASE']['node']
+
+        # main.scale[ 0 ] determines the current number of ONOS controller
+        main.numCtrls = int( main.scale[ 0 ] )
+
+        main.log.info("Creating list of ONOS cli handles")
+        for i in range(main.maxNodes):
+            main.CLIs.append( getattr( main, 'ONOScli' + str( i+1 )))
+
+        if not main.CLIs:
+            main.log.error("Failed to create the list of ONOS cli handles")
+            main.cleanup()
+            main.exit()
+
+        main.log.info("Loading wrapper files")
+        main.startUp = imp.load_source( wrapperFile1,
+                                        main.dependencyPath +
+                                        wrapperFile1 +
+                                        ".py" )
+
+        main.intentFunctions = imp.load_source( wrapperFile2,
+                                               main.dependencyPath +
+                                               wrapperFile2 +
+                                               ".py" )
+
+        copyResult = main.ONOSbench.copyMininetFile( main.topology,
+                                                    main.dependencyPath,
+                                                    main.Mininet1.user_name,
+                                                    main.Mininet1.ip_address )
+
+        commit = main.ONOSbench.getVersion(report=True)
+        commit = commit.split(" ")[1]
+
+        if gitPull == 'True':
+            if not main.startUp.onosBuild( main, gitBranch ):
+                main.log.error("Failed to build ONOS")
+                main.cleanup()
+                main.exit()
+        else:
+            main.log.warn( "Did not pull new code so skipping mvn " +
+                           "clean install" )
+
+        main.log.info( "Starting up %s node(s) ONOS cluster" % main.numCtrls)
+        main.log.info( "Safety check, killing all ONOS processes" +
+                       " before initiating environment setup" )
+
+        for i in range( main.maxNodes ):
+            main.ONOSbench.onosDie( main.ONOSip[ i ] )
+
+        main.log.info( "NODE COUNT = %s" % main.numCtrls)
+
+        tempOnosIp = []
+        for i in range( main.numCtrls ):
+            tempOnosIp.append( main.ONOSip[i] )
+
+        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
+                                       "temp",
+                                       main.Mininet1.ip_address,
+                                       main.apps,
+                                       tempOnosIp )
+
+        main.step( "Apply cell to environment" )
+        cellResult = main.ONOSbench.setCell( "temp" )
+        verifyResult = main.ONOSbench.verifyCell()
+        stepResult = cellResult and verifyResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully applied cell to " + \
+                                        "environment",
+                                 onfail="Failed to apply cell to environment " )
+
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.onosPackage()
+        stepResult = packageResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully created ONOS package",
+                                 onfail="Failed to create ONOS package" )
+
+        main.log.info("Creating DB file")
+        with open(main.dbFileName, "w+") as dbFile:
+            temp = "'" + commit + "',"
+            temp += "'" + nic + "',"
+            temp += str(main.numCtrls) + ","
+            temp += "'" + node + "1" + "'"
+            temp += ",0"
+            temp += ",0"
+            temp += ",0"
+            temp += ",0"
+            dbFile.write(temp)
+
+    def CASE2( self, main ):
+        """
+        - Uninstall ONOS cluster
+        - Verify ONOS start up
+        - Install ONOS cluster
+        - Connect to cli
+        """
+
+        main.step( "Installing ONOS with -f" )
+        onosInstallResult = main.TRUE
+        for i in range( main.numCtrls ):
+            onosInstallResult = onosInstallResult and \
+                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
+        stepResult = onosInstallResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully installed ONOS package",
+                                 onfail="Failed to install ONOS package" )
+
+        time.sleep( main.startUpSleep )
+
+        main.step( "Start ONOS cli" )
+        cliResult = main.TRUE
+        for i in range( main.numCtrls ):
+            cliResult = cliResult and \
+                        main.CLIs[ i ].startOnosCli( main.ONOSip[ i ] )
+        stepResult = cliResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully start ONOS cli",
+                                 onfail="Failed to start ONOS cli" )
+
+        time.sleep( main.startUpSleep )
+
+    def CASE10( self, main ):
+        """
+            Setting up null-provider
+        """
+        import json
+        # Activate apps
+        main.step("Activating null-provider")
+        appStatus = utilities.retry( main.CLIs[0].activateApp,
+                                     main.FALSE,
+                                     ['org.onosproject.null'],
+                                     sleep=main.verifySleep,
+                                     attempts=main.verifyAttempts )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=appStatus,
+                                 onpass="Successfully activated null-provider",
+                                 onfail="Failed activate null-provider" )
+
+        # Setup the null-provider
+        main.step("Configuring null-provider")
+        cfgStatus = utilities.retry( main.ONOSbench.onosCfgSet,
+                                     main.FALSE,
+                                     [ main.ONOSip[0],
+                                      'org.onosproject.provider.nil.NullProviders', 'deviceCount 3'],
+                                     sleep=main.verifySleep,
+                                     attempts = main.verifyAttempts )
+        cfgStatus = cfgStatus and utilities.retry( main.ONOSbench.onosCfgSet,
+                                                   main.FALSE,
+                                                   [ main.ONOSip[0],
+                                                     'org.onosproject.provider.nil.NullProviders', 'topoShape reroute'],
+                                                   sleep=main.verifySleep,
+                                                   attempts = main.verifyAttempts )
+
+        cfgStatus = cfgStatus and utilities.retry( main.ONOSbench.onosCfgSet,
+                                                   main.FALSE,
+                                                   [ main.ONOSip[0],
+                                                     'org.onosproject.provider.nil.NullProviders', 'enabled true'],
+                                                   sleep=main.verifySleep,
+                                                   attempts = main.verifyAttempts )
+
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=cfgStatus,
+                                 onpass="Successfully configured null-provider",
+                                 onfail="Failed to configure null-provider" )
+
+        # give onos some time to settle
+        time.sleep(main.startUpSleep)
+
+        main.log.info("Setting default flows to zero")
+        main.defaultFlows = 0
+
+        main.step("Check status of null-provider setup")
+        caseResult = appStatus and cfgStatus
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=caseResult,
+                                 onpass="Setting up null-provider was successfull",
+                                 onfail="Failed to setup null-provider" )
+
+        # This tells the following cases if we are using the null-provider or ovs
+        main.switchType = "null:"
+
+        # If the null-provider setup was unsuccessfull, then there is no point to
+        # run the subsequent cases
+        if not caseResult:
+            main.setupSkipped = True
+
+    def CASE11( self, main ):
+        '''
+            Setting up mininet
+        '''
+        import json
+        import time
+
+        time.sleep(main.startUpSleep)
+
+        main.step("Activating openflow")
+        appStatus = main.CLIs[0].activateApp('org.onosproject.openflow')
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=appStatus,
+                                 onpass="Successfully activated openflow",
+                                 onfail="Failed activate openflow" )
+
+        time.sleep(main.startUpSleep)
+
+        main.step('Starting mininet topology')
+        mnStatus = main.Mininet1.startNet(topoFile='~/mininet/custom/rerouteTopo.py')
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=mnStatus,
+                                 onpass="Successfully started Mininet",
+                                 onfail="Failed to activate Mininet" )
+
+        main.step("Assinging masters to switches")
+        switches = main.Mininet1.getSwitches()
+        swStatus = main.Mininet1.assignSwController( sw=switches.keys(), ip=main.ONOSip )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=swStatus,
+                                 onpass="Successfully assigned switches to masters",
+                                 onfail="Failed assign switches to masters" )
+
+        time.sleep(main.startUpSleep)
+
+        main.log.info("Getting default flows")
+        jsonSum = json.loads(main.CLIs[0].summary())
+        main.defaultFlows = jsonSum["flows"]
+
+        main.step("Check status of Mininet setup")
+        caseResult = appStatus and mnStatus and swStatus
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=caseResult,
+                                 onpass="Successfully setup Mininet",
+                                 onfail="Failed setup Mininet" )
+
+        # This tells the following cases if we are using the null-provider or ovs
+        main.switchType = "of:"
+
+        if not caseResult:
+            main.setupSkipped = True
+
+    def CASE20( self, main ):
+        '''
+            Pushing intents
+        '''
+
+        if main.reroute:
+            if main.switchType == "of:":
+                main.minIntents = int(main.params['OVS']['REROUTE']['min_intents'])
+                main.maxIntents = int(main.params['OVS']['REROUTE']['max_intents'])
+                main.checkInterval = int(main.params['OVS']['REROUTE']['check_interval'])
+                main.batchSize = int(main.params['OVS']['REROUTE']['batch_size'])
+            else:
+                main.minIntents = int(main.params['NULL']['REROUTE']['min_intents'])
+                main.maxIntents = int(main.params['NULL']['REROUTE']['max_intents'])
+                main.checkInterval = int(main.params['NULL']['REROUTE']['check_interval'])
+                main.batchSize = int(main.params['NULL']['REROUTE']['batch_size'])
+        else:
+            if main.switchType == "of:":
+                main.minIntents = int(main.params['OVS']['PUSH']['min_intents'])
+                main.maxIntents = int(main.params['OVS']['PUSH']['max_intents'])
+                main.checkInterval = int(main.params['OVS']['PUSH']['check_interval'])
+                main.batchSize = int(main.params['OVS']['PUSH']['batch_size'])
+            else:
+                main.minIntents = int(main.params['NULL']['PUSH']['min_intents'])
+                main.maxIntents = int(main.params['NULL']['PUSH']['max_intents'])
+                main.checkInterval = int(main.params['NULL']['PUSH']['check_interval'])
+                main.batchSize = int(main.params['NULL']['PUSH']['batch_size'])
+
+        # check if the case needs to be skipped
+        if main.setupSkipped:
+            main.setupSkipped = False
+            main.skipCase()
+
+        # the index where the next intents will be installed
+        offset = 0
+        # keeps track of how many intents have been installed
+        currIntents = 0
+        # keeps track of how many flows have been installed
+        currFlows = main.defaultFlows
+        # limit for the number of intents that can be installed
+        limit = main.maxIntents / main.batchSize
+
+        main.step( "Pushing intents" )
+        for i in range(limit):
+            pushResult = main.ONOScli1.pushTestIntents( main.switchType +  main.ingress,
+                                                        main.switchType +  main.egress,
+                                                        main.batchSize,
+                                                        offset = offset,
+                                                        options = "-i",
+                                                        timeout = main.timeout )
+            if pushResult == None:
+                main.log.info( "Timeout!" )
+                main.skipCase()
+            time.sleep(1)
+
+            # Update offset
+            offset += main.batchSize
+
+            if offset >= main.minIntents and offset % main.checkInterval == 0:
+                intentVerify = utilities.retry( main.ONOScli1.checkIntentSummary,
+                                                main.FALSE,
+                                                [main.timeout],
+                                                sleep=main.verifySleep,
+                                                attempts=main.verifyAttempts )
+
+                flowVerify = utilities.retry( main.ONOScli1.checkFlowsState,
+                                              main.FALSE,
+                                              [False,main.timeout],
+                                              sleep=main.verifySleep,
+                                              attempts=main.verifyAttempts )
+
+                if not intentVerify:
+                    main.log.error( "Failed to install intents" )
+                    break
+
+                if main.reroute:
+                    main.step( "Reroute" )
+                    # tear down a link
+                    main.log.info("Tearing down link")
+                    if main.switchType == "of:":
+                        downlink = main.Mininet1.link( END1 = "s1", END2 = "s3", OPTION = "down" )
+                    else:
+                        downlink = main.ONOScli1.link( main.ingress, main.egress, "down")
+
+                    if downlink:
+                        main.log.info( "Successfully tear down link" )
+                    else:
+                        main.log.warn( "Failed to tear down link" )
+
+                    time.sleep(main.rerouteSleep)
+
+                    # Verifying intents
+                    main.step( "Checking intents and flows" )
+                    intentVerify = utilities.retry( main.ONOScli1.checkIntentSummary,
+                                                    main.FALSE,
+                                                    [main.timeout],
+                                                    sleep=main.verifySleep,
+                                                    attempts=main.verifyAttempts )
+                    # Verfying flows
+                    flowVerify = utilities.retry( main.ONOScli1.checkFlowsState,
+                                                  main.FALSE,
+                                                  [False, main.timeout],
+                                                  sleep = main.verifySleep,
+                                                  attempts = main.verifyAttempts )
+
+                    if not intentVerify:
+                        main.log.error( "Failed to install intents" )
+                    # Bring link back up
+                    main.log.info("Bringing link back up")
+                    if main.switchType == "of:":
+                        uplink = main.Mininet1.link( END1 = "s1", END2 = "s3", OPTION = "up" )
+                    else:
+                        uplink = main.ONOScli1.link( main.ingress, main.egress, "up" )
+
+                    if uplink:
+                        main.log.info( "Successfully bring link back up" )
+                    else:
+                        main.log.warn( "Failed to bring link back up" )
+
+                    time.sleep(main.rerouteSleep)
+
+                    # Verifying intents
+                    main.step( "Checking intents and flows" )
+                    intentVerify = utilities.retry( main.ONOScli1.checkIntentSummary,
+                                                    main.FALSE,
+                                                    [main.timeout],
+                                                    sleep=main.verifySleep,
+                                                    attempts=main.verifyAttempts )
+                    # Verfying flows
+                    flowVerify = utilities.retry( main.ONOScli1.checkFlowsState,
+                                                  main.FALSE,
+                                                  [False, main.timeout],
+                                                  sleep = main.verifySleep,
+                                                  attempts = main.verifyAttempts )
+
+                    if not intentVerify:
+                        main.log.error( "Failed to install intents" )
+
+                    rerouteResult = downlink and uplink
+                    utilities.assert_equals( expect = main.TRUE,
+                                             actual = rerouteResult,
+                                             onpass = "Successfully reroute",
+                                             onfail = "Failed to reroute" )
+
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = intentVerify,
+                                 onpass = "Successfully pushed and verified intents",
+                                 onfail = "Failed to push and verify intents" )
+        currIntents = main.ONOScli1.getTotalIntentsNum()
+        currFlows = 0
+        # Get current flows from REST API
+        temp = json.loads( main.ONOSrest1.flows() )
+        for t in temp:
+            if t.get("state") == "ADDED":
+                currFlows = currFlows + 1
+        main.log.info( "Total Intents Installed: {}".format( currIntents ) )
+        main.log.info( "Total Flows ADDED: {}".format( currFlows ) )
+
+        main.log.info("Writing results to DB file")
+        with open(main.dbFileName, "a") as dbFile:
+            temp = "," + str(currIntents)
+            temp += "," + str(currFlows)
+            temp += ",0"
+            temp += ",0\n"
+            dbFile.write(temp)
+
+        if main.switchType == "of:":
+            main.step( "Stopping mininet" )
+            stepResult = main.Mininet1.stopNet()
+            utilities.assert_equals( expect = main.TRUE,
+                                     actual = stepResult,
+                                     oppass = "Successfully stop Mininet",
+                                     opfail = "Failed stop Mininet" )
+
+
+    def CASE100( self, main ):
+        '''
+            Report errors/warnings/exceptions
+        '''
+        main.log.info("Error report: \n")
+        main.ONOSbench.logReport( main.ONOSip[ 0 ],
+                                  [ "INFO",
+                                    "FOLLOWER",
+                                    "WARN",
+                                    "flow",
+                                    "ERROR",
+                                    "Except" ],
+                                  "s" )
diff --git a/TestON/tests/SCPF/SCPFmaxIntents/SCPFmaxIntents.topo b/TestON/tests/SCPF/SCPFmaxIntents/SCPFmaxIntents.topo
new file mode 100755
index 0000000..987f444
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFmaxIntents/SCPFmaxIntents.topo
@@ -0,0 +1,46 @@
+<TOPOLOGY>
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOScli1>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOScli1>
+
+        <ONOSrest1>
+            <host>OC1</host>
+            <port>8181</port>
+            <user>onos</user>
+            <password>rocks</password>
+            <type>OnosRestDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOSrest1>
+
+        <Mininet1>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>MininetCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </Mininet1>
+
+    </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/SCPF/SCPFmaxIntents/__init__.py b/TestON/tests/SCPF/SCPFmaxIntents/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFmaxIntents/__init__.py
diff --git a/TestON/tests/SCPF/SCPFportLat/README b/TestON/tests/SCPF/SCPFportLat/README
new file mode 100644
index 0000000..0c89f26
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFportLat/README
@@ -0,0 +1,31 @@
+PORT LATENCY
+
+Summary: This is a performance test suite to measure the time it takes ONOS 
+        to recognize a port going down and up.
+
+Pre-requisites: To run out-of-the box this test requires 7 NODES. 
+    OC1->OC7 must be set before initiating the test. Passwordless login 
+    must be set from TestStation "sdn" root user. The 7 NODES must have
+    their clocks synced to TestStation via ptpd and be accurate to the 
+    millisecond. You will also need the Wireshark disector to see openflow packets.
+
+***If you wish to run this test with less than 7 nodes the following 
+    alterations must be made:
+
+NOTE: Only scale sizes 1,3,5 and 7 will be functional
+
+--In the .params, remove any values in the comma separated list in the 
+    <scale> tag that are above your desired cluster size. 
+
+--In the .params file remove one instance of “1,2” from the <testcases> 
+    tag for each value you removed from <scale> (case 1 and 2 are each 
+    called once for each scale value)
+
+--In the .params file, change the value in the <max> tag to your 
+    desired scale size (1,3, or 5)
+
+--In the .topo file, change the <ONOSbench/COMPONENTS/nodes> tag to your 
+    desired scale size 
+
+--Also in the .topo file, you will need to remove all unneeded <ONOS X 
+    cli> tags and their contents
diff --git a/TestON/tests/SCPF/SCPFportLat/SCPFportLat.params b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.params
new file mode 100644
index 0000000..4a758b3
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.params
@@ -0,0 +1,84 @@
+<PARAMS>
+    <testcases>1,2,1,2,1,2,1,2</testcases>
+
+    <SCALE>1,3,5,7</SCALE>
+    <max>7</max>
+
+    <ENV>
+        <cellName>topo_perf_test</cellName>
+        <cellApps>drivers,metrics,openflow</cellApps>
+    </ENV>
+
+    <GIT>
+        <autopull>off</autopull>
+        <checkout>master</checkout>
+    </GIT>
+
+    <CTRL>
+        <user>sdn</user>
+        <ip1>OC1</ip1>
+        <ip2>OC2</ip2>
+        <ip3>OC3</ip3>
+        <ip4>OC4</ip4>
+        <ip5>OC5</ip5>
+        <ip6>OC6</ip6>
+        <ip7>OC7</ip7>
+    </CTRL>
+
+    <MN>
+        <ip1>localhost</ip1>
+    </MN>
+
+    <BENCH>
+        <ip>localhost</ip>
+    </BENCH>
+
+    <TSHARK>
+        <ofpPortStatus>OF 1.3 146</ofpPortStatus>
+        <ofpRoleReply>OF 1.3 90 of_role_reply</ofpRoleReply>
+        <featureReply>OF 1.3 98 of_features_reply</featureReply>
+        <roleRequest>OF 1.3 90 of_role_request</roleRequest>
+        <tcpSynAck>TCP 74 6653</tcpSynAck>
+        <finAckSequence>FIN</finAckSequence>
+    </TSHARK>
+
+    <TEST>
+        #'on' or 'off' debug mode.
+        #If on, logging will be more verbose and
+        #tshark pcap will be enabled
+        #pcap file located at /tmp/'capture_name'
+        <debugMode>on</debugMode>
+        <onosLogFile>/opt/onos/log/karaf*</onosLogFile>
+        <mci>off</mci>
+
+        <topoConfigFile>
+            single_topo_event_accumulator.cfg
+        </topoConfigFile>
+        <topoConfigName>
+            org.onlab.onos.net.topology.impl.DefaultTopologyProvider.cfg
+        </topoConfigName>
+
+        #Number of times to iterate each case
+        <numIter>25</numIter>
+        <numSwitch>2</numSwitch>
+        #Number of iterations to ignore initially
+        <iterIgnore>5</iterIgnore>
+
+        <portUpThreshold>0,5000</portUpThreshold>
+        <portDownThreshold>0,1000</portDownThreshold>
+
+        <tabletFile>tablets_3node.json</tabletFile>
+   </TEST>
+
+    <DB>
+        <postToDB>no</postToDB>
+        <portEventResultPath>/tmp/portEventResultDb</portEventResultPath>
+    </DB>
+
+    <JSON>
+        <deviceTimestamp>topologyDeviceEventTimestamp</deviceTimestamp>
+        <hostTimestamp>topologyHostEventTimestamp</hostTimestamp>
+        <linkTimestamp>topologyLinkEventTimestamp</linkTimestamp>
+        <graphTimestamp>topologyGraphEventTimestamp</graphTimestamp>
+    </JSON>
+</PARAMS>
diff --git a/TestON/tests/SCPF/SCPFportLat/SCPFportLat.py b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.py
new file mode 100644
index 0000000..35147ca
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.py
@@ -0,0 +1,550 @@
+# CASE1 starts number of nodes specified in param file
+#
+# cameron@onlab.us
+
+class SCPFportLat:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):
+        import sys
+        import re
+        import os
+        import time
+
+        global init
+        try:
+            if type(init) is not bool:
+                init = Fals
+        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' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip' ]
+        MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+        main.maxNodes = int(main.params[ 'max' ])
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        homeDir = os.path.expanduser('~')
+        topoCfgFile = main.params['TEST']['topoConfigFile']
+        topoCfgName = main.params['TEST']['topoConfigName']
+        resultPath = main.params['DB']['portEventResultPath']
+        skipMvn = main.params ['TEST']['mci']
+        testONpath = re.sub( "(tests)$", "bin", main.testDir )  # TestON/bin
+
+        # -- 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
+            global timeToPost
+            global runNum
+            global jenkinsBuildNumber
+            global CLIs
+            CLIs = []
+
+            timeToPost = time.strftime('%Y-%m-%d %H:%M:%S')
+            runNum = time.strftime('%d%H%M%S')
+            ONOSIp = main.ONOSbench.getOnosIps()
+
+            #Assigning ONOS cli handles to a list
+            for i in range(main.maxNodes):
+                CLIs.append( getattr( main, 'ONOS' + str(i+1) + 'cli'))
+
+            try:
+                jenkinsBuildNumber = str(os.environ['BUILD_NUMBER'])
+                main.log.report( 'Jenkins build number: ' + jenkinsBuildNumber )
+            except KeyError:
+                jenkinsBuildNumber = str(0)
+                main.log.info( 'Job is not run by jenkins. ' + 'Build number set to: ' + jenkinsBuildNumber)
+
+            clusterCount = 0
+            ONOSIp = main.ONOSbench.getOnosIps()
+
+            scale = (main.params[ 'SCALE' ]).split(",")
+            clusterCount = int(scale[0])
+
+            #mvn clean install, for debugging set param 'skipCleanInstall' to yes to speed up test
+            if skipMvn != "off":
+                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" )
+
+            main.step("Grabbing commit number")
+            commit = main.ONOSbench.getVersion()
+            commit = (commit.split(" "))[1]
+
+            main.step("Creating results file")
+            resultsDB = open(resultPath, "w+")
+            resultsDB.close()
+
+            main.log.report('Commit information - ')
+            main.ONOSbench.getVersion(report=True)
+
+        # -- END OF INIT SECTION --#
+
+        main.step("Adjusting scale")
+        clusterCount = int(scale[0])
+        scale.remove(scale[0])
+
+        #kill off all onos processes
+        main.step("Killing all ONOS processes before environmnet setup")
+        for node in range(main.maxNodes):
+            main.ONOSbench.onosDie(ONOSIp[node])
+
+        #Uninstall everywhere
+        main.step( "Cleaning Enviornment..." )
+        for i in range(main.maxNodes):
+            main.log.info(" Uninstalling ONOS " + str(i) )
+            main.ONOSbench.onosUninstall( ONOSIp[i] )
+        main.log.info("Sleep 10 second for uninstall to settle...")
+        time.sleep(10)
+        main.ONOSbench.handle.sendline(" ")
+        main.ONOSbench.handle.expect(":~")
+
+        #construct the cell file
+        main.log.info("Creating cell file")
+        cellIp = []
+        for node in range (clusterCount):
+            cellIp.append(ONOSIp[node])
+
+        main.ONOSbench.createCellFile("localhost",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.step('Starting mininet topology ')
+        main.Mininet1.startNet()
+
+        main.log.report( "Initializeing " + str( clusterCount ) + " node cluster." )
+        for node in range(clusterCount):
+            main.log.info("Starting ONOS " + str(node) + " at IP: " + ONOSIp[node])
+            main.ONOSbench.onosInstall( ONOSIp[node])
+
+        for node in range(clusterCount):
+            for i in range( 2 ):
+                isup = main.ONOSbench.isup( ONOSIp[node] )
+                if isup:
+                    main.log.info("ONOS " + str(node + 1) + " is up\n")
+                    break
+            if not isup:
+                main.log.report( "ONOS " + str(node) + " didn't start!" )
+        main.log.info("Startup sequence complete")
+
+        main.step('Starting onos CLIs')
+        for i in range(clusterCount):
+            CLIs[i].startOnosCli(ONOSIp[i])
+
+        time.sleep(20)
+
+        main.step( 'activating essential applications' )
+        CLIs[0].activateApp( 'org.onosproject.metrics' )
+        CLIs[0].activateApp( 'org.onosproject.openflow' )
+
+        main.step( 'Configuring application parameters' )
+
+        configName = 'org.onosproject.net.topology.impl.DefaultTopologyProvider'
+        configParam = 'maxEvents 1'
+        main.ONOSbench.onosCfgSet( ONOSIp[0], configName, configParam )
+        configParam = 'maxBatchMs 0'
+        main.ONOSbench.onosCfgSet( ONOSIp[0], configName, configParam )
+        configParam = 'maxIdleMs 0'
+        main.ONOSbench.onosCfgSet( ONOSIp[0], configName, configParam )
+
+    def CASE2( self, main ):
+        """
+        Bring port up / down and measure latency.
+        Port enable / disable is simulated by ifconfig up / down
+
+        In ONOS-next, we must ensure that the port we are
+        manipulating is connected to another switch with a valid
+        connection. Otherwise, graph view will not be updated.
+        """
+        import time
+        import subprocess
+        import os
+        import requests
+        import json
+        import numpy
+
+        ONOSUser = main.params['CTRL']['user']
+        numIter = main.params['TEST']['numIter']
+        iterIgnore = int(main.params['TEST']['iterIgnore'])
+
+        deviceTimestampKey = main.params['JSON']['deviceTimestamp']
+        graphTimestampKey = main.params['JSON']['graphTimestamp']
+        linkTimestampKey = main.params['JSON']['linkTimestamp']
+
+        tsharkPortUp = '/tmp/tshark_port_up.txt'
+        tsharkPortDown = '/tmp/tshark_port_down.txt'
+        tsharkPortStatus = main.params[ 'TSHARK' ][ 'ofpPortStatus' ]
+
+        debugMode = main.params['TEST']['debugMode']
+        postToDB = main.params['DB']['postToDB']
+        resultPath = main.params['DB']['portEventResultPath']
+        localTime = time.strftime('%x %X')
+        localTime = localTime.replace('/', '')
+        localTime = localTime.replace(' ', '_')
+        localTime = localTime.replace(':', '')
+
+        if debugMode == 'on':
+            main.ONOSbench.tsharkPcap('eth0', '/tmp/port_lat_pcap_' + localTime)
+
+        upThresholdStr = main.params['TEST']['portUpThreshold']
+        downThresholdStr = main.params['TEST']['portDownThreshold']
+        upThresholdObj = upThresholdStr.split(',')
+        downThresholdObj = downThresholdStr.split(',')
+        upThresholdMin = int(upThresholdObj[0])
+        upThresholdMax = int(upThresholdObj[1])
+        downThresholdMin = int(downThresholdObj[0])
+        downThresholdMax = int(downThresholdObj[1])
+
+        interfaceConfig = 's1-eth1'
+        main.log.report('Port enable / disable latency')
+        main.log.report('Simulated by ifconfig up / down')
+        main.log.report('Total iterations of test: ' + str(numIter))
+        main.step('Assign switches s1 and s2 to controller 1')
+
+        main.Mininet1.assignSwController(sw='s1', ip=ONOSIp[0])
+        main.Mininet1.assignSwController(sw='s2', ip=ONOSIp[0])
+
+        time.sleep(15)
+
+        portUpEndToEndNodeIter = numpy.zeros((clusterCount, int(numIter)))
+        portUpOfpToDevNodeIter = numpy.zeros((clusterCount, int(numIter)))
+        portUpDevToLinkNodeIter = numpy.zeros((clusterCount, int(numIter)))
+        portUpLinkToGraphNodeIter = numpy.zeros((clusterCount, int(numIter)))
+
+        portDownEndToEndNodeIter = numpy.zeros((clusterCount, int(numIter)))
+        portDownOfpToDevNodeIter = numpy.zeros((clusterCount, int(numIter)))
+        portDownDevToLinkNodeIter = numpy.zeros((clusterCount, int(numIter)))
+        portDownLinkToGraphNodeIter = numpy.zeros((clusterCount, int(numIter)))
+
+        for i in range(0, int(numIter)):
+            main.log.report('Iteration: ' + str(i+1) + ' ClusterCount: ' + str(clusterCount))
+            main.step('Starting wireshark capture for port status down')
+            main.ONOSbench.tsharkGrep(tsharkPortStatus, tsharkPortDown)
+
+            time.sleep(2)
+
+            main.step('Disable port: ' + interfaceConfig)
+            main.Mininet1.handle.sendline('sh ifconfig ' +
+                    interfaceConfig + ' down')
+            main.Mininet1.handle.expect('mininet>')
+
+            time.sleep(2)
+
+            jsonStrPtDown = []
+            for node in range (0, clusterCount):
+                metricsPortDown = CLIs[node].topologyEventsMetrics()
+                jsonStrPtDown.append(metricsPortDown)
+
+            time.sleep(10)
+
+            main.ONOSbench.tsharkStop()
+
+            fPortDown = open(tsharkPortDown, 'r')
+            fLine = fPortDown.readline()
+            objDown = fLine.split(' ')
+            if len(fLine) > 0:
+                timestampBeginPtDown = int(float(objDown[1]) * 1000)
+                # At times, tshark reports timestamp at the 3rd
+                # index of the array. If initial readings were
+                # unlike the epoch timestamp, then check the 3rd
+                # index and set that as a timestamp
+                if timestampBeginPtDown < 1400000000000:
+                   timestampBeginPtDown = int(float(objDown[2]) * 1000)
+            else:
+                main.log.info('Tshark output file returned unexpected' +
+                        ' results: ' + str(objDown))
+                timestampBeginPtDown = 0
+            fPortDown.close()
+
+            for node in range(0, clusterCount):
+                nodeNum = node+1
+                metricsDown = CLIs[node].topologyEventsMetrics
+                jsonStrPtDown[node] = metricsDown()
+                jsonObj = json.loads(jsonStrPtDown[node])
+
+                if jsonObj:
+                    graphTimestamp = jsonObj[graphTimestampKey]['value']
+                    deviceTimestamp = jsonObj[deviceTimestampKey]['value']
+                    linkTimestamp = jsonObj[linkTimestampKey]['value']
+                else:
+                    main.log.error( "Unexpected json object" )
+                    graphTimestamp = 0
+                    deviceTimestamp = 0
+                    linkTimestamp = 0
+
+                main.log.info('ptDownTimestamp: ' + str(timestampBeginPtDown))
+                main.log.info("graphTimestamp: " + str(graphTimestamp))
+                main.log.info("deviceTimestamp: " + str(deviceTimestamp))
+                main.log.info("linkTimestamp: " + str(linkTimestamp))
+
+                ptDownEndToEnd = int(graphTimestamp) - int(timestampBeginPtDown)
+                ptDownOfpToDevice = float(deviceTimestamp) - float(timestampBeginPtDown)
+                ptDownDeviceToLink = float(linkTimestamp) - float(deviceTimestamp)
+                ptDownLinkToGraph = float(graphTimestamp) - float(linkTimestamp)
+
+                if ptDownEndToEnd < downThresholdMin or ptDownEndToEnd >= downThresholdMax:
+                    main.log.info("ONOS " +str(nodeNum) + " surpassed threshold - port down End-to-end: "+ str(ptDownEndToEnd) + " ms")
+                elif i < iterIgnore:
+                    main.log.info("ONOS "+str(nodeNum) + " warming up - port down End-to-end: "+ str(ptDownEndToEnd) + " ms")
+                else:
+                    portDownEndToEndNodeIter[node][i] = ptDownEndToEnd
+                    main.log.info("ONOS "+str(nodeNum) + " port down End-to-end: "+ str(ptDownEndToEnd) + " ms")
+
+                if ptDownOfpToDevice < downThresholdMin or ptDownOfpToDevice >= downThresholdMax:
+                    main.log.info("ONOS " +str(nodeNum) + " surpassed threshold - port down Ofp-to-device: "+ str(ptDownOfpToDevice) + " ms")
+                elif i < iterIgnore:
+                    main.log.info("ONOS "+str(nodeNum) + " warming up - port down Ofp-to-device: "+ str(ptDownOfpToDevice) + " ms")
+                else:
+                    portDownOfpToDevNodeIter[node][i] = ptDownOfpToDevice
+                    main.log.info("ONOS "+str(nodeNum) + " port down Ofp-to-device: "+ str(ptDownOfpToDevice) + " ms")
+
+                if ptDownDeviceToLink < downThresholdMin or ptDownDeviceToLink >= downThresholdMax:
+                    main.log.info("ONOS " +str(nodeNum) + " surpassed threshold - port down Device-to-link: "+ str(ptDownDeviceToLink) + " ms")
+                elif i < iterIgnore:
+                    main.log.info("ONOS "+str(nodeNum) + " warming up - port down Device-to-link: "+ str(ptDownDeviceToLink) + " ms")
+                else:
+                    portDownDevToLinkNodeIter[node][i] = ptDownDeviceToLink
+                    main.log.info("ONOS "+str(nodeNum) + " port down Device-to-link: "+ str(ptDownDeviceToLink) + " ms")
+
+                if ptDownLinkToGraph < downThresholdMin or ptDownLinkToGraph >= downThresholdMax:
+                    main.log.info("ONOS " +str(nodeNum) + " surpassed threshold - port down Link-to-graph: "+ str(ptDownLinkToGraph) + " ms")
+                elif i < iterIgnore:
+                    main.log.info("ONOS "+str(nodeNum) + " warming up - port down Link-to-graph: "+ str(ptDownLinkToGraph) + " ms")
+                else:
+                    portDownLinkToGraphNodeIter[node][i] = ptDownLinkToGraph
+                    main.log.info("ONOS "+str(nodeNum) + " port down Link-to-graph: "+ str(ptDownLinkToGraph) + " ms")
+
+            time.sleep(3)
+
+            main.step('Starting wireshark capture for port status up')
+            main.ONOSbench.tsharkGrep(tsharkPortStatus, tsharkPortUp)
+
+            time.sleep(5)
+            main.step('Enable port and obtain timestamp')
+            main.Mininet1.handle.sendline('sh ifconfig ' + interfaceConfig + ' up')
+            main.Mininet1.handle.expect('mininet>')
+
+            time.sleep(5)
+
+            jsonStrPtUp = []
+            for node in range (0, clusterCount):
+                metricsPortUp = CLIs[node].topologyEventsMetrics()
+                jsonStrPtUp.append(metricsPortUp)
+
+            time.sleep(5)
+            main.ONOSbench.tsharkStop()
+
+            time.sleep(3)
+
+            fPortUp = open(tsharkPortUp, 'r')
+            fLine = fPortUp.readline()
+            objUp = fLine.split(' ')
+            if len(fLine) > 0:
+                timestampBeginPtUp = int(float(objUp[1]) * 1000)
+                if timestampBeginPtUp < 1400000000000:
+                    timestampBeginPtUp = int(float(objUp[2]) * 1000)
+            else:
+                main.log.info('Tshark output file returned unexpected' + ' results.')
+                timestampBeginPtUp = 0
+            fPortUp.close()
+
+            for node in range(0, clusterCount):
+                nodeNum = node+1
+                metricsUp = CLIs[node].topologyEventsMetrics
+                jsonStrUp = metricsUp()
+                jsonObj = json.loads(jsonStrPtUp[node])
+
+                if jsonObj:
+                    graphTimestamp = jsonObj[graphTimestampKey]['value']
+                    deviceTimestamp = jsonObj[deviceTimestampKey]['value']
+                    linkTimestamp = jsonObj[linkTimestampKey]['value']
+                else:
+                    main.log.error( "Unexpected json object" )
+                    graphTimestamp = 0
+                    deviceTimestamp = 0
+                    linkTimestamp = 0
+
+
+                main.log.info('ptUpTimestamp: ' + str(timestampBeginPtUp))
+                main.log.info("graphTimestamp: " + str(graphTimestamp))
+                main.log.info("deviceTimestamp: " + str(deviceTimestamp))
+                main.log.info("linkTimestamp: " + str(linkTimestamp))
+
+                ptUpEndToEnd = int(graphTimestamp) - int(timestampBeginPtUp)
+                ptUpOfpToDevice = float(deviceTimestamp) - float(timestampBeginPtUp)
+                ptUpDeviceToLink = float(linkTimestamp) - float(deviceTimestamp)
+                ptUpLinkToGraph = float(graphTimestamp) - float(linkTimestamp)
+
+                if ptUpEndToEnd < upThresholdMin or ptUpEndToEnd >= upThresholdMax:
+                    main.log.info("ONOS " +str(nodeNum) + " surpassed threshold - port up End-to-end: "+ str(ptUpEndToEnd) + " ms")
+                elif i < iterIgnore:
+                    main.log.info("ONOS "+str(nodeNum) + " warming up - port up End-to-end: "+ str(ptUpEndToEnd) + " ms")
+                else:
+                    portUpEndToEndNodeIter[node][i] = ptUpEndToEnd
+                    main.log.info("ONOS "+str(nodeNum) + " port up End-to-end: "+ str(ptUpEndToEnd) + " ms")
+
+                if ptUpOfpToDevice < upThresholdMin or ptUpOfpToDevice >= upThresholdMax:
+                    main.log.info("ONOS " + str(nodeNum) + " surpassed threshold - port up Ofp-to-device: "+ str(ptUpOfpToDevice) + " ms")
+                elif i < iterIgnore:
+                    main.log.info("ONOS "+ str(nodeNum) + " warming up - port up Ofp-to-device: "+ str(ptUpOfpToDevice) + " ms")
+                else:
+                    portUpOfpToDevNodeIter[node][i] = ptUpOfpToDevice
+                    main.log.info("ONOS "+ str(nodeNum) + " port up Ofp-to-device: "+ str(ptUpOfpToDevice) + " ms")
+
+                if ptUpDeviceToLink < upThresholdMin or ptUpDeviceToLink >= upThresholdMax:
+                    main.log.info("ONOS " +str(nodeNum) + " surpassed threshold - port up Device-to-link: "+ str(ptUpDeviceToLink) + " ms")
+                elif i < iterIgnore:
+                    main.log.info("ONOS "+str(nodeNum) + " warming up - port up Device-to-link: "+ str(ptUpDeviceToLink) + " ms")
+                else:
+                    portUpDevToLinkNodeIter[node][i] = ptUpDeviceToLink
+                    main.log.info("ONOS "+str(nodeNum) + " port up Device-to-link: "+ str(ptUpDeviceToLink) + " ms")
+
+                if ptUpLinkToGraph < upThresholdMin or ptUpLinkToGraph >= upThresholdMax:
+                    main.log.info("ONOS " + str(nodeNum) + " surpassed threshold - port up Link-to-graph: " + str(ptUpLinkToGraph) + " ms")
+                elif i < iterIgnore:
+                    main.log.info("ONOS " + str(nodeNum) + " warming up - port up Link-to-graph: " + str(ptUpLinkToGraph) + " ms")
+                else:
+                    portUpLinkToGraphNodeIter[node][i] = ptUpLinkToGraph
+                    main.log.info("ONOS " + str(nodeNum) + " port up Link-to-graph: " + str(ptUpLinkToGraph) + " ms")
+
+        dbCmdList = []
+        for node in range(0, clusterCount):
+            portUpEndToEndList = []
+            portUpOfpToDevList = []
+            portUpDevToLinkList = []
+            portUpLinkToGraphList = []
+
+            portDownEndToEndList = []
+            portDownOfpToDevList = []
+            portDownDevToLinkList = []
+            portDownLinkToGraphList = []
+
+            portUpEndToEndAvg = 0
+            portUpOfpToDevAvg = 0
+            portUpDevToLinkAvg = 0
+            portUpLinkToGraphAvg = 0
+
+            portDownEndToEndAvg = 0
+            portDownOfpToDevAvg = 0
+            portDownDevToLinkAvg = 0
+            portDownLinkToGraphAvg = 0
+
+            # TODO: Update for more pythonic way to get list
+            # portUpDevList = [item for item in portUpDevNodeIter[node]
+            #        if item > 0.0]
+            for item in portUpEndToEndNodeIter[node]:
+                if item > 0.0:
+                    portUpEndToEndList.append(item)
+
+            for item in portUpOfpToDevNodeIter[node]:
+                if item > 0.0:
+                    portUpOfpToDevList.append(item)
+
+            for item in portUpDevToLinkNodeIter[node]:
+                if item > 0.0:
+                    portUpDevToLinkList.append(item)
+
+            for item in portUpLinkToGraphNodeIter[node]:
+                if item >= 0.0:
+                    portUpLinkToGraphList.append(item)
+
+            for item in portDownEndToEndNodeIter[node]:
+                if item > 0.0:
+                    portDownEndToEndList.append(item)
+
+            for item in portDownOfpToDevNodeIter[node]:
+                if item > 0.0:
+                    portDownOfpToDevList.append(item)
+
+            for item in portDownDevToLinkNodeIter[node]:
+                if item >= 0.0:
+                    portDownDevToLinkList.append(item)
+
+            for item in portDownLinkToGraphNodeIter[node]:
+                if item >= 0.0:
+                    portDownLinkToGraphList.append(item)
+
+            portUpEndToEndAvg = round(numpy.mean(portUpEndToEndList), 2)
+            portUpOfpToDevAvg = round(numpy.mean(portUpOfpToDevList), 2)
+            portUpDevToLinkAvg = round(numpy.mean(portUpDevToLinkList), 2)
+            portUpLinkToGraphAvg = round(numpy.mean(portUpLinkToGraphList), 2)
+
+            portDownEndToEndAvg = round(numpy.mean(portDownEndToEndList), 2)
+            portDownOfpToDevAvg = round(numpy.mean(portDownOfpToDevList), 2)
+            portDownDevToLinkAvg = round(numpy.mean(portDownDevToLinkList), 2)
+            portDownLinkToGraphAvg = round(numpy.mean(portDownLinkToGraphList), 2)
+
+            portUpStdDev = round(numpy.std(portUpEndToEndList), 2)
+            portDownStdDev = round(numpy.std(portDownEndToEndList), 2)
+
+            main.log.report(' - Node ' + str(node + 1) + ' Summary ---------------- ')
+            main.log.report(' Port up End-to-end ' +
+                    str(portUpEndToEndAvg) + ' ms')
+            main.log.report(' Port up Ofp-to-device ' +
+                    str(portUpOfpToDevAvg) + ' ms')
+            main.log.report(' Port up Device-to-link ' +
+                    str(portUpDevToLinkAvg) + ' ms')
+            main.log.report(' Port up Link-to-graph ' +
+                    str(portUpLinkToGraphAvg) + ' ms')
+
+            main.log.report(' Port down End-to-end ' +
+                    str(round(portDownEndToEndAvg, 2)) + ' ms')
+            main.log.report(' Port down Ofp-to-device ' +
+                    str(portDownOfpToDevAvg) + ' ms')
+            main.log.report(' Port down Device-to-link ' +
+                    str(portDownDevToLinkAvg) + ' ms')
+            main.log.report(' Port down Link-to-graph' +
+                    str(portDownLinkToGraphAvg) + ' ms')
+
+            dbCmdList.append(
+                    "'" + timeToPost + "','port_latency_results'," + jenkinsBuildNumber +
+                    ',' + str(clusterCount) + ",'baremetal" + str(node + 1) +
+                    "'," +
+                    str(portUpEndToEndAvg) +',' +
+                    str(portUpOfpToDevAvg) + ',' +
+                    str(portUpDevToLinkAvg) + ',' +
+                    str(portUpLinkToGraphAvg) + ',' +
+                    str(portDownEndToEndAvg) + ',' +
+                    str(portDownOfpToDevAvg) + ',' +
+                    str(portDownDevToLinkAvg) + ',' +
+                    str(portDownLinkToGraphAvg))
+
+        fResult = open(resultPath, 'a')
+        for line in dbCmdList:
+            if line:
+                fResult.write(line + '\n')
+
+        fResult.close()
+
+        # Delete switches from controller to prepare for next
+        # set of tests
+        main.Mininet1.deleteSwController('s1')
+        main.Mininet1.deleteSwController('s2')
+
+        main.log.info("Stopping mininet")
+        main.Mininet1.stopNet()
diff --git a/TestON/tests/SCPF/SCPFportLat/SCPFportLat.topo b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.topo
new file mode 100644
index 0000000..1a73a2b
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.topo
@@ -0,0 +1,97 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+                <home>~/onos</home>
+                <nodes>7</nodes> 
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOS1cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1cli>
+
+        <ONOS2cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2cli>
+
+        <ONOS3cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3cli>
+
+        <ONOS4cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4cli>
+
+        <ONOS5cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5cli>
+
+        <ONOS6cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6cli>
+
+        <ONOS7cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>8</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS7cli>
+
+        <Mininet1>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>MininetCliDriver</type>
+            <connect_order>9</connect_order>
+            <COMPONENTS>
+                <arg1> --custom ~/mininet/custom/topo-perf-2sw.py </arg1>
+                <arg2> --topo mytopo</arg2>
+                <arg3> --switch ovsk,protocols=OpenFlow13</arg3>
+                <controller> remote </controller>
+            </COMPONENTS>
+        </Mininet1>
+
+    </COMPONENT>
+
+</TOPOLOGY>
+ 
diff --git a/TestON/tests/SCPF/SCPFportLat/__init__.py b/TestON/tests/SCPF/SCPFportLat/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFportLat/__init__.py
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/Dependency/multiovs.py b/TestON/tests/SCPF/SCPFscaleTopo/Dependency/multiovs.py
new file mode 100755
index 0000000..0545013
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscaleTopo/Dependency/multiovs.py
@@ -0,0 +1,274 @@
+#!/usr/bin/python
+
+"""
+Multiple ovsdb OVS!!
+
+We scale up by creating multiple ovsdb instances,
+each of which is shared by several OVS switches
+
+The shell may also be shared among switch instances,
+which causes switch.cmd() and switch.popen() to be
+delegated to the ovsdb instance.
+
+"""
+
+from mininet.net import Mininet
+from mininet.node import Node, OVSSwitch
+from mininet.node import OVSBridge
+from mininet.link import Link, OVSIntf
+from mininet.topo import LinearTopo, SingleSwitchTopo
+from mininet.topolib import TreeTopo
+from mininet.log import setLogLevel, info
+from mininet.cli import CLI
+from mininet.clean import Cleanup, sh
+
+from itertools import groupby
+from operator import attrgetter
+
+class OVSDB( Node ):
+    "Namespace for an OVSDB instance"
+
+    privateDirs = [ '/etc/openvswitch',
+                    '/var/run/openvswitch',
+                    '/var/log/openvswitch' ]
+
+    # Control network
+    ipBase = '172.123.123.0/24'
+    cnet = None
+    nat = None
+
+    @classmethod
+    def startControlNet( cls ):
+        "Start control net if necessary and return it"
+        cnet = cls.cnet
+        if not cnet:
+            info( '### Starting control network\n' )
+            cnet = Mininet( ipBase=cls.ipBase )
+            cswitch = cnet.addSwitch( 'ovsbr0', cls=OVSBridge )
+            # Add NAT - note this can conflict with data network NAT
+            info( '### Adding NAT for control and data networks'
+                  ' (use --nat flush=0 for data network)\n' )
+            cls.cnet = cnet
+            cls.nat = cnet.addNAT( 'ovsdbnat0')
+            cnet.start()
+            info( '### Control network started\n' )
+        return cnet
+
+    def stopControlNet( self ):
+        info( '\n### Stopping control network\n' )
+        cls = self.__class__
+        cls.cnet.stop()
+        info( '### Control network stopped\n' )
+
+    def addSwitch( self, switch ):
+        "Add a switch to our namespace"
+        # Attach first switch to cswitch!
+        self.switches.append( switch )
+
+    def delSwitch( self, switch ):
+        "Delete a switch from our namespace, and terminate if none left"
+        self.switches.remove( switch )
+        if not self.switches:
+            self.stopOVS()
+
+    ovsdbCount = 0
+
+    def startOVS( self ):
+        "Start new OVS instance"
+        self.cmd( 'ovsdb-tool create /etc/openvswitch/conf.db' )
+        self.cmd( 'ovsdb-server /etc/openvswitch/conf.db'
+                  ' -vfile:emer -vfile:err -vfile:info'
+                  ' --remote=punix:/var/run/openvswitch/db.sock '
+                  ' --log-file=/var/log/openvswitch/ovsdb-server.log'
+                  ' --pidfile=/var/run/openvswitch/ovsdb-server-mn.pid'
+                  ' --no-chdir'
+                  ' --detach' )
+
+        self.cmd( 'ovs-vswitchd unix:/var/run/openvswitch/db.sock'
+                  ' -vfile:emer -vfile:err -vfile:info'
+                  ' --mlockall --log-file=/var/log/openvswitch/ovs-vswitchd.log'
+                  ' --pidfile=/var/run/openvswitch/ovs-vswitchd-mn.pid'
+                  ' --no-chdir'
+                  ' --detach' )
+
+    def stopOVS( self ):
+        self.cmd( 'kill',
+                  '`cat /var/run/openvswitch/ovs-vswitchd-mn.pid`',
+                  '`cat /var/run/openvswitch/ovsdb-server-mn.pid`' )
+        self.cmd( 'wait' )
+        self.__class__.ovsdbCount -= 1
+        if self.__class__.ovsdbCount <= 0:
+            self.stopControlNet()
+
+    @classmethod
+    def cleanUpOVS( cls ):
+        "Clean up leftover ovsdb-server/ovs-vswitchd processes"
+        info( '*** Shutting down extra ovsdb-server/ovs-vswitchd processes\n' )
+        sh( 'pkill -f mn.pid' )
+
+    def self( self, *args, **kwargs ):
+        "A fake constructor that sets params and returns self"
+        self.params = kwargs
+        return self
+
+    def __init__( self, **kwargs ):
+        cls = self.__class__
+        cls.ovsdbCount += 1
+        cnet = self.startControlNet()
+        # Create a new ovsdb namespace
+        self.switches = []
+        name = 'ovsdb%d' % cls.ovsdbCount
+        kwargs.update( inNamespace=True )
+        kwargs.setdefault( 'privateDirs', self.privateDirs )
+        super( OVSDB, self ).__init__( name, **kwargs )
+        ovsdb = cnet.addHost( name, cls=self.self, **kwargs )
+        link = cnet.addLink( ovsdb, cnet.switches[ 0 ] )
+        cnet.switches[ 0 ].attach( link.intf2 )
+        ovsdb.configDefault()
+        ovsdb.setDefaultRoute( 'via %s' % self.nat.intfs[ 0 ].IP() )
+        ovsdb.startOVS()
+
+
+# Install cleanup callback
+Cleanup.addCleanupCallback( OVSDB.cleanUpOVS )
+
+
+class OVSSwitchNS( OVSSwitch ):
+    "OVS Switch in shared OVSNS namespace"
+
+    isSetup = False
+
+    @classmethod
+    def batchStartup( cls, switches ):
+        result = []
+        for ovsdb, switchGroup in groupby( switches, attrgetter( 'ovsdb') ):
+            switchGroup = list( switchGroup )
+            info( '(%s)' % ovsdb )
+            result += OVSSwitch.batchStartup( switchGroup, run=ovsdb.cmd )
+        return result
+
+    @classmethod
+    def batchShutdown( cls, switches ):
+        result = []
+        for ovsdb, switchGroup in groupby( switches, attrgetter( 'ovsdb') ):
+            switchGroup = list( switchGroup )
+            info( '(%s)' % ovsdb )
+            for switch in switches:
+                if switch.pid == ovsdb.pid:
+                    switch.pid = None
+                    switch.shell = None
+            result += OVSSwitch.batchShutdown( switchGroup, run=ovsdb.cmd )
+            for switch in switchGroup:
+                switch.ovsdbFree()
+        return result
+
+    # OVSDB allocation
+    groupSize = 64
+    switchCount = 0
+    lastOvsdb = None
+
+    @classmethod
+    def ovsdbAlloc( cls, switch ):
+        "Allocate (possibly new) OVSDB instance for switch"
+        if cls.switchCount % switch.groupSize == 0:
+            cls.lastOvsdb = OVSDB()
+        cls.switchCount += 1
+        cls.lastOvsdb.addSwitch( switch )
+        return cls.lastOvsdb
+
+    def ovsdbFree( self ):
+        "Deallocate OVSDB instance for switch"
+        self.ovsdb.delSwitch( self )
+
+    def startShell( self, *args, **kwargs ):
+        "Start shell in shared OVSDB namespace"
+        ovsdb = self.ovsdbAlloc( self )
+        kwargs.update( mnopts='-da %d ' % ovsdb.pid )
+        self.ns = [ 'net' ]
+        self.ovsdb = ovsdb
+        self._waiting = False
+        if self.privateShell:
+            super( OVSSwitchNS, self ).startShell( *args, **kwargs )
+        else:
+            # Delegate methods and initialize local vars
+            attrs = ( 'cmd', 'cmdPrint', 'sendCmd', 'waitOutput',
+                      'monitor', 'write', 'read',
+                      'pid', 'shell', 'stdout',)
+            for attr in attrs:
+                setattr( self, attr, getattr( ovsdb, attr ) )
+        self.defaultIntf().updateIP()
+
+    @property
+    def waiting( self ):
+        "Optionally delegated to ovsdb"
+        return self._waiting if self.privateShell else self.ovsdb.waiting
+
+    @waiting.setter
+    def waiting( self, value ):
+        "Optionally delegated to ovsdb (read only!)"
+        if self.privateShell:
+            _waiting = value
+
+    def start( self, controllers ):
+        "Update controller IP addresses if necessary"
+        for controller in controllers:
+            if controller.IP() == '127.0.0.1' and not controller.intfs:
+                controller.intfs[ 0 ] = self.ovsdb.nat.intfs[ 0 ]
+        super( OVSSwitchNS, self ).start( controllers )
+
+    def stop( self, *args, **kwargs ):
+        "Stop and free OVSDB namespace if necessary"
+        self.ovsdbFree()
+
+    def terminate( self, *args, **kwargs ):
+        if self.privateShell:
+            super( OVSSwitchNS, self ).terminate( *args, **kwargs )
+        else:
+            self.pid = None
+            self.shell= None
+
+    def defaultIntf( self ):
+        return self.ovsdb.defaultIntf()
+
+    def __init__( self, *args, **kwargs ):
+        """n: number of OVS instances per OVSDB
+           shell: run private shell/bash process? (False)
+           If shell is shared/not private, cmd() and popen() are
+           delegated to the OVSDB instance, which is different than
+           regular OVSSwitch semantics!!"""
+        self.groupSize = kwargs.pop( 'n', self.groupSize )
+        self.privateShell = kwargs.pop( 'shell', False )
+        super( OVSSwitchNS, self ).__init__( *args, **kwargs )
+
+class OVSLinkNS( Link ):
+    "OVSLink that supports OVSSwitchNS"
+
+    def __init__( self, node1, node2, **kwargs ):
+        "See Link.__init__() for options"
+        self.isPatchLink = False
+        if ( isinstance( node1, OVSSwitch ) and
+             isinstance( node2, OVSSwitch ) and
+             getattr( node1, 'ovsdb', None ) ==
+             getattr( node2, 'ovsdb', None ) ):
+            self.isPatchLink = True
+            kwargs.update( cls1=OVSIntf, cls2=OVSIntf )
+        Link.__init__( self, node1, node2, **kwargs )
+
+switches = { 'ovsns': OVSSwitchNS, 'ovsm': OVSSwitchNS }
+
+links = { 'ovs': OVSLinkNS }
+
+def test():
+    "Test OVSNS switch"
+    setLogLevel( 'info' )
+    topo = TreeTopo( depth=4, fanout=2 )
+    net = Mininet( topo=topo, switch=OVSSwitchNS )
+    # Add connectivity to controller which is on LAN or in root NS
+    # net.addNAT().configDefault()
+    net.start()
+    CLI( net )
+    net.stop()
+
+
+if __name__ == '__main__':
+    test()
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/Dependency/newFuncTopo.py b/TestON/tests/SCPF/SCPFscaleTopo/Dependency/newFuncTopo.py
new file mode 100755
index 0000000..5edf7f7
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscaleTopo/Dependency/newFuncTopo.py
@@ -0,0 +1,148 @@
+#!/usr/bin/python
+
+"""
+Custom topology for Mininet
+"""
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import Host, RemoteController
+from mininet.node import Node
+from mininet.node import CPULimitedHost
+from mininet.link import TCLink
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+from mininet.util import dumpNodeConnections
+from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+
+class VLANHost( Host ):
+    def config( self, vlan=100, **params ):
+        r = super( Host, self ).config( **params )
+        intf = self.defaultIntf()
+        self.cmd( 'ifconfig %s inet 0' % intf )
+        self.cmd( 'vconfig add %s %d' % ( intf, vlan ) )
+        self.cmd( 'ifconfig %s.%d inet %s' % ( intf, vlan, params['ip'] ) )
+        newName = '%s.%d' % ( intf, vlan )
+        intf.name = newName
+        self.nameToIntf[ newName ] = intf
+        return r
+
+class IPv6Host( Host ):
+    def config( self, v6Addr='1000:1/64', **params ):
+        r = super( Host, self ).config( **params )
+        intf = self.defaultIntf()
+        self.cmd( 'ifconfig %s inet 0' % intf )
+        self.cmd( 'ip -6 addr add %s dev %s' % ( v6Addr, intf ) )
+        return r
+
+class dualStackHost( Host ):
+    def config( self, v6Addr='2000:1/64', **params ):
+        r = super( Host, self ).config( **params )
+        intf = self.defaultIntf()
+        self.cmd( 'ip -6 addr add %s dev %s' % ( v6Addr, intf ) )
+        return r
+
+class MyTopo( Topo ):
+
+    def __init__( self ):
+        # Initialize topology
+        Topo.__init__( self )
+        # Switch S5 Hosts
+        host1=self.addHost( 'h1', ip='10.1.0.2/24' )
+        host2=self.addHost( 'h2', cls=IPv6Host, v6Addr='1000::2/64' )
+        host3=self.addHost( 'h3', ip='10.1.0.3/24', cls=dualStackHost, v6Addr='2000::2/64' )
+        #VLAN hosts
+        host4=self.addHost( 'h4', ip='100.1.0.2/24', cls=VLANHost, vlan=100 )
+        host5=self.addHost( 'h5', ip='200.1.0.2/24', cls=VLANHost, vlan=200 )
+        #VPN-1 and VPN-2 Hosts
+        host6=self.addHost( 'h6', ip='11.1.0.2/24' )
+        host7=self.addHost( 'h7', ip='12.1.0.2/24' )
+        #Multicast Sender
+        host8=self.addHost( 'h8', ip='10.1.0.4/24' )
+
+        # Switch S6 Hosts
+        host9=self.addHost( 'h9', ip='10.1.0.5/24' )
+        host10=self.addHost( 'h10', cls=IPv6Host, v6Addr='1000::3/64' )
+        host11=self.addHost( 'h11', ip='10.1.0.6/24', cls=dualStackHost, v6Addr='2000::3/64' )
+        #VLAN hosts
+        host12=self.addHost( 'h12', ip='100.1.0.3/24', cls=VLANHost, vlan=100 )
+        host13=self.addHost( 'h13', ip='200.1.0.3/24', cls=VLANHost, vlan=200 )
+        #VPN-1 and VPN-2 Hosts
+        host14=self.addHost( 'h14', ip='11.1.0.3/24' )
+        host15=self.addHost( 'h15', ip='12.1.0.3/24' )
+        #Multicast Receiver
+        host16=self.addHost( 'h16', ip='10.1.0.7/24' )
+
+        # Switch S7 Hosts
+        host17=self.addHost( 'h17', ip='10.1.0.8/24' )
+        host18=self.addHost( 'h18', cls=IPv6Host, v6Addr='1000::4/64' )
+        host19=self.addHost( 'h19', ip='10.1.0.9/24', cls=dualStackHost, v6Addr='2000::4/64' )
+        #VLAN hosts
+        host20=self.addHost( 'h20', ip='100.1.0.4/24', cls=VLANHost, vlan=100 )
+        host21=self.addHost( 'h21', ip='200.1.0.4/24', cls=VLANHost, vlan=200 )
+        #VPN-1 and VPN-2 Hosts
+        host22=self.addHost( 'h22', ip='11.1.0.4/24' )
+        host23=self.addHost( 'h23', ip='12.1.0.4/24' )
+        #Multicast Receiver
+        host24=self.addHost( 'h24', ip='10.1.0.10/24' )
+
+        s1 = self.addSwitch( 's1' )
+        s2 = self.addSwitch( 's2' )
+        s3 = self.addSwitch( 's3' )
+        s4 = self.addSwitch( 's4' )
+        s5 = self.addSwitch( 's5' )
+        s6 = self.addSwitch( 's6' )
+        s7 = self.addSwitch( 's7' )
+
+        self.addLink(s5,host1)
+        self.addLink(s5,host2)
+        self.addLink(s5,host3)
+        self.addLink(s5,host4)
+        self.addLink(s5,host5)
+        self.addLink(s5,host6)
+        self.addLink(s5,host7)
+        self.addLink(s5,host8)
+
+        self.addLink(s6,host9)
+        self.addLink(s6,host10)
+        self.addLink(s6,host11)
+        self.addLink(s6,host12)
+        self.addLink(s6,host13)
+        self.addLink(s6,host14)
+        self.addLink(s6,host15)
+        self.addLink(s6,host16)
+
+        self.addLink(s7,host17)
+        self.addLink(s7,host18)
+        self.addLink(s7,host19)
+        self.addLink(s7,host20)
+        self.addLink(s7,host21)
+        self.addLink(s7,host22)
+        self.addLink(s7,host23)
+        self.addLink(s7,host24)
+
+        self.addLink(s1,s2)
+        self.addLink(s1,s3)
+        self.addLink(s1,s4)
+        self.addLink(s1,s5)
+        self.addLink(s2,s3)
+        self.addLink(s2,s5)
+        self.addLink(s2,s6)
+        self.addLink(s3,s4)
+        self.addLink(s3,s6)
+        self.addLink(s4,s7)
+        topos = { 'mytopo': ( lambda: MyTopo() ) }
+
+# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS
+
+def setupNetwork():
+    "Create network"
+    topo = MyTopo()
+    network = Mininet(topo=topo, autoSetMacs=True, controller=None)
+    network.start()
+    CLI( network )
+    network.stop()
+
+if __name__ == '__main__':
+    setLogLevel('info')
+    #setLogLevel('debug')
+    setupNetwork()
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/Dependency/scaleTopoFunction.py b/TestON/tests/SCPF/SCPFscaleTopo/Dependency/scaleTopoFunction.py
new file mode 100644
index 0000000..075f4f2
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscaleTopo/Dependency/scaleTopoFunction.py
@@ -0,0 +1,385 @@
+"""
+    Wrapper function for FuncTopo
+    Includes onosclidriver and mininetclidriver functions
+"""
+import time
+import json
+import re
+
+def __init__( self ):
+    self.default = ''
+
+def testTopology( main, topoFile='', args='', mnCmd='', timeout=300, clean=True ):
+    """
+    Description:
+        This function combines different wrapper functions in this module
+        to simulate a topology test
+    Test Steps:
+        - Load topology
+        - Discover topology
+        - Compare topology
+        - pingall
+        - Bring links down
+        - Compare topology
+        - pingall
+        - Bring links up
+        - Compare topology
+        - pingall
+    Options:
+        clean: Does sudo mn -c to clean mininet residue
+        Please read mininetclidriver.py >> startNet( .. ) function for details
+    Returns:
+        Returns main.TRUE if the test is successful, main.FALSE otherwise
+    """
+    testTopoResult = main.TRUE
+    compareTopoResult = main.TRUE
+    topoObjectResult = main.TRUE
+    stopResult = main.TRUE
+
+    if clean:
+        # Cleans minient
+        stopResult = stopMininet( main )
+
+    # Restart ONOS to clear hosts test new mininet topology
+    reinstallOnosResult = reinstallOnos( main )
+
+    # Starts topology
+    startResult = startNewTopology( main, topoFile, args, mnCmd, timeout=timeout )
+    # onos needs time to see the links
+    time.sleep(15)
+
+    # Gets list of switches in mininet
+    #assignSwitch( main )
+
+    testTopoResult = startResult and topoObjectResult
+
+
+    return testTopoResult
+
+def startNewTopology( main, topoFile='', args='', mnCmd='', timeout=900 ):
+    """
+    Description:
+        This wrapper function starts new topology
+    Options:
+        Please read mininetclidriver.py >> startNet( .. ) function for details
+    Return:
+        Returns main.TRUE if topology is successfully created by mininet,
+        main.FALSE otherwise
+    NOTE:
+        Assumes Mininet1 is the name of the handler
+    """
+    assert main, "There is no main variable"
+    assert main.Mininet1, "Mininet 1 is not created"
+    result = main.TRUE
+
+    main.log.info( main.topoName + ": Starting new Mininet topology" )
+
+    # log which method is being used
+    if topoFile:
+        main.log.info( main.topoName + ": Starting topology with " +
+                       topoFile + "topology file" )
+    elif not topoFile and not mnCmd:
+        main.log.info( main.topoName + ": Starting topology using" +
+                       " the topo file" )
+    elif topoFile and mnCmd:
+        main.log.error( main.topoName + ": You can only use one " +
+                        "method to start a topology" )
+    elif mnCmd:
+        main.log.info( main.topoName + ": Starting topology with '" +
+                       mnCmd + "' Mininet command" )
+
+
+    result = main.Mininet1.startNet( topoFile=topoFile,
+                                     args=args,
+                                     mnCmd=mnCmd,
+                                     timeout=timeout)
+
+    return result
+
+def stopMininet( main ):
+    """
+        Stops current topology and execute mn -c basically triggers
+        stopNet in mininetclidrivers
+
+        NOTE: Mininet should be running when issuing this command other wise
+        the this function will cause the test to stop
+    """
+    stopResult = main.TRUE
+    stopResult = main.Mininet1.stopNet()
+    time.sleep( 30 )
+    if not stopResult:
+        main.log.info(  main.topoName + ": Did not stop Mininet topology" )
+    return stopResult
+
+def compareTopo( main ):
+    """
+        Compare topology( devices, links, ports, hosts ) between ONOS and
+        mininet using sts
+    """
+    devices = []
+    links = []
+    ports = []
+    hosts = []
+    switchResult = []
+    linksResult = []
+    portsResult = []
+    hostsResult = []
+    mnSwitches = main.Mininet1.getSwitches()
+    mnLinks = main.Mininet1.getLinks()
+    mnHosts = main.Mininet1.getHosts()
+    compareTopoResult = main.TRUE
+
+    for i in range( main.numCtrls ):
+        devices.append( json.loads( main.CLIs[ i ].devices() ) )
+        links.append( json.loads( main.CLIs[ i ].links() ) )
+        ports.append( json.loads(  main.CLIs[ i ].ports() ) )
+        hosts.append( json.loads( main.CLIs[ i ].hosts() ) )
+
+    # Comparing switches
+    main.log.info( main.topoName + ": Comparing switches in each ONOS nodes" +
+                   " with Mininet" )
+    for i in range( main.numCtrls ):
+        tempResult = main.Mininet1.compareSwitches( mnSwitches,
+                                                    devices[ i ],
+                                                    ports[ i ] )
+        switchResult.append( tempResult )
+        if tempResult == main.FALSE:
+            main.log.error( main.topoName + ": ONOS-" + str( i + 1 ) +
+                            " switch view is incorrect " )
+
+    if all( result == main.TRUE for result in switchResult ):
+        main.log.info( main.topoName + ": Switch view in all ONOS nodes "+
+                       "are correct " )
+    else:
+        compareTopoResult = main.FALSE
+
+    # Comparing links
+    main.log.info( main.topoName + ": Comparing links in each ONOS nodes" +
+                   " with Mininet" )
+    for i in range( main.numCtrls ):
+        tempResult = main.Mininet1.compareLinks( mnSwitches,
+                                                 mnLinks,
+                                                 links[ i ] )
+        linksResult.append( tempResult )
+        if tempResult == main.FALSE:
+            main.log.error( main.topoName + ": ONOS-" + str( i + 1 ) +
+                            " links view are incorrect " )
+
+    if all( result == main.TRUE for result in linksResult ):
+        main.log.info( main.topoName + ": Links view in all ONOS nodes "+
+                       "are correct " )
+    else:
+        compareTopoResult = main.FALSE
+
+    # Comparing hosts
+    main.log.info( main.topoName + ": Comparing hosts in each ONOS nodes" +
+                   " with Mininet" )
+    for i in range( main.numCtrls ):
+        tempResult = main.Mininet1.compareHosts( mnHosts, hosts[ i ] )
+        hostsResult.append( tempResult )
+        if tempResult == main.FALSE:
+            main.log.error( main.topoName + ": ONOS-" + str( i + 1 ) +
+                            " hosts view are incorrect " )
+
+    if all( result == main.TRUE for result in hostsResult ):
+        main.log.info( main.topoName + ": Hosts view in all ONOS nodes "+
+                       "are correct " )
+    else:
+        compareTopoResult = main.FALSE
+
+    return compareTopoResult
+
+def assignSwitch( main ):
+    """
+        Returns switch list using getSwitch in Mininet driver
+    """
+    switchList = []
+    assignResult = main.TRUE
+    switchList =  main.Mininet1.getSwitch()
+    assignResult = main.Mininet1.assignSwController( sw=switchList,
+                                                     ip=main.ONOSip[ 0 ],
+                                                     port=6633 )
+
+    for sw in switchList:
+        response = main.Mininet1.getSwController( sw )
+        if re.search( "tcp:" + main.ONOSip[ 0 ], response ):
+            assignResult = assignResult and main.TRUE
+        else:
+            assignResult = main.FALSE
+
+    return switchList
+
+def connectivity( main, timeout=900, shortCircuit=True, acceptableFailed=20 ):
+    """
+        Use fwd app and pingall to discover all the hosts
+    """
+    activateResult = main.TRUE
+    appCheck = main.TRUE
+    getDataResult = main.TRUE
+    main.log.info( main.topoName + ": Activating reactive forwarding app " )
+    activateResult = main.CLIs[ 0 ].activateApp( "org.onosproject.fwd" )
+
+    if main.hostsData:
+        main.hostsData = {}
+    for i in range( main.numCtrls ):
+        appCheck = appCheck and main.CLIs[ i ].appToIDCheck()
+        if appCheck != main.TRUE:
+            main.log.warn( main.CLIs[ i ].apps() )
+            main.log.warn( main.CLIs[ i ].appIDs() )
+
+    time.sleep( main.fwdSleep )
+
+    # Discover hosts using pingall
+    pingResult = main.Mininet1.pingall( timeout=timeout,
+                                        shortCircuit=shortCircuit,
+                                        acceptableFailed=acceptableFailed )
+
+    main.log.info( main.topoName + ": Deactivate reactive forwarding app " )
+    activateResult = main.CLIs[ 0 ].deactivateApp( "org.onosproject.fwd" )
+    for i in range( main.numCtrls ):
+        appCheck = appCheck and main.CLIs[ i ].appToIDCheck()
+        if appCheck != main.TRUE:
+            main.log.warn( main.CLIs[ i ].apps() )
+            main.log.warn( main.CLIs[ i ].appIDs() )
+
+    return pingResult
+
+def getHostsData( main ):
+    """
+        Use fwd app and pingall to discover all the hosts
+    """
+    activateResult = main.TRUE
+    appCheck = main.TRUE
+    getDataResult = main.TRUE
+    main.log.info( main.topoName + ": Activating reactive forwarding app " )
+    activateResult = main.CLIs[ 0 ].activateApp( "org.onosproject.fwd" )
+
+    if main.hostsData:
+        main.hostsData = {}
+    for i in range( main.numCtrls ):
+        appCheck = appCheck and main.CLIs[ i ].appToIDCheck()
+        if appCheck != main.TRUE:
+            main.log.warn( main.CLIs[ i ].apps() )
+            main.log.warn( main.CLIs[ i ].appIDs() )
+
+    time.sleep( main.fwdSleep )
+    # Discover hosts using pingall
+    pingResult = main.Mininet1.pingall( timeout=900 )
+
+    hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
+    hosts = main.Mininet1.getHosts().keys()
+
+    for host in hosts:
+        main.hostsData[ host ] = {}
+        main.hostsData[ host ][ 'mac' ] =  \
+            main.Mininet1.getMacAddress( host ).upper()
+        for hostj in hostsJson:
+            if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
+                main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
+                main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
+                main.hostsData[ host ][ 'location' ] = \
+                            hostj[ 'location' ][ 'elementId' ] + '/' + \
+                            hostj[ 'location' ][ 'port' ]
+                main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
+
+    if activateResult and main.hostsData:
+        main.log.info( main.topoName + ": Successfully used fwd app" +
+                       " to discover hosts " )
+        getDataResult = main.TRUE
+    else:
+        main.log.info( main.topoName + ": Failed to use fwd app" +
+                       " to discover hosts " )
+        getDataResult = main.FALSE
+
+    main.log.info( main.topoName + ": Deactivate reactive forwarding app " )
+    activateResult = main.CLIs[ 0 ].deactivateApp( "org.onosproject.fwd" )
+    for i in range( main.numCtrls ):
+        appCheck = appCheck and main.CLIs[ i ].appToIDCheck()
+        if appCheck != main.TRUE:
+            main.log.warn( main.CLIs[ i ].apps() )
+            main.log.warn( main.CLIs[ i ].appIDs() )
+
+    # This data can be use later for intents
+    print main.hostsData
+
+    return getDataResult
+
+def reinstallOnos( main ):
+    """
+    Description:
+        Stop and start ONOS that clears hosts,devices etc. in order to test
+        new mininet topology
+    Return:
+        Retruns main.TRUE for a successful restart, main.FALSE otherwise.
+    """
+    uninstallResult = []
+    installResult = []
+    stopResult = []
+    startResult = []
+    onosIsUpResult = []
+    restartResult = main.TRUE
+
+    main.log.info( main.topoName + ": Uninstall ONOS cluster" )
+    for ip in main.ONOSip:
+        uninstallResult.append( main.ONOSbench.onosUninstall( nodeIp=ip ) )
+
+    if all( result == main.TRUE for result in uninstallResult ):
+        main.log.info( main.topoName + ": Successfully uninstall ONOS cluster" )
+    else:
+        restartResult = main.FALSE
+        main.log.error( main.topoName + ": Failed to uninstall ONOS cluster" )
+
+    time.sleep( main.startUpSleep )
+
+    main.log.info( main.topoName + ": Installing ONOS cluster" )
+
+    for i in range( main.numCtrls ):
+        installResult.append( main.ONOSbench.onosInstall(
+                                                    node=main.ONOSip[ i ] ) )
+
+    if all( result == main.TRUE for result in installResult ):
+        main.log.info( main.topoName + ": Successfully installed ONOS cluster" )
+    else:
+        restartResult = main.FALSE
+        main.log.error( main.topoName + ": Failed to install ONOS cluster" )
+
+    for i in range( main.numCtrls ):
+        onosIsUpResult.append( main.ONOSbench.isup( main.ONOSip[ i ] ) )
+
+    if all( result == main.TRUE for result in onosIsUpResult ):
+        main.log.report( "ONOS instance is up and ready" )
+    else:
+        main.log.report( "ONOS instance may not be up, stop and " +
+                         "start ONOS again " )
+        for i in range( main.numCtrls ):
+            stopResult.append( main.ONOSbench.onosStop( main.ONOSip[ i ] ) )
+
+        if all( result == main.TRUE for result in stopResult ):
+            main.log.info( main.topoName + ": Successfully stop ONOS cluster" )
+        else:
+            main.log.error( main.topoName + ": Failed to stop ONOS cluster" )
+
+        for i in range( main.numCtrls ):
+            startResult.append( main.ONOSbench.onosStart( main.ONOSip[ i ] ) )
+
+        if all( result == main.TRUE for result in startResult ):
+            main.log.info( main.topoName + ": Successfully start ONOS cluster" )
+        else:
+            main.log.error( main.topoName + ": Failed to start ONOS cluster" )
+
+    main.log.info( main.topoName + ": Starting ONOS CLI" )
+    cliResult = []
+    for i in range( main.numCtrls ):
+        cliResult.append( main.CLIs[ i ].startOnosCli( main.ONOSip[ i ] ) )
+
+    if all( result == main.TRUE for result in cliResult ):
+        main.log.info( main.topoName + ": Successfully start ONOS cli" )
+    else:
+        main.log.error( main.topoName + ": Failed to start ONOS cli" )
+        restartResult = main.FALSE
+
+
+    return restartResult
+
+
+
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/Dependency/spine.py b/TestON/tests/SCPF/SCPFscaleTopo/Dependency/spine.py
new file mode 100644
index 0000000..4aa67b3
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscaleTopo/Dependency/spine.py
@@ -0,0 +1,277 @@
+#!/usr/bin/python
+
+"""
+Custom topology for Mininet
+Author: kelvin@onlab.us
+"""
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import Host, RemoteController
+from mininet.node import Node
+from mininet.node import CPULimitedHost
+from mininet.link import TCLink
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+from mininet.util import dumpNodeConnections
+from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+import sys
+coreSwitches = {}
+spineSwitches = {}
+leafSwitches = {}
+endSwitches = {}
+allSwitches = {}
+# Counters for nodes
+totalSwitches = 0
+totalEndSwitches = 0
+totalHosts = 0
+endSwitchCount = 0 # total count of end switch in each row in gui
+class spineTopo( Topo ):
+
+    def __init__( self, **opts ):
+        "Create a topology."
+        Topo.__init__( self, **opts )
+
+    def build( self, s, l, c, e, h, **opts ):
+        """
+            s = number of spine switches
+            l = number of leaf switches
+            c = number of core
+            e = number of end switch
+            h = number of end host
+        """
+        global totalSwitches
+        global coreSwitches
+        global spineSwitches
+        global leafSwitches
+        global endSwitches
+        global totalEndSwitches
+        global totalHosts
+        global allSwitches
+        global endSwitchCount
+        endSwitchCount = e
+
+        print "Creating topology with", s,"spine", l,"leaf", c,"core",\
+                e,"end switches and",h,"host for each end switches"
+
+        self.addCore( c )
+        self.addSpine( s )
+        self.addLeaf( l )
+        self.linkLayer( coreSwitches, spineSwitches )
+        self.linkLayer( spineSwitches, leafSwitches )
+        self.linkEndSwitch( e, leafSwitches )
+        self.linkHosts( h )
+
+        allSwitches = coreSwitches
+        allSwitches.update( spineSwitches )
+        allSwitches.update( leafSwitches )
+        allSwitches.update( endSwitches )
+        deviceData = self.createSwitchDict()
+        self.genCfgJson( deviceData )
+
+
+    def addCore( self, numSwitch ):
+        global totalSwitches
+        global coreSwitches
+        for i in range( numSwitch ):
+            coreSwitches[ 'core' + str( i + 1 ) ] = self.addSwitch(
+                                             's' + str( totalSwitches + 1 ) )
+            totalSwitches += 1
+
+    def addSpine( self, numSwitch ):
+        global totalSwitches
+        global spineSwitches
+        for i in range( numSwitch ):
+            spineSwitches[ 'spine' + str( i + 1 ) ] = self.addSwitch(
+                                                 's' + str( totalSwitches + 1 ) )
+            totalSwitches += 1
+
+    def addLeaf( self, numSwitch ):
+        global totalSwitches
+        global leafSwitches
+        for i in range( numSwitch ):
+            leafSwitches[ 'leaf' + str( i + 1 ) ] = self.addSwitch(
+                                         's' + str( totalSwitches + 1 ) )
+            totalSwitches += 1
+
+    def addEnd( self ):
+        global totalSwitches
+        global totalEndSwitches
+        global endSwitches
+
+        endSwitches[ 'end' + str( totalEndSwitches + 1 ) ] = self.addSwitch(
+                                      's' + str( totalSwitches + 1 ) )
+        totalSwitches += 1
+        totalEndSwitches += 1
+
+        return endSwitches[ 'end' + str( totalEndSwitches ) ]
+
+    def addEndHosts( self ):
+        global totalHosts
+
+        totalHosts += 1
+        host = self.addHost( 'h' + str( totalHosts ) )
+
+        return host
+
+
+    def linkHosts( self, numHosts ):
+        global endSwitches
+        switches = sorted( endSwitches.values() )
+
+        for sw in switches:
+            for i in xrange( numHosts ):
+                self.addLink( sw, self.addEndHosts() )
+
+
+    def linkLayer( self, topLayer, botLayer ):
+        """
+        Description:
+            The top layer is the upper layer in the spine topology eg. top layer
+            can be the spine and the bottom layer is the leaf, another is the
+            core layer is the top layer and the spine is the bottom layer and
+            so on.
+        Required:
+            topLayer - Upper layer in the spine topology to be linked in the
+                       layer below
+            botLater - Layer that is below the upper layer to be linked at
+        """
+
+        topSwitches = sorted( topLayer.keys() )
+        botSwitches = sorted( botLayer.keys() )
+
+        for topSw in topSwitches:
+            for botSw in botSwitches:
+                self.addLink( topLayer.get( topSw ), botLayer.get( botSw ) )
+
+
+    def linkEndSwitch( self, numSwitch, leafLayer ):
+        global totalSwitches
+        global totalEndSwitches
+
+        leaf = sorted( leafLayer.values() )
+
+        for i in xrange( len( leafSwitches ) ):
+            if len( leafSwitches ) == 1:
+                for j in xrange( numSwitch ):
+                    self.addLink( leaf[ 0 ], self.addEnd() )
+                break
+            if len( leafSwitches ) == 2:
+                for j in xrange( numSwitch ):
+                    endSw = self.addEnd()
+                    self.addLink( leaf[ i ], endSw )
+                    self.addLink( leaf[ i + 1 ], endSw )
+                break
+            if i == ( len( leafSwitches ) - 1 ) and len( leafSwitches )%2:
+                for j in xrange( numSwitch ):
+                    self.addLink( leaf[ i ], self.addEnd() )
+                break
+            if i == 0:
+                for j in xrange( numSwitch ):
+                    endSw = self.addEnd()
+                    self.addLink( leaf[ i ], endSw )
+                    self.addLink( leaf[ i + 1 ], endSw )
+                continue
+            if i == 1:
+                continue
+            if i%2 == 0:
+                for j in xrange( numSwitch ):
+                    endSw = self.addEnd()
+                    self.addLink( leaf[ i ], endSw )
+                    self.addLink( leaf[ i + 1 ], endSw )
+
+    def genCfgJson( self, deviceData ):
+        import json
+        configJson = {}
+        configJson[ "devices" ] = deviceData
+        with open( 'spine.json', 'w+' ) as outfile:
+            json.dump( configJson, outfile )
+        #cfgFile = open( "spine.json" , 'w+' )
+        #cfgFile.write( configJson )
+        #cfgFile.close()
+
+
+
+    def createSwitchDict( self ):
+        global allSwitches
+        global endSwitchCount
+
+        latitude = 0
+        longitude = 0
+        coreLong = -70
+        spineLong = -80
+        leafLong = -90
+        endLat = 30
+        rowCount = 0 # count of end switches or rows
+        colOffSet = 0 # off set for end switches; longitude
+
+        #for i in xrange( len( allSwitches ) ):
+        deviceList = []
+        deviceDict = {}
+        for sw in allSwitches:
+            tempSw = allSwitches.get( sw )
+            uri = str( "{0:0>16}".format( str( hex( int( tempSw[ 1: ] ) )\
+                            ).split( "x" )[ 1 ] ) )
+            mac = str( "{0:0>12}".format( str( hex( int( tempSw[ 1: ] ) )\
+                            ).split( "x" )[ 1 ] ) )
+
+            if "core" in sw:
+                latitude = 45
+                longitude = coreLong
+                coreLong += 2.5
+            elif "spine" in sw:
+                latitude = 40
+                longitude = spineLong
+                spineLong += 1.5
+            elif "leaf" in sw:
+                latitude = 35
+                longitude = leafLong
+                leafLong += 1.5
+            elif "end" in sw:
+                # Reset position and move to the right once every
+                # number of end switches
+                if rowCount == endSwitchCount:
+                    colOffSet += 2.5
+                    rowCount = 0
+                    endLat = 30
+                longitude = -80 + colOffSet
+                latitude = endLat
+                endLat -= 1
+                rowCount += 1
+
+            tempItem = { "alias": allSwitches.get( sw ) ,
+                         "uri": "of:" + uri,
+                         "mac": mac,
+                         "annotations": { "name": sw,
+                                          "latitude": latitude,
+                                          "longitude": longitude },
+                         "type": "SWITCH" }
+            deviceList.append( tempItem )
+
+        return deviceList
+    #def createHostsJson( hostDict ):
+
+topos = { 'spine': ( lambda s=2, l=3, c=1, e=5, h=1: spineTopo( s=s,
+                                                                l=l,
+                                                                c=c,
+                                                                e=e,
+                                                                h=h) ) }
+
+# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS
+
+def setupNetwork():
+    "Create network"
+    topo = spineTopo()
+    #if controller_ip == '':
+        #controller_ip = '10.0.2.2';
+    #    controller_ip = '127.0.0.1';
+    network = Mininet( topo=topo,
+                       autoSetMacs=True,
+                       controller=None )
+    network.start()
+    CLI( network )
+    network.stop()
+
+if __name__ == '__main__':
+    setLogLevel( 'info' )
+    #setLogLevel('debug')
+    setupNetwork()
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/Dependency/startUp.py b/TestON/tests/SCPF/SCPFscaleTopo/Dependency/startUp.py
new file mode 100644
index 0000000..bf2a2b6
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscaleTopo/Dependency/startUp.py
@@ -0,0 +1,38 @@
+"""
+    This wrapper function is use for starting up onos instance
+"""
+
+import time
+import os
+import json
+
+def onosBuild( main, gitBranch ):
+    """
+        This includes pulling ONOS and building it using maven install
+    """
+
+    buildResult = main.FALSE
+
+    # Git checkout a branch of ONOS
+    checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
+    # Does the git pull on the branch that was checked out
+    if not checkOutResult:
+        main.log.warn( "Failed to checked out " + gitBranch +
+                                           " branch")
+    else:
+        main.log.info( "Successfully checked out " + gitBranch +
+                                           " branch")
+    gitPullResult = main.ONOSbench.gitPull()
+    if gitPullResult == main.ERROR:
+        main.log.error( "Error pulling git branch" )
+    else:
+        main.log.info( "Successfully pulled " + gitBranch + " branch" )
+
+    # Maven clean install
+    buildResult = main.ONOSbench.cleanInstall()
+
+    return buildResult
+
+
+
+
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/Dependency/topo.py b/TestON/tests/SCPF/SCPFscaleTopo/Dependency/topo.py
new file mode 100644
index 0000000..0dbb02d
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscaleTopo/Dependency/topo.py
@@ -0,0 +1,100 @@
+"""
+    These functions can be used for topology comparisons
+"""
+
+import time
+import os
+import json
+
+def getAllDevices( main ):
+    """
+        Return a list containing the devices output from each ONOS node
+    """
+    devices = []
+    threads = []
+    for i in main.activeNodes:
+        t = main.Thread( target=main.CLIs[i].devices,
+                         name="devices-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        devices.append( t.result )
+    return devices
+
+def getAllHosts( main ):
+    """
+        Return a list containing the hosts output from each ONOS node
+    """
+    hosts = []
+    ipResult = main.TRUE
+    threads = []
+    for i in main.activeNodes:
+        t = main.Thread( target=main.CLIs[i].hosts,
+                         name="hosts-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        hosts.append( t.result )
+    return hosts
+
+def getAllPorts( main ):
+    """
+        Return a list containing the ports output from each ONOS node
+    """
+    ports = []
+    threads = []
+    for i in main.activeNodes:
+        t = main.Thread( target=main.CLIs[i].ports,
+                         name="ports-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        ports.append( t.result )
+    return ports
+
+def getAllLinks( main ):
+    """
+        Return a list containing the links output from each ONOS node
+    """
+    links = []
+    threads = []
+    for i in main.activeNodes:
+        t = main.Thread( target=main.CLIs[i].links,
+                         name="links-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        links.append( t.result )
+    return links
+
+def getAllClusters( main ):
+    """
+        Return a list containing the clusters output from each ONOS node
+    """
+    clusters = []
+    threads = []
+    for i in main.activeNodes:
+        t = main.Thread( target=main.CLIs[i].clusters,
+                         name="clusters-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        clusters.append( t.result )
+    return clusters
+
+
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/README b/TestON/tests/SCPF/SCPFscaleTopo/README
new file mode 100644
index 0000000..16df150
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscaleTopo/README
@@ -0,0 +1,8 @@
+Summary:
+        This is a performance test suite that is designed to test
+        large topologies. It also contains a failure case that brings
+        down an onos controller to see if the neighboring controllers
+        pick up the rest of the devices.
+NOTE:
+        This test does not scale onos controllers. The number of
+        controllers is fixed at 3.
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.params b/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.params
new file mode 100755
index 0000000..986145e
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.params
@@ -0,0 +1,58 @@
+<PARAMS>
+
+    # 1 - optional pull and build ONOS package
+    # 2 - set cell and install ONOS
+    # 10 - start mininet
+    # 11 - pingall and verify topo
+    # 100 - balance master and bring onos node down
+    # 200 - bring onos node up and balance masters
+    # 1000 - report logs
+
+    <testcases>1,2,[10,300,11,100,300,11,200,300,11,1000]*3</testcases>
+
+    <DEPENDENCY>
+        <path>/tests/SCPFscaleTopo/dependencies/</path>
+        <wrapper1>startUp</wrapper1>
+        <wrapper2>scaleTopoFunction</wrapper2>
+        <wrapper3>topo</wrapper3>
+        <multiovs>multiovs.py</multiovs>
+    </DEPENDENCY>
+
+    <ENV>
+        <cellApps>drivers,openflow,fwd</cellApps>
+    </ENV>
+
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
+
+    <CTRL>
+        <port>6653</port>
+        <numCtrls>3</numCtrls>
+    </CTRL>
+
+    <SLEEP>
+        <startup>15</startup>
+        <balance>10</balance>
+        <nodeSleep>10</nodeSleep>
+        <pingall>15</pingall>
+        <MNsleep>5</MNsleep>
+    </SLEEP>
+
+    <TIMEOUT>
+        # pingall timeout unit: ms
+        <pingall>0.03</pingall>
+    </TIMEOUT>
+
+    <ATTEMPTS>
+        <topoCmp>1</topoCmp>
+        <pingall>3</pingall>
+    </ATTEMPTS>
+
+    <TOPOLOGY>
+        <topology>torus</topology>
+        <scale>5,10,15</scale>
+    </TOPOLOGY>
+
+</PARAMS>
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.py b/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.py
new file mode 100644
index 0000000..830fbf2
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.py
@@ -0,0 +1,431 @@
+
+# Testing network scalability, this test suite scales up a network topology
+# using mininet and verifies ONOS stability
+
+class SCPFscaleTopo:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):
+        import time
+        import os
+        import imp
+        import re
+
+        """
+        - Construct tests variables
+        - GIT ( optional )
+            - Checkout ONOS master branch
+            - Pull latest ONOS code
+        - Building ONOS ( optional )
+            - Install ONOS package
+            - Build ONOS package
+        """
+
+        main.case( "Constructing test variables" )
+        main.step( "Constructing test variables" )
+        stepResult = main.FALSE
+
+        main.testOnDirectory = os.path.dirname( os.getcwd ( ) )
+        main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+        gitBranch = main.params[ 'GIT' ][ 'branch' ]
+        main.dependencyPath = main.testOnDirectory + \
+                              main.params[ 'DEPENDENCY' ][ 'path' ]
+        main.multiovs = main.params[ 'DEPENDENCY' ][ 'multiovs' ]
+        main.topoName = main.params[ 'TOPOLOGY' ][ 'topology' ]
+        main.numCtrls = int( main.params[ 'CTRL' ][ 'numCtrls' ] )
+        main.topoScale = ( main.params[ 'TOPOLOGY' ][ 'scale' ] ).split( "," )
+        main.topoScaleSize = len( main.topoScale )
+        wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
+        wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
+        wrapperFile3 = main.params[ 'DEPENDENCY' ][ 'wrapper3' ]
+        main.topoCmpAttempts = int( main.params[ 'ATTEMPTS' ][ 'topoCmp' ] )
+        main.pingallAttempts = int( main.params[ 'ATTEMPTS' ][ 'pingall' ] )
+        main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+        main.balanceSleep = int( main.params[ 'SLEEP' ][ 'balance' ] )
+        main.nodeSleep = int( main.params[ 'SLEEP' ][ 'nodeSleep' ] )
+        main.pingallSleep = int( main.params[ 'SLEEP' ][ 'pingall' ] )
+        main.MNSleep = int( main.params[ 'SLEEP' ][ 'MNsleep' ] )
+        main.pingTimeout = float( main.params[ 'TIMEOUT' ][ 'pingall' ] )
+        gitPull = main.params[ 'GIT' ][ 'pull' ]
+        main.homeDir = os.path.expanduser('~')
+        main.cellData = {} # for creating cell file
+        main.hostsData = {}
+        main.CLIs = []
+        main.ONOSip = []
+        main.activeNodes = []
+        main.ONOSip = main.ONOSbench.getOnosIps()
+
+        for i in range(main.numCtrls):
+                main.CLIs.append( getattr( main, 'ONOScli%s' % (i+1) ) )
+
+        main.startUp = imp.load_source( wrapperFile1,
+                                        main.dependencyPath +
+                                        wrapperFile1 +
+                                        ".py" )
+
+        main.scaleTopoFunction = imp.load_source( wrapperFile2,
+                                                  main.dependencyPath +
+                                                  wrapperFile2 +
+                                                  ".py" )
+
+        main.topo = imp.load_source( wrapperFile3,
+                                     main.dependencyPath +
+                                     wrapperFile3 +
+                                     ".py" )
+
+        main.ONOSbench.scp( main.Mininet1,
+                            main.dependencyPath +
+                            main.multiovs,
+                            main.Mininet1.home,
+                            direction="to" )
+
+        if main.CLIs:
+                stepResult = main.TRUE
+        else:
+            main.log.error( "Did not properly created list of " +
+                            "ONOS CLI handle" )
+            stepResult = main.FALSE
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully construct " +
+                                        "test variables ",
+                                 onfail="Failed to construct test variables" )
+
+        if gitPull == 'True':
+            main.step( "Building ONOS in " + gitBranch + " branch" )
+            onosBuildResult = main.startUp.onosBuild( main, gitBranch )
+            stepResult = onosBuildResult
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=stepResult,
+                                     onpass="Successfully compiled " +
+                                            "latest ONOS",
+                                     onfail="Failed to compile " +
+                                            "latest ONOS" )
+        else:
+            main.log.warn( "Did not pull new code so skipping mvn " +
+                           "clean install" )
+
+
+    def CASE2( self, main):
+        """
+        - Set up cell
+            - Create cell file
+            - Set cell file
+            - Verify cell file
+        - Kill ONOS process
+        - Uninstall ONOS cluster
+        - Verify ONOS start up
+        - Install ONOS cluster
+        - Connect to cli
+        """
+
+        main.case( "Starting up " + str( main.numCtrls ) +
+                   " node(s) ONOS cluster" )
+        main.caseExplanation = "Set up ONOS with " + str( main.numCtrls ) +\
+                                " node(s) ONOS cluster"
+
+
+
+        #kill off all onos processes
+        main.log.info( "Safety check, killing all ONOS processes" +
+                       " before initiating environment setup" )
+
+        for i in range( main.numCtrls ):
+            main.ONOSbench.onosDie( main.ONOSip[ i ] )
+
+        tempOnosIp = []
+        for i in range( main.numCtrls ):
+            tempOnosIp.append( main.ONOSip[i] )
+
+        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
+                                       "temp", main.Mininet1.ip_address,
+                                       main.apps, tempOnosIp )
+
+        main.step( "Apply cell to environment" )
+        cellResult = main.ONOSbench.setCell( "temp" )
+        verifyResult = main.ONOSbench.verifyCell()
+        stepResult = cellResult and verifyResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully applied cell to " + \
+                                        "environment",
+                                 onfail="Failed to apply cell to environment " )
+
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.onosPackage()
+        stepResult = packageResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully created ONOS package",
+                                 onfail="Failed to create ONOS package" )
+
+        time.sleep( main.startUpSleep )
+        main.step( "Uninstalling ONOS package" )
+        onosUninstallResult = main.TRUE
+        for ip in main.ONOSip:
+            onosUninstallResult = onosUninstallResult and \
+                    main.ONOSbench.onosUninstall( nodeIp=ip )
+        stepResult = onosUninstallResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully uninstalled ONOS package",
+                                 onfail="Failed to uninstall ONOS package" )
+
+        time.sleep( main.startUpSleep )
+        main.step( "Installing ONOS package" )
+        onosInstallResult = main.TRUE
+        for i in range( main.numCtrls ):
+            onosInstallResult = onosInstallResult and \
+                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
+        stepResult = onosInstallResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully installed ONOS package",
+                                 onfail="Failed to install ONOS package" )
+
+        time.sleep( main.startUpSleep )
+        main.step( "Starting ONOS service" )
+        stopResult = main.TRUE
+        startResult = main.TRUE
+        onosIsUp = main.TRUE
+
+        for i in range( main.numCtrls ):
+            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
+        if onosIsUp == main.TRUE:
+            main.log.report( "ONOS instance is up and ready" )
+        else:
+            main.log.report( "ONOS instance may not be up, stop and " +
+                             "start ONOS again " )
+
+            for i in range( main.numCtrls ):
+                stopResult = stopResult and \
+                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
+            for i in range( main.numCtrls ):
+                startResult = startResult and \
+                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
+        stepResult = onosIsUp and stopResult and startResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="ONOS service is ready",
+                                 onfail="ONOS service did not start properly" )
+
+        main.step( "Start ONOS cli" )
+        cliResult = main.TRUE
+        for i in range( main.numCtrls ):
+            cliResult = cliResult and \
+                        main.CLIs[ i ].startOnosCli( main.ONOSip[ i ] )
+            main.activeNodes.append( i )
+        stepResult = cliResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully start ONOS cli",
+                                 onfail="Failed to start ONOS cli" )
+
+
+    def CASE10( self, main ):
+        """
+            Starting up torus topology
+        """
+        import json
+
+        main.case( "Starting up Mininet and verifying topology" )
+        main.caseExplanation = "Starting Mininet with a scalling topology and " +\
+                "comparing topology elements between Mininet and ONOS"
+
+        main.log.info( "Checking if mininet is already running" )
+        if len( main.topoScale ) < main.topoScaleSize:
+            main.log.info( "Mininet is already running. Stopping mininet." )
+            main.Mininet1.stopNet()
+            time.sleep(main.MNSleep)
+        else:
+            main.log.info( "Mininet was not running" )
+
+        if main.topoScale:
+            main.currScale = main.topoScale.pop(0)
+        else: main.log.error( "topology scale is empty" )
+
+
+        main.step( "Starting up TORUS %sx%s topology" % (main.currScale, main.currScale) )
+
+        main.log.info( "Constructing Mininet command" )
+        mnCmd = " mn --custom " + main.Mininet1.home + main.multiovs +\
+                " --switch ovsm --topo " + main.topoName + ","+ main.currScale + "," + main.currScale
+
+        for i in range( main.numCtrls ):
+                mnCmd += " --controller remote,ip=" + main.ONOSip[ i ]
+
+        stepResult = main.Mininet1.startNet(mnCmd=mnCmd)
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass=main.topoName +
+                                    " topology started successfully",
+                                 onfail=main.topoName +
+                                    " topology failed to start" )
+
+        time.sleep( main.MNSleep )
+
+    def CASE11( self, main ):
+        """
+            Pingall, and compare topo
+            We don't care the pingall result,
+            if the topology is same, then Pass.
+        """
+        import json
+
+        main.case( "Verifying topology: TORUS %sx%s" % (main.currScale, main.currScale) )
+        main.caseExplanation = "Pinging all hosts and comparing topology " +\
+                "elements between Mininet and ONOS"
+
+        main.log.info( "Pinging all hosts" )
+
+        # the pingall timeout is depend on the number of total host
+        pingTimeout = int( main.pingTimeout * float( int(main.currScale) * int(main.currScale ) ) )
+        pingResult = main.Mininet1.pingall( pingTimeout )
+
+        main.log.info( "Gathering topology information" )
+
+        time.sleep( main.MNSleep )
+
+        devicesResults = main.TRUE
+        linksResults = main.TRUE
+        hostsResults = main.TRUE
+        stepResult = main.TRUE
+        devices = main.topo.getAllDevices( main )
+        hosts = main.topo.getAllHosts( main )
+        ports = main.topo.getAllPorts( main )
+        links = main.topo.getAllLinks( main )
+        clusters = main.topo.getAllClusters( main )
+        mnSwitches = main.Mininet1.getSwitches()
+        mnLinks = main.Mininet1.getLinks()
+        mnHosts = main.Mininet1.getHosts()
+
+        main.step( "Comparing MN topology to ONOS topology" )
+        for controller in range(len(main.activeNodes)):
+            controllerStr = str( main.activeNodes[controller] + 1 )
+            if devices[ controller ] and ports[ controller ] and\
+                "Error" not in devices[ controller ] and\
+                "Error" not in ports[ controller ]:
+
+                currentDevicesResult = main.Mininet1.compareSwitches(
+                        mnSwitches,
+                        json.loads( devices[ controller ] ),
+                        json.loads( ports[ controller ] ) )
+            else:
+                currentDevicesResult = main.FALSE
+ 
+            if links[ controller ] and "Error" not in links[ controller ]:
+                currentLinksResult = main.Mininet1.compareLinks(
+                        mnSwitches, mnLinks,
+                        json.loads( links[ controller ] ) )
+            else:
+                currentLinksResult = main.FALSE
+
+            if hosts[ controller ] or "Error" not in hosts[ controller ]:
+                currentHostsResult = main.Mininet1.compareHosts(
+                        mnHosts,
+                        json.loads( hosts[ controller ] ) )
+            else:
+                currentHostsResult = main.FALSE
+
+            stepResult = stepResult and currentDevicesResult and currentLinksResult and currentHostsResult
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass=" Topology match Mininet",
+                                 onfail="ONOS" + controllerStr +
+                                 " Topology doesn't match Mininet" )
+
+
+    def CASE100( self, main ):
+        '''
+           Bring Down node 3 
+        '''
+
+        main.case("Balancing Masters and bring ONOS node 3 down: TORUS %sx%s" % (main.currScale, main.currScale))
+        main.caseExplanation = "Balance masters to make sure " +\
+                        "each controller has some devices and " +\
+                        "stop ONOS node 3 service. "
+
+        stepResult = main.FALSE
+        main.step( "Bringing down node 3" )
+        # Always bring down the third node
+        main.deadNode = 2
+        # Printing purposes
+        node = main.deadNode + 1
+        main.log.info( "Stopping node %s" % node )
+        stepResult = main.ONOSbench.onosStop( main.ONOSip[ main.deadNode ] )
+        main.log.info( "Removing dead node from list of active nodes" )
+        main.activeNodes.pop( main.deadNode )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully bring down node 3",
+                                 onfail="Failed to bring down node 3" )
+
+    def CASE200( self, main ):
+        '''
+            Bring up onos node and balance masters
+        '''
+
+        main.case("Bring ONOS node 3 up and balance masters: TORUS %sx%s" % (main.currScale, main.currScale))
+        main.caseExplanation = "Bring node 3 back up and balance the masters"
+
+        node = main.deadNode + 1
+        main.log.info( "Starting node %s" % node )
+        stepResult = main.ONOSbench.onosStart( main.ONOSip[ main.deadNode ] )
+        main.log.info( "Starting onos cli" )
+        stepResult = stepResult and main.CLIs[ main.deadNode ].startOnosCli( main.ONOSip[ main.deadNode ] )
+
+        main.log.info( "Adding previously dead node to list of active nodes" )
+        main.activeNodes.append( main.deadNode )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully brought up onos node %s" % node,
+                                 onfail="Failed to bring up onos node %s" % node )
+
+
+        time.sleep(main.nodeSleep)
+
+    def CASE300( self, main ):
+        '''
+
+            Balancing Masters
+        '''
+        time.sleep(main.balanceSleep)
+        main.step( "Balancing Masters" )
+
+        stepResult = main.FALSE
+        if main.activeNodes:
+            controller = main.activeNodes[0]
+            stepResult = utilities.retry( main.CLIs[controller].balanceMasters,
+                                          main.FALSE,
+                                          [],
+                                          sleep=3,
+                                          attempts=3 )
+
+        else:
+            main.log.error( "List of active nodes is empty" )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Balance masters was successfull",
+                                 onfail="Failed to balance masters")
+        time.sleep(main.balanceSleep)
+
+    def CASE1000( self, main ):
+        '''
+            Report errors/warnings/exceptions
+        '''
+        main.case( "Checking logs for errors, warnings, and exceptions" )
+        main.log.info("Error report: \n" )
+        main.ONOSbench.logReport( main.ONOSip[ 0 ],
+                                                            [ "INFO",
+                                                              "FOLLOWER",
+                                                              "WARN",
+                                                              "flow",
+                                                              "ERROR",
+                                                              "Except" ],
+                                                            "s" )
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.topo b/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.topo
new file mode 100755
index 0000000..a47522d
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.topo
@@ -0,0 +1,57 @@
+<TOPOLOGY>
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+                <nodes>3</nodes>
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOScli1>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOScli1>
+
+        <ONOScli2>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOScli2>
+
+         <ONOScli3>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOScli3>
+
+        <Mininet1>
+            <host>OCN</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>MininetCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS>
+                <home>~/mininet/custom/</home>
+            </COMPONENTS>
+        </Mininet1>
+
+    </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/__init__.py b/TestON/tests/SCPF/SCPFscaleTopo/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscaleTopo/__init__.py
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntents/Dependency/rerouteTopo.py b/TestON/tests/SCPF/SCPFscalingMaxIntents/Dependency/rerouteTopo.py
new file mode 100755
index 0000000..774f12f
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscalingMaxIntents/Dependency/rerouteTopo.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+
+"""
+Custom topology for Mininet
+"""
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import Host, RemoteController
+from mininet.node import Node
+from mininet.link import TCLink
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+from mininet.util import dumpNodeConnections
+from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+
+class MyTopo( Topo ):
+
+    def __init__( self ):
+        # Initialize topology
+        Topo.__init__( self )
+
+        host1 = self.addHost('h1', ip='10.1.0.1/24')
+        host2 = self.addHost('h2', ip='10.1.0.2/24')
+        host3 = self.addHost('h3', ip='10.1.0.3/24')
+        host4 = self.addHost('h4', ip='10.1.0.4/24')
+        host5 = self.addHost('h5', ip='10.1.0.5/24')
+        host6 = self.addHost('h6', ip='10.1.0.6/24')
+        host7 = self.addHost('h7', ip='10.1.0.7/24')
+
+        s1 = self.addSwitch( 's1' )
+        s2 = self.addSwitch( 's2' )
+        s3 = self.addSwitch( 's3' )
+        s4 = self.addSwitch( 's4' )
+        s5 = self.addSwitch( 's5' )
+        s6 = self.addSwitch( 's6' )
+        s7 = self.addSwitch( 's7' )
+        s8 = self.addSwitch( 's8' )
+
+
+        self.addLink(s1, host1)
+        self.addLink(s2, host2)
+        self.addLink(s3, host3)
+        self.addLink(s4, host4)
+        self.addLink(s5, host5)
+        self.addLink(s6, host6)
+        self.addLink(s7, host7)
+
+
+
+        self.addLink(s1,s2)
+        self.addLink(s2,s3)
+        self.addLink(s3,s4)
+        self.addLink(s4,s5)
+        self.addLink(s5,s6)
+        self.addLink(s6,s7)
+        self.addLink(s4,s8)
+        self.addLink(s8,s5)
+
+        topos = { 'mytopo': ( lambda: MyTopo() ) }
+
+# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS
+
+def setupNetwork():
+    "Create network"
+    topo = MyTopo()
+    network = Mininet(topo=topo, autoSetMacs=True, controller=None)
+    network.start()
+    CLI( network )
+    network.stop()
+
+if __name__ == '__main__':
+    setLogLevel('info')
+    #setLogLevel('debug')
+    setupNetwork()
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntents/Dependency/startUp.py b/TestON/tests/SCPF/SCPFscalingMaxIntents/Dependency/startUp.py
new file mode 100644
index 0000000..bf2a2b6
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscalingMaxIntents/Dependency/startUp.py
@@ -0,0 +1,38 @@
+"""
+    This wrapper function is use for starting up onos instance
+"""
+
+import time
+import os
+import json
+
+def onosBuild( main, gitBranch ):
+    """
+        This includes pulling ONOS and building it using maven install
+    """
+
+    buildResult = main.FALSE
+
+    # Git checkout a branch of ONOS
+    checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
+    # Does the git pull on the branch that was checked out
+    if not checkOutResult:
+        main.log.warn( "Failed to checked out " + gitBranch +
+                                           " branch")
+    else:
+        main.log.info( "Successfully checked out " + gitBranch +
+                                           " branch")
+    gitPullResult = main.ONOSbench.gitPull()
+    if gitPullResult == main.ERROR:
+        main.log.error( "Error pulling git branch" )
+    else:
+        main.log.info( "Successfully pulled " + gitBranch + " branch" )
+
+    # Maven clean install
+    buildResult = main.ONOSbench.cleanInstall()
+
+    return buildResult
+
+
+
+
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntents/README b/TestON/tests/SCPF/SCPFscalingMaxIntents/README
new file mode 100644
index 0000000..0c16859
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscalingMaxIntents/README
@@ -0,0 +1,11 @@
+Summary:
+        This is a performance test suit, designed to test the upper limits
+        of onos and ovsdb with respect to installing intents.
+        In this test, CASE10 set up null provoder, CASE 11 set up ovs. Start from
+        1 node, and scale to 7 nodes.
+        We push intents to every node by using Thread, and when the intents number
+        reach to the minimun number, we will verify intents and flows. If intents are
+        not installed correctly, test will stop pushing and finish this case.
+NOTE:
+        This test is largely based on the hardware used to run onos and mininet.
+        Therefore, results will very test station to test station.
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.params b/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.params
new file mode 100644
index 0000000..6efe17e
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.params
@@ -0,0 +1,99 @@
+<PARAMS>
+
+    # 0-init
+    # 1-setup
+    # 2-Install
+    # 10-null provider setup
+    # 20-pushing intents, and rerouting intents if reroute is true
+    # 0,1,2,10,20,1,2,10,20,1,2,10,20
+   <testcases>0,1,2,11,20,1,2,11,20,1,2,11,20,1,2,11,20</testcases>
+
+    <reroute>False</reroute>
+
+    <SCALE>1,3,5,7</SCALE>
+
+    <DEPENDENCY>
+        <path>/tests/SCPFscalingMaxIntents/dependencies/</path>
+        <wrapper1>startUp</wrapper1>
+        <topology>rerouteTopo.py</topology>
+    </DEPENDENCY>
+
+    <ENV>
+        <cellName>productionCell</cellName>
+        <cellApps>drivers</cellApps>
+    </ENV>
+
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
+
+    <CTRL>
+        <port>6653</port>
+    </CTRL>
+
+    <SLEEP>
+        <startup>10</startup>
+        <install>10</install>
+        <verify>15</verify>
+        <reroute>3</reroute>
+        # timeout for pexpect
+        <timeout>300</timeout>
+    </SLEEP>
+
+    <ATTEMPTS>
+        <verify>3</verify>
+        <push>3</push>
+    </ATTEMPTS>
+
+    <DATABASE>
+        <file>/tmp/ScalingMaxIntentDB</file>
+        <nic>1gig</nic>
+        <node>baremetal</node>
+    </DATABASE>
+
+    <LINK>
+        <ingress>0000000000000001/5</ingress>
+        <egress>0000000000000007/5</egress>
+    </LINK>
+
+    # CASE10
+    <NULL>
+        # CASE20
+        <PUSH>
+            <batch_size>100</batch_size>
+            <min_intents>100</min_intents>
+            <max_intents>100000</max_intents>
+            <check_interval>100</check_interval>
+        </PUSH>
+
+        # if reroute is true
+        <REROUTE>
+            <batch_size>1000</batch_size>
+            <min_intents>10000</min_intents>
+            <max_intents>1000000</max_intents>
+            <check_interval>100000</check_interval>
+        </REROUTE>
+    </NULL>
+
+    # CASE11
+    <OVS>
+        # CASE20
+        <PUSH>
+            <batch_size>1000</batch_size>
+            <min_intents>10000</min_intents>
+            <max_intents>500000</max_intents>
+            <check_interval>10000</check_interval>
+        </PUSH>
+
+        # if reroute is true
+        <REROUTE>
+            <batch_size>1000</batch_size>
+            <min_intents>10000</min_intents>
+            <max_intents>500000</max_intents>
+            <check_interval>10000</check_interval>
+        </REROUTE>
+    </OVS>
+
+
+</PARAMS>
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.py b/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.py
new file mode 100644
index 0000000..27bc5c2
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.py
@@ -0,0 +1,558 @@
+import sys
+import json
+import time
+import os
+'''
+SCPFscalingMaxIntents
+Push test Intents to onos
+CASE10: set up Null Provider
+CASE11: set up Open Flows
+Scale up when reach the Limited
+Start from 1 nodes, 8 devices. Then Scale up to 3,5,7 nodes
+Recommand batch size: 100, check interval: 100
+'''
+class SCPFscalingMaxIntents:
+    def __init__( self ):
+        self.default = ''
+
+    def CASE0( self, main):
+        import sys
+        import json
+        import time
+        import os
+        import imp
+
+        main.case( "Constructing test variables and building ONOS package" )
+        main.step( "Constructing test variables" )
+        stepResult = main.FALSE
+
+        # Test variables
+        main.testOnDirectory = os.path.dirname( os.getcwd ( ) )
+        main.dependencyPath = main.testOnDirectory + \
+                main.params['DEPENDENCY']['path']
+        main.cellName = main.params[ 'ENV' ][ 'cellName' ]
+        main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+        main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
+        main.scale = ( main.params[ 'SCALE' ] ).split( "," )
+        main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
+        main.timeout = int(main.params['SLEEP']['timeout'])
+        main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+        main.installSleep = int( main.params[ 'SLEEP' ][ 'install' ] )
+        main.verifySleep = int( main.params[ 'SLEEP' ][ 'verify' ] )
+        main.rerouteSleep = int ( main.params['SLEEP']['reroute'] )
+        main.verifyAttempts = int( main.params['ATTEMPTS']['verify'] )
+        main.ingress = main.params['LINK']['ingress']
+        main.egress = main.params['LINK']['egress']
+        main.dbFileName = main.params['DATABASE']['file']
+        main.cellData = {} # for creating cell file
+        main.reroute = main.params['reroute']
+        main.threadID = 0
+
+        if main.reroute == "True":
+            main.reroute = True
+        else:
+            main.reroute = False
+
+        main.CLIs = []
+        main.ONOSip = []
+        main.maxNumBatch = 0
+        main.ONOSip = main.ONOSbench.getOnosIps()
+        main.log.info(main.ONOSip)
+        main.setupSkipped = False
+
+        wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
+        gitBranch = main.params[ 'GIT' ][ 'branch' ]
+        gitPull = main.params[ 'GIT' ][ 'pull' ]
+        nic = main.params['DATABASE']['nic']
+        node = main.params['DATABASE']['node']
+        nic = main.params['DATABASE']['nic']
+        node = main.params['DATABASE']['node']
+        stepResult = main.TRUE
+
+        main.log.info("Cresting DB file")
+        with open(main.dbFileName, "w+") as dbFile:
+            dbFile.write("")
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="environment set up successfull",
+                                 onfail="environment set up Failed" )
+
+    def CASE1( self ):
+        # main.scale[ 0 ] determines the current number of ONOS controller
+        main.CLIs = []
+        main.numCtrls = int( main.scale[ 0 ] )
+        main.log.info( "Creating list of ONOS cli handles" )
+        for i in range(main.numCtrls):
+            main.CLIs.append( getattr( main, 'ONOScli%s' % (i+1) ) )
+
+        main.log.info(main.CLIs)
+        if not main.CLIs:
+            main.log.error( "Failed to create the list of ONOS cli handles" )
+            main.cleanup()
+            main.exit()
+
+        main.log.info( "Loading wrapper files" )
+        main.startUp = imp.load_source( wrapperFile1,
+                                        main.dependencyPath +
+                                        wrapperFile1 +
+                                        ".py" )
+
+        copyResult = main.ONOSbench.copyMininetFile( main.topology,
+                                                     main.dependencyPath,
+                                                     main.Mininet1.user_name,
+                                                     main.Mininet1.ip_address )
+
+        commit = main.ONOSbench.getVersion(report=True)
+        commit = commit.split(" ")[1]
+
+        if gitPull == 'True':
+            if not main.startUp.onosBuild( main, gitBranch ):
+                main.log.error( "Failed to build ONOS" )
+                main.cleanup()
+                main.exit()
+        else:
+            main.log.warn( "Did not pull new code so skipping mvn " +
+                           "clean install" )
+        with open(main.dbFileName, "a") as dbFile:
+            temp = "'" + commit + "',"
+            temp += "'" + nic + "',"
+            dbFile.write(temp)
+
+    def CASE2( self, main ):
+        """
+        - Uninstall ONOS cluster
+        - Verify ONOS start up
+        - Install ONOS cluster
+        - Connect to cli
+        """
+        main.log.info( "Starting up %s node(s) ONOS cluster" % main.numCtrls)
+        main.log.info( "Safety check, killing all ONOS processes" +
+                       " before initiating environment setup" )
+
+        for i in range( main.numCtrls ):
+            main.ONOSbench.onosDie( main.ONOSip[ i ] )
+
+        main.log.info( "NODE COUNT = %s" % main.numCtrls)
+
+        tempOnosIp = []
+        for i in range( main.numCtrls ):
+            tempOnosIp.append( main.ONOSip[i] )
+
+        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
+                                       "temp",
+                                       main.Mininet1.ip_address,
+                                       main.apps,
+                                       tempOnosIp )
+
+        main.step( "Apply cell to environment" )
+        cellResult = main.ONOSbench.setCell( "temp" )
+        verifyResult = main.ONOSbench.verifyCell()
+        stepResult = cellResult and verifyResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully applied cell to " + \
+                                        "environment",
+                                 onfail="Failed to apply cell to environment " )
+
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.onosPackage()
+        stepResult = packageResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully created ONOS package",
+                                 onfail="Failed to create ONOS package" )
+
+        main.step( "Uninstall ONOS package on all Nodes" )
+        uninstallResult = main.TRUE
+        for i in range( int( main.numCtrls ) ):
+            main.log.info( "Uninstalling package on ONOS Node IP: " + main.ONOSip[i] )
+            u_result = main.ONOSbench.onosUninstall( main.ONOSip[i] )
+            utilities.assert_equals( expect=main.TRUE, actual=u_result,
+                                     onpass="Test step PASS",
+                                     onfail="Test step FAIL" )
+            uninstallResult = ( uninstallResult and u_result )
+
+        main.step( "Install ONOS package on all Nodes" )
+        installResult = main.TRUE
+        for i in range( int( main.numCtrls ) ):
+            main.log.info( "Installing package on ONOS Node IP: " + main.ONOSip[i] )
+            i_result = main.ONOSbench.onosInstall( node=main.ONOSip[i] )
+            utilities.assert_equals( expect=main.TRUE, actual=i_result,
+                                     onpass="Test step PASS",
+                                     onfail="Test step FAIL" )
+            installResult = installResult and i_result
+
+        main.step( "Verify ONOS nodes UP status" )
+        statusResult = main.TRUE
+        for i in range( int( main.numCtrls ) ):
+            main.log.info( "ONOS Node " + main.ONOSip[i] + " status:" )
+            onos_status = main.ONOSbench.onosStatus( node=main.ONOSip[i] )
+            utilities.assert_equals( expect=main.TRUE, actual=onos_status,
+                                     onpass="Test step PASS",
+                                     onfail="Test step FAIL" )
+            statusResult = ( statusResult and onos_status )
+
+        main.step( "Start ONOS CLI on all nodes" )
+        cliResult = main.TRUE
+        main.log.step(" Start ONOS cli using thread ")
+        startCliResult  = main.TRUE
+        pool = []
+
+        for i in range( int( main.numCtrls) ):
+            t = main.Thread( target=main.CLIs[i].startOnosCli,
+                             threadID=main.threadID,
+                             name="startOnosCli",
+                             args=[ main.ONOSip[i] ],
+                             kwargs = {"onosStartTimeout":main.timeout} )
+            pool.append(t)
+            t.start()
+            main.threadID = main.threadID + 1
+        for t in pool:
+            t.join()
+            startCliResult = startCliResult and t.result
+        time.sleep( main.startUpSleep )
+
+    def CASE10( self, main ):
+        """
+            Setting up null-provider
+        """
+        import json
+        # Activate apps
+        main.step("Activating null-provider")
+        appStatus = utilities.retry( main.CLIs[0].activateApp,
+                                     main.FALSE,
+                                     ['org.onosproject.null'],
+                                     sleep=main.verifySleep,
+                                     attempts=main.verifyAttempts )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=appStatus,
+                                 onpass="Successfully activated null-provider",
+                                 onfail="Failed activate null-provider" )
+
+        # Setup the null-provider
+        main.step("Configuring null-provider")
+        cfgStatus = utilities.retry( main.ONOSbench.onosCfgSet,
+                                    main.FALSE,
+                                    [ main.ONOSip[0],
+                                      'org.onosproject.provider.nil.NullProviders', 'deviceCount 8'],
+                                    sleep=main.verifySleep,
+                                    attempts = main.verifyAttempts )
+        cfgStatus = cfgStatus and utilities.retry( main.ONOSbench.onosCfgSet,
+                                                   main.FALSE,
+                                                   [ main.ONOSip[0],
+                                                     'org.onosproject.provider.nil.NullProviders', 'topoShape reroute'],
+                                                   sleep=main.verifySleep,
+                                                   attempts = main.verifyAttempts )
+
+        cfgStatus = cfgStatus and utilities.retry( main.ONOSbench.onosCfgSet,
+                                                   main.FALSE,
+                                                   [ main.ONOSip[0],
+                                                     'org.onosproject.provider.nil.NullProviders', 'enabled true'],
+                                                   sleep=main.verifySleep,
+                                                   attempts = main.verifyAttempts )
+
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=cfgStatus,
+                                 onpass="Successfully configured null-provider",
+                                 onfail="Failed to configure null-provider" )
+
+        # give onos some time to settle
+        time.sleep(main.startUpSleep)
+
+        main.log.info("Setting default flows to zero")
+        main.defaultFlows = 0
+
+        main.step("Check status of null-provider setup")
+        caseResult = appStatus and cfgStatus
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=caseResult,
+                                 onpass="Setting up null-provider was successfull",
+                                 onfail="Failed to setup null-provider" )
+
+        # This tells the following cases if we are using the null-provider or ovs
+        main.switchType = "null:"
+
+        # If the null-provider setup was unsuccessfull, then there is no point to
+        # run the subsequent cases
+
+        time.sleep(main.startUpSleep)
+        main.step( "Balancing Masters" )
+
+        stepResult = main.FALSE
+        stepResult = utilities.retry( main.CLIs[0].balanceMasters,
+                                      main.FALSE,
+                                      [],
+                                      sleep=3,
+                                      attempts=3 )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Balance masters was successfull",
+                                 onfail="Failed to balance masters")
+
+        time.sleep( 5 )
+        if not caseResult:
+            main.setupSkipped = True
+
+    def CASE11( self, main):
+        '''
+            Setting up mininet
+        '''
+        import json
+        import time
+
+        time.sleep(main.startUpSleep)
+
+        main.step("Activating openflow")
+        appStatus = utilities.retry( main.ONOSrest1.activateApp,
+                                     main.FALSE,
+                                     ['org.onosproject.openflow'],
+                                     sleep=3,
+                                     attempts=3 )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=appStatus,
+                                 onpass="Successfully activated openflow",
+                                 onfail="Failed activate openflow" )
+
+        time.sleep(main.startUpSleep)
+        main.step('Starting mininet topology')
+        mnStatus = main.Mininet1.startNet(topoFile='~/mininet/custom/rerouteTopo.py')
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=mnStatus,
+                                 onpass="Successfully started Mininet",
+                                 onfail="Failed to activate Mininet" )
+
+        main.step("Assinging masters to switches")
+        switches = main.Mininet1.getSwitches()
+        swStatus = main.Mininet1.assignSwController( sw=switches.keys(), ip=main.ONOSip )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=swStatus,
+                                 onpass="Successfully assigned switches to masters",
+                                 onfail="Failed assign switches to masters" )
+
+        time.sleep(main.startUpSleep)
+
+        main.log.info("Getting default flows")
+        jsonSum = json.loads(main.CLIs[0].summary())
+        main.defaultFlows = jsonSum["flows"]
+
+        main.step("Check status of Mininet setup")
+        caseResult = appStatus and mnStatus and swStatus
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=caseResult,
+                                 onpass="Successfully setup Mininet",
+                                 onfail="Failed setup Mininet" )
+
+        # This tells the following cases if we are using the null-provider or ovs
+        main.switchType = "of:"
+
+        time.sleep(main.startUpSleep)
+        main.step( "Balancing Masters" )
+
+        stepResult = main.FALSE
+        stepResult = utilities.retry( main.CLIs[0].balanceMasters,
+                                      main.FALSE,
+                                      [],
+                                      sleep=3,
+                                      attempts=3 )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Balance masters was successfull",
+                                 onfail="Failed to balance masters")
+
+        time.sleep(5)
+        if not caseResult:
+            main.setupSkipped = True
+
+
+
+    def CASE20( self, main ):
+        if main.reroute:
+            main.minIntents = int(main.params['NULL']['REROUTE']['min_intents'])
+            main.maxIntents = int(main.params['NULL']['REROUTE']['max_intents'])
+            main.checkInterval = int(main.params['NULL']['REROUTE']['check_interval'])
+            main.batchSize = int(main.params['NULL']['REROUTE']['batch_size'])
+        else:
+            main.minIntents = int(main.params['NULL']['PUSH']['min_intents'])
+            main.maxIntents = int(main.params['NULL']['PUSH']['max_intents'])
+            main.checkInterval = int(main.params['NULL']['PUSH']['check_interval'])
+            main.batchSize = int(main.params['NULL']['PUSH']['batch_size'])
+
+        # check if the case needs to be skipped
+        if main.setupSkipped:
+            main.setupSkipped = False
+            main.skipCase()
+
+        # the index where the next intents will be installed
+        offfset = 0
+        # keeps track of how many intents have been installed
+        currIntents = 0
+        # keeps track of how many flows have been installed, set to 0 at start
+        currFlows = 0
+        # limit for the number of intents that can be installed
+        limit = main.maxIntents / main.batchSize
+        # total intents installed
+        totalIntents = 0
+
+        intentsState = None
+
+        offtmp = 0
+        main.step( "Pushing intents" )
+        stepResult = main.TRUE
+        # temp variable to contain the number of flows
+        flowsNum = 0
+
+        for i in range(limit):
+
+            # Threads pool
+            pool = []
+
+            for j in range( int( main.numCtrls) ):
+                if main.numCtrls > 1:
+                    time.sleep( 1 )
+                offtmp = offfset + main.maxIntents * j
+                # Push intents by using threads
+                t = main.Thread( target=main.CLIs[j].pushTestIntents,
+                                 threadID=main.threadID,
+                                 name="Push-Test-Intents",
+                                 args=[ main.switchType + main.ingress,
+                                        main.switchType + main.egress,
+                                        main.batchSize ],
+                                 kwargs={ "offset": offtmp,
+                                          "options": "-i",
+                                          "timeout": main.timeout,
+                                          "background":False } )
+                pool.append(t)
+                t.start()
+                main.threadID = main.threadID + 1
+            for t in pool:
+                t.join()
+                stepResult = stepResult and t.result
+            offfset = offfset + main.batchSize
+
+            totalIntents = main.batchSize * main.numCtrls + totalIntents
+            if totalIntents >= main.minIntents and totalIntents % main.checkInterval == 0:
+                # if reach to minimum number and check interval, verify Intetns and flows
+                time.sleep( main.verifySleep * main.numCtrls )
+
+                main.log.info("Verify Intents states")
+                # k is a control variable for verify retry attempts
+                k = 1
+                intentVerify = main.FALSE
+
+                while k <= main.verifyAttempts:
+                    # while loop for check intents by using REST api
+                    time.sleep(5)
+                    temp = 0
+                    intentsState = json.loads( main.ONOSrest1.intents() )
+                    for f in intentsState:
+                        # get INSTALLED intents number
+                        if f.get("state") == "INSTALLED":
+                            temp = temp + 1
+
+                    main.log.info("Total Intents: {} INSTALLED: {}".format(totalIntents, temp))
+                    if totalIntents == temp:
+                        intentVerify = main.TRUE
+                        break
+                    intentVerify = main.FALSE
+                    k = k+1
+                if not intentVerify:
+                    # If some intents are not installed, grep the previous flows list, and finished this test case
+                    main.log.warn( "Some intens did not install" )
+                    # We don't want to check flows if intents not installed, because onos will drop flows
+                    if currFlows == 0:
+                    # If currFlows equal 0, which means we failed to install intents at first, or we didn't get
+                    # the correct number, so we need get flows here.
+                        flowsState = json.loads( main.ONOSrest1.flows() )
+                    break
+
+                main.log.info("Verify Flows states")
+                k = 1
+                flowsVerify = main.TRUE
+                while k <= main.verifyAttempts:
+                    # while loop for check flows by using REST api
+                    time.sleep(3)
+                    temp = 0
+                    flowsStateCount = []
+                    flowsState = json.loads( main.ONOSrest1.flows() )
+                    main.log.info("Total flows now: {}".format(len(flowsState)))
+                    if ( flowsNum < len(flowsState) ):
+                        flowsNum = len(flowsState)
+                    print(flowsNum)
+                    for f in flowsState:
+                        # get PENDING_ADD flows
+                        if f.get("state") == "PENDING_ADD":
+                            temp = temp + 1
+
+                    flowsStateCount.append(temp)
+                    temp = 0
+
+                    for f in flowsState:
+                        # get PENDING_REMOVE flows
+                        if f.get("state") == "PENDING_REMOVE":
+                            temp = temp + 1
+
+                    flowsStateCount.append(temp)
+                    temp = 0
+
+                    for f in flowsState:
+                        # get REMOVED flows
+                        if f.get("state") == "REMOVED":
+                            temp = temp + 1
+
+                    flowsStateCount.append(temp)
+                    temp = 0
+
+                    for f in flowsState:
+                        # get FAILED flwos
+                        if f.get("state") == "FAILED":
+                            temp = temp + 1
+
+                    flowsStateCount.append(temp)
+                    temp = 0
+                    k = k + 1
+                    for c in flowsStateCount:
+                        if int(c) > 0:
+                            flowsVerify = main.FALSE
+
+                    main.log.info( "Check flows States:" )
+                    main.log.info( "PENDING_ADD: {}".format( flowsStateCount[0]) )
+                    main.log.info( "PENDING_REMOVE: {}".format( flowsStateCount[1]) )
+                    main.log.info( "REMOVED: {}".format( flowsStateCount[2]) )
+                    main.log.info( "FAILED: {}".format( flowsStateCount[3]) )
+
+                    if flowsVerify == main.TRUE:
+                        break
+
+        del main.scale[0]
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = intentVerify,
+                                 onpass = "Successfully pushed and verified intents",
+                                 onfail = "Failed to push and verify intents" )
+
+        # we need the total intents before crash
+        totalIntents = len(intentsState)
+        totalFlows = flowsNum
+
+        main.log.info( "Total Intents Installed before crash: {}".format( totalIntents ) )
+        main.log.info( "Total Flows ADDED before crash: {}".format( totalFlows ) )
+
+        main.step('clean up Mininet')
+        main.Mininet1.stopNet()
+
+        main.log.info("Writing results to DS file")
+        with open(main.dbFileName, "a") as dbFile:
+            # Scale number
+            temp = str(main.numCtrls)
+            temp += ",'" + "baremetal1" + "'"
+            # how many intents we installed before crash
+            temp += "," + str(totalIntents)
+            # how many flows we installed before crash
+            temp += "," + str(totalFlows)
+            # other columns in database, but we didn't use in this test
+            temp += "," + "0,0,0,0,0,0"
+            temp += "\n"
+            dbFile.write( temp )
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.topo b/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.topo
new file mode 100755
index 0000000..a1ec149
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.topo
@@ -0,0 +1,101 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+                <home>~/onos</home>
+                <nodes>7</nodes> 
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOSrest1>
+            <host>OC1</host>
+            <port>8181</port>
+            <user>onos</user>
+            <password>rocks</password>
+            <type>OnosRestDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOSrest1>
+        <ONOScli1>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli1>
+
+        <ONOScli2>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli2>
+
+        <ONOScli3>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli3>
+
+        <ONOScli4>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli4>
+
+        <ONOScli5>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli5>
+
+        <ONOScli6>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli6>
+
+        <ONOScli7>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>8</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli7>
+
+        <Mininet1>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>MininetCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </Mininet1>
+
+    </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntents/__init__.py b/TestON/tests/SCPF/SCPFscalingMaxIntents/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscalingMaxIntents/__init__.py
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/Dependency/rerouteTopo.py b/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/Dependency/rerouteTopo.py
new file mode 100755
index 0000000..774f12f
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/Dependency/rerouteTopo.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+
+"""
+Custom topology for Mininet
+"""
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import Host, RemoteController
+from mininet.node import Node
+from mininet.link import TCLink
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+from mininet.util import dumpNodeConnections
+from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+
+class MyTopo( Topo ):
+
+    def __init__( self ):
+        # Initialize topology
+        Topo.__init__( self )
+
+        host1 = self.addHost('h1', ip='10.1.0.1/24')
+        host2 = self.addHost('h2', ip='10.1.0.2/24')
+        host3 = self.addHost('h3', ip='10.1.0.3/24')
+        host4 = self.addHost('h4', ip='10.1.0.4/24')
+        host5 = self.addHost('h5', ip='10.1.0.5/24')
+        host6 = self.addHost('h6', ip='10.1.0.6/24')
+        host7 = self.addHost('h7', ip='10.1.0.7/24')
+
+        s1 = self.addSwitch( 's1' )
+        s2 = self.addSwitch( 's2' )
+        s3 = self.addSwitch( 's3' )
+        s4 = self.addSwitch( 's4' )
+        s5 = self.addSwitch( 's5' )
+        s6 = self.addSwitch( 's6' )
+        s7 = self.addSwitch( 's7' )
+        s8 = self.addSwitch( 's8' )
+
+
+        self.addLink(s1, host1)
+        self.addLink(s2, host2)
+        self.addLink(s3, host3)
+        self.addLink(s4, host4)
+        self.addLink(s5, host5)
+        self.addLink(s6, host6)
+        self.addLink(s7, host7)
+
+
+
+        self.addLink(s1,s2)
+        self.addLink(s2,s3)
+        self.addLink(s3,s4)
+        self.addLink(s4,s5)
+        self.addLink(s5,s6)
+        self.addLink(s6,s7)
+        self.addLink(s4,s8)
+        self.addLink(s8,s5)
+
+        topos = { 'mytopo': ( lambda: MyTopo() ) }
+
+# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS
+
+def setupNetwork():
+    "Create network"
+    topo = MyTopo()
+    network = Mininet(topo=topo, autoSetMacs=True, controller=None)
+    network.start()
+    CLI( network )
+    network.stop()
+
+if __name__ == '__main__':
+    setLogLevel('info')
+    #setLogLevel('debug')
+    setupNetwork()
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/Dependency/startUp.py b/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/Dependency/startUp.py
new file mode 100644
index 0000000..bf2a2b6
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/Dependency/startUp.py
@@ -0,0 +1,38 @@
+"""
+    This wrapper function is use for starting up onos instance
+"""
+
+import time
+import os
+import json
+
+def onosBuild( main, gitBranch ):
+    """
+        This includes pulling ONOS and building it using maven install
+    """
+
+    buildResult = main.FALSE
+
+    # Git checkout a branch of ONOS
+    checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
+    # Does the git pull on the branch that was checked out
+    if not checkOutResult:
+        main.log.warn( "Failed to checked out " + gitBranch +
+                                           " branch")
+    else:
+        main.log.info( "Successfully checked out " + gitBranch +
+                                           " branch")
+    gitPullResult = main.ONOSbench.gitPull()
+    if gitPullResult == main.ERROR:
+        main.log.error( "Error pulling git branch" )
+    else:
+        main.log.info( "Successfully pulled " + gitBranch + " branch" )
+
+    # Maven clean install
+    buildResult = main.ONOSbench.cleanInstall()
+
+    return buildResult
+
+
+
+
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/README b/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/README
new file mode 100644
index 0000000..0c16859
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/README
@@ -0,0 +1,11 @@
+Summary:
+        This is a performance test suit, designed to test the upper limits
+        of onos and ovsdb with respect to installing intents.
+        In this test, CASE10 set up null provoder, CASE 11 set up ovs. Start from
+        1 node, and scale to 7 nodes.
+        We push intents to every node by using Thread, and when the intents number
+        reach to the minimun number, we will verify intents and flows. If intents are
+        not installed correctly, test will stop pushing and finish this case.
+NOTE:
+        This test is largely based on the hardware used to run onos and mininet.
+        Therefore, results will very test station to test station.
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.params b/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.params
new file mode 100644
index 0000000..ed0badf
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.params
@@ -0,0 +1,99 @@
+<PARAMS>
+
+    # 0-init
+    # 1-setup
+    # 2-Install
+    # 10-null provider setup
+    # 20-pushing intents, and rerouting intents if reroute is true
+    # 0,1,2,10,20,1,2,10,20,1,2,10,20
+   <testcases>0,1,2,11,20,1,2,11,20,1,2,11,20,1,2,11,20</testcases>
+
+    <reroute>False</reroute>
+
+    <SCALE>1,3,5,7</SCALE>
+
+    <DEPENDENCY>
+        <path>/tests/SCPFscalingMaxIntents/dependencies/</path>
+        <wrapper1>startUp</wrapper1>
+        <topology>rerouteTopo.py</topology>
+    </DEPENDENCY>
+
+    <ENV>
+        <cellName>productionCell</cellName>
+        <cellApps>drivers</cellApps>
+    </ENV>
+
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
+
+    <CTRL>
+        <port>6653</port>
+    </CTRL>
+
+    <SLEEP>
+        <startup>10</startup>
+        <install>10</install>
+        <verify>15</verify>
+        <reroute>3</reroute>
+        # timeout for pexpect
+        <timeout>300</timeout>
+    </SLEEP>
+
+    <ATTEMPTS>
+        <verify>3</verify>
+        <push>3</push>
+    </ATTEMPTS>
+
+    <DATABASE>
+        <file>/tmp/ScalingMaxIntentDBWFO</file>
+        <nic>1gig</nic>
+        <node>baremetal</node>
+    </DATABASE>
+
+    <LINK>
+        <ingress>0000000000000001/5</ingress>
+        <egress>0000000000000007/5</egress>
+    </LINK>
+
+    # CASE10
+    <NULL>
+        # CASE20
+        <PUSH>
+            <batch_size>100</batch_size>
+            <min_intents>100</min_intents>
+            <max_intents>100000</max_intents>
+            <check_interval>100</check_interval>
+        </PUSH>
+
+        # if reroute is true
+        <REROUTE>
+            <batch_size>1000</batch_size>
+            <min_intents>10000</min_intents>
+            <max_intents>1000000</max_intents>
+            <check_interval>100000</check_interval>
+        </REROUTE>
+    </NULL>
+
+    # CASE11
+    <OVS>
+        # CASE20
+        <PUSH>
+            <batch_size>1000</batch_size>
+            <min_intents>10000</min_intents>
+            <max_intents>500000</max_intents>
+            <check_interval>10000</check_interval>
+        </PUSH>
+
+        # if reroute is true
+        <REROUTE>
+            <batch_size>1000</batch_size>
+            <min_intents>10000</min_intents>
+            <max_intents>500000</max_intents>
+            <check_interval>10000</check_interval>
+        </REROUTE>
+    </OVS>
+
+
+</PARAMS>
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.py b/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.py
new file mode 100644
index 0000000..e405fd3
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.py
@@ -0,0 +1,561 @@
+import sys
+import json
+import time
+import os
+'''
+SCPFscalingMaxIntentsWithFlowObj
+Push test Intents to onos
+CASE10: set up Null Provider
+CASE11: set up Open Flows
+Scale up when reach the Limited
+Start from 1 nodes, 8 devices. Then Scale up to 3,5,7 nodes
+Recommand batch size: 100, check interval: 100
+'''
+class SCPFscalingMaxIntentsWithFlowObj:
+    def __init__( self ):
+        self.default = ''
+
+    def CASE0( self, main):
+        import sys
+        import json
+        import time
+        import os
+        import imp
+
+        main.case( "Constructing test variables and building ONOS package" )
+        main.step( "Constructing test variables" )
+        stepResult = main.FALSE
+
+        # Test variables
+        main.testOnDirectory = os.path.dirname( os.getcwd ( ) )
+        main.dependencyPath = main.testOnDirectory + \
+                main.params['DEPENDENCY']['path']
+        main.cellName = main.params[ 'ENV' ][ 'cellName' ]
+        main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+        main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
+        main.scale = ( main.params[ 'SCALE' ] ).split( "," )
+        main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
+        main.timeout = int(main.params['SLEEP']['timeout'])
+        main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+        main.installSleep = int( main.params[ 'SLEEP' ][ 'install' ] )
+        main.verifySleep = int( main.params[ 'SLEEP' ][ 'verify' ] )
+        main.rerouteSleep = int ( main.params['SLEEP']['reroute'] )
+        main.verifyAttempts = int( main.params['ATTEMPTS']['verify'] )
+        main.ingress = main.params['LINK']['ingress']
+        main.egress = main.params['LINK']['egress']
+        main.dbFileName = main.params['DATABASE']['file']
+        main.cellData = {} # for creating cell file
+        main.reroute = main.params['reroute']
+        main.threadID = 0
+
+        if main.reroute == "True":
+            main.reroute = True
+        else:
+            main.reroute = False
+
+        main.CLIs = []
+        main.ONOSip = []
+        main.maxNumBatch = 0
+        main.ONOSip = main.ONOSbench.getOnosIps()
+        main.log.info(main.ONOSip)
+        main.setupSkipped = False
+
+        wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
+        gitBranch = main.params[ 'GIT' ][ 'branch' ]
+        gitPull = main.params[ 'GIT' ][ 'pull' ]
+        nic = main.params['DATABASE']['nic']
+        node = main.params['DATABASE']['node']
+        nic = main.params['DATABASE']['nic']
+        node = main.params['DATABASE']['node']
+        stepResult = main.TRUE
+
+        main.log.info("Cresting DB file")
+        with open(main.dbFileName, "w+") as dbFile:
+            dbFile.write("")
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="environment set up successfull",
+                                 onfail="environment set up Failed" )
+
+    def CASE1( self ):
+        # main.scale[ 0 ] determines the current number of ONOS controller
+        main.CLIs = []
+        main.numCtrls = int( main.scale[ 0 ] )
+        main.log.info( "Creating list of ONOS cli handles" )
+        for i in range(main.numCtrls):
+            main.CLIs.append( getattr( main, 'ONOScli%s' % (i+1) ) )
+
+        main.log.info(main.CLIs)
+        if not main.CLIs:
+            main.log.error( "Failed to create the list of ONOS cli handles" )
+            main.cleanup()
+            main.exit()
+
+        main.log.info( "Loading wrapper files" )
+        main.startUp = imp.load_source( wrapperFile1,
+                                        main.dependencyPath +
+                                        wrapperFile1 +
+                                        ".py" )
+
+        copyResult = main.ONOSbench.copyMininetFile( main.topology,
+                                                     main.dependencyPath,
+                                                     main.Mininet1.user_name,
+                                                     main.Mininet1.ip_address )
+
+        commit = main.ONOSbench.getVersion(report=True)
+        commit = commit.split(" ")[1]
+
+        if gitPull == 'True':
+            if not main.startUp.onosBuild( main, gitBranch ):
+                main.log.error( "Failed to build ONOS" )
+                main.cleanup()
+                main.exit()
+        else:
+            main.log.warn( "Did not pull new code so skipping mvn " +
+                           "clean install" )
+        with open(main.dbFileName, "a") as dbFile:
+            temp = "'" + commit + "',"
+            temp += "'" + nic + "',"
+            dbFile.write(temp)
+
+    def CASE2( self, main ):
+        """
+        - Uninstall ONOS cluster
+        - Verify ONOS start up
+        - Install ONOS cluster
+        - Connect to cli
+        """
+        main.log.info( "Starting up %s node(s) ONOS cluster" % main.numCtrls)
+        main.log.info( "Safety check, killing all ONOS processes" +
+                       " before initiating environment setup" )
+
+        for i in range( main.numCtrls ):
+            main.ONOSbench.onosDie( main.ONOSip[ i ] )
+
+        main.log.info( "NODE COUNT = %s" % main.numCtrls)
+
+        tempOnosIp = []
+        for i in range( main.numCtrls ):
+            tempOnosIp.append( main.ONOSip[i] )
+
+        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
+                                       "temp",
+                                       main.Mininet1.ip_address,
+                                       main.apps,
+                                       tempOnosIp )
+
+        main.step( "Apply cell to environment" )
+        cellResult = main.ONOSbench.setCell( "temp" )
+        verifyResult = main.ONOSbench.verifyCell()
+        stepResult = cellResult and verifyResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully applied cell to " + \
+                                        "environment",
+                                 onfail="Failed to apply cell to environment " )
+
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.onosPackage()
+        stepResult = packageResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully created ONOS package",
+                                 onfail="Failed to create ONOS package" )
+
+        main.step( "Uninstall ONOS package on all Nodes" )
+        uninstallResult = main.TRUE
+        for i in range( int( main.numCtrls ) ):
+            main.log.info( "Uninstalling package on ONOS Node IP: " + main.ONOSip[i] )
+            u_result = main.ONOSbench.onosUninstall( main.ONOSip[i] )
+            utilities.assert_equals( expect=main.TRUE, actual=u_result,
+                                     onpass="Test step PASS",
+                                     onfail="Test step FAIL" )
+            uninstallResult = ( uninstallResult and u_result )
+
+        main.step( "Install ONOS package on all Nodes" )
+        installResult = main.TRUE
+        for i in range( int( main.numCtrls ) ):
+            main.log.info( "Installing package on ONOS Node IP: " + main.ONOSip[i] )
+            i_result = main.ONOSbench.onosInstall( node=main.ONOSip[i] )
+            utilities.assert_equals( expect=main.TRUE, actual=i_result,
+                                     onpass="Test step PASS",
+                                     onfail="Test step FAIL" )
+            installResult = installResult and i_result
+
+        main.step( "Verify ONOS nodes UP status" )
+        statusResult = main.TRUE
+        for i in range( int( main.numCtrls ) ):
+            main.log.info( "ONOS Node " + main.ONOSip[i] + " status:" )
+            onos_status = main.ONOSbench.onosStatus( node=main.ONOSip[i] )
+            utilities.assert_equals( expect=main.TRUE, actual=onos_status,
+                                     onpass="Test step PASS",
+                                     onfail="Test step FAIL" )
+            statusResult = ( statusResult and onos_status )
+
+        main.step( "Start ONOS CLI on all nodes" )
+        cliResult = main.TRUE
+        main.log.step(" Start ONOS cli using thread ")
+        startCliResult  = main.TRUE
+        pool = []
+
+        for i in range( int( main.numCtrls) ):
+            t = main.Thread( target=main.CLIs[i].startOnosCli,
+                             threadID=main.threadID,
+                             name="startOnosCli",
+                             args=[ main.ONOSip[i] ],
+                             kwargs = {"onosStartTimeout":main.timeout} )
+            pool.append(t)
+            t.start()
+            main.threadID = main.threadID + 1
+        for t in pool:
+            t.join()
+            startCliResult = startCliResult and t.result
+        time.sleep( main.startUpSleep )
+
+    def CASE10( self, main ):
+        """
+            Setting up null-provider
+        """
+        import json
+        # Activate apps
+        main.step("Activating null-provider")
+        appStatus = utilities.retry( main.CLIs[0].activateApp,
+                                     main.FALSE,
+                                     ['org.onosproject.null'],
+                                     sleep=main.verifySleep,
+                                     attempts=main.verifyAttempts )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=appStatus,
+                                 onpass="Successfully activated null-provider",
+                                 onfail="Failed activate null-provider" )
+
+        # Setup the null-provider
+        main.step("Configuring null-provider")
+        cfgStatus = utilities.retry( main.ONOSbench.onosCfgSet,
+                                    main.FALSE,
+                                    [ main.ONOSip[0],
+                                      'org.onosproject.provider.nil.NullProviders', 'deviceCount 8'],
+                                    sleep=main.verifySleep,
+                                    attempts = main.verifyAttempts )
+        cfgStatus = cfgStatus and utilities.retry( main.ONOSbench.onosCfgSet,
+                                                   main.FALSE,
+                                                   [ main.ONOSip[0],
+                                                     'org.onosproject.provider.nil.NullProviders', 'topoShape reroute'],
+                                                   sleep=main.verifySleep,
+                                                   attempts = main.verifyAttempts )
+
+        cfgStatus = cfgStatus and utilities.retry( main.ONOSbench.onosCfgSet,
+                                                   main.FALSE,
+                                                   [ main.ONOSip[0],
+                                                     'org.onosproject.provider.nil.NullProviders', 'enabled true'],
+                                                   sleep=main.verifySleep,
+                                                   attempts = main.verifyAttempts )
+
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=cfgStatus,
+                                 onpass="Successfully configured null-provider",
+                                 onfail="Failed to configure null-provider" )
+
+        # give onos some time to settle
+        time.sleep(main.startUpSleep)
+
+        main.log.info("Setting default flows to zero")
+        main.defaultFlows = 0
+
+        main.step("Check status of null-provider setup")
+        caseResult = appStatus and cfgStatus
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=caseResult,
+                                 onpass="Setting up null-provider was successfull",
+                                 onfail="Failed to setup null-provider" )
+
+        # This tells the following cases if we are using the null-provider or ovs
+        main.switchType = "null:"
+
+        # If the null-provider setup was unsuccessfull, then there is no point to
+        # run the subsequent cases
+
+        time.sleep(main.startUpSleep)
+        main.step( "Balancing Masters" )
+
+        stepResult = main.FALSE
+        stepResult = utilities.retry( main.CLIs[0].balanceMasters,
+                                      main.FALSE,
+                                      [],
+                                      sleep=3,
+                                      attempts=3 )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Balance masters was successfull",
+                                 onfail="Failed to balance masters")
+
+        time.sleep( 5 )
+        if not caseResult:
+            main.setupSkipped = True
+
+    def CASE11( self, main):
+        '''
+            Setting up mininet
+        '''
+        import json
+        import time
+
+        time.sleep(main.startUpSleep)
+
+        main.step("Activating openflow")
+        appStatus = utilities.retry( main.ONOSrest1.activateApp,
+                                     main.FALSE,
+                                     ['org.onosproject.openflow'],
+                                     sleep=3,
+                                     attempts=3 )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=appStatus,
+                                 onpass="Successfully activated openflow",
+                                 onfail="Failed activate openflow" )
+
+        time.sleep(main.startUpSleep)
+        main.log.info("Set Intent Compiler use Flow Object")
+        main.CLIs[0].setCfg( "org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator", "useFlowObjectives", "true" )
+
+        main.step('Starting mininet topology')
+        mnStatus = main.Mininet1.startNet(topoFile='~/mininet/custom/rerouteTopo.py')
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=mnStatus,
+                                 onpass="Successfully started Mininet",
+                                 onfail="Failed to activate Mininet" )
+
+        main.step("Assinging masters to switches")
+        switches = main.Mininet1.getSwitches()
+        swStatus = main.Mininet1.assignSwController( sw=switches.keys(), ip=main.ONOSip )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=swStatus,
+                                 onpass="Successfully assigned switches to masters",
+                                 onfail="Failed assign switches to masters" )
+
+        time.sleep(main.startUpSleep)
+
+        main.log.info("Getting default flows")
+        jsonSum = json.loads(main.CLIs[0].summary())
+        main.defaultFlows = jsonSum["flows"]
+
+        main.step("Check status of Mininet setup")
+        caseResult = appStatus and mnStatus and swStatus
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=caseResult,
+                                 onpass="Successfully setup Mininet",
+                                 onfail="Failed setup Mininet" )
+
+        # This tells the following cases if we are using the null-provider or ovs
+        main.switchType = "of:"
+
+        time.sleep(main.startUpSleep)
+        main.step( "Balancing Masters" )
+
+        stepResult = main.FALSE
+        stepResult = utilities.retry( main.CLIs[0].balanceMasters,
+                                      main.FALSE,
+                                      [],
+                                      sleep=3,
+                                      attempts=3 )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Balance masters was successfull",
+                                 onfail="Failed to balance masters")
+
+        time.sleep(5)
+        if not caseResult:
+            main.setupSkipped = True
+
+
+
+    def CASE20( self, main ):
+        if main.reroute:
+            main.minIntents = int(main.params['NULL']['REROUTE']['min_intents'])
+            main.maxIntents = int(main.params['NULL']['REROUTE']['max_intents'])
+            main.checkInterval = int(main.params['NULL']['REROUTE']['check_interval'])
+            main.batchSize = int(main.params['NULL']['REROUTE']['batch_size'])
+        else:
+            main.minIntents = int(main.params['NULL']['PUSH']['min_intents'])
+            main.maxIntents = int(main.params['NULL']['PUSH']['max_intents'])
+            main.checkInterval = int(main.params['NULL']['PUSH']['check_interval'])
+            main.batchSize = int(main.params['NULL']['PUSH']['batch_size'])
+
+        # check if the case needs to be skipped
+        if main.setupSkipped:
+            main.setupSkipped = False
+            main.skipCase()
+
+        # the index where the next intents will be installed
+        offfset = 0
+        # keeps track of how many intents have been installed
+        currIntents = 0
+        # keeps track of how many flows have been installed, set to 0 at start
+        currFlows = 0
+        # limit for the number of intents that can be installed
+        limit = main.maxIntents / main.batchSize
+        # total intents installed
+        totalIntents = 0
+
+        intentsState = None
+
+        offtmp = 0
+        main.step( "Pushing intents" )
+        stepResult = main.TRUE
+        # temp variable to contain the number of flows
+        flowsNum = 0
+
+        for i in range(limit):
+
+            # Threads pool
+            pool = []
+
+            for j in range( int( main.numCtrls) ):
+                if main.numCtrls > 1:
+                    time.sleep( 1 )
+                offtmp = offfset + main.maxIntents * j
+                # Push intents by using threads
+                t = main.Thread( target=main.CLIs[j].pushTestIntents,
+                                 threadID=main.threadID,
+                                 name="Push-Test-Intents",
+                                 args=[ main.switchType + main.ingress,
+                                        main.switchType + main.egress,
+                                        main.batchSize ],
+                                 kwargs={ "offset": offtmp,
+                                          "options": "-i",
+                                          "timeout": main.timeout,
+                                          "background":False } )
+                pool.append(t)
+                t.start()
+                main.threadID = main.threadID + 1
+            for t in pool:
+                t.join()
+                stepResult = stepResult and t.result
+            offfset = offfset + main.batchSize
+
+            totalIntents = main.batchSize * main.numCtrls + totalIntents
+            if totalIntents >= main.minIntents and totalIntents % main.checkInterval == 0:
+                # if reach to minimum number and check interval, verify Intetns and flows
+                time.sleep( main.verifySleep * main.numCtrls )
+
+                main.log.info("Verify Intents states")
+                # k is a control variable for verify retry attempts
+                k = 1
+                intentVerify = main.FALSE
+
+                while k <= main.verifyAttempts:
+                    # while loop for check intents by using REST api
+                    time.sleep(5)
+                    temp = 0
+                    intentsState = json.loads( main.ONOSrest1.intents() )
+                    for f in intentsState:
+                        # get INSTALLED intents number
+                        if f.get("state") == "INSTALLED":
+                            temp = temp + 1
+
+                    main.log.info("Total Intents: {} INSTALLED: {}".format(totalIntents, temp))
+                    if totalIntents == temp:
+                        intentVerify = main.TRUE
+                        break
+                    intentVerify = main.FALSE
+                    k = k+1
+                if not intentVerify:
+                    # If some intents are not installed, grep the previous flows list, and finished this test case
+                    main.log.warn( "Some intens did not install" )
+                    # We don't want to check flows if intents not installed, because onos will drop flows
+                    if currFlows == 0:
+                    # If currFlows equal 0, which means we failed to install intents at first, or we didn't get
+                    # the correct number, so we need get flows here.
+                        flowsState = json.loads( main.ONOSrest1.flows() )
+                    break
+
+                main.log.info("Verify Flows states")
+                k = 1
+                flowsVerify = main.TRUE
+                while k <= main.verifyAttempts:
+                    # while loop for check flows by using REST api
+                    time.sleep(3)
+                    temp = 0
+                    flowsStateCount = []
+                    flowsState = json.loads( main.ONOSrest1.flows() )
+                    main.log.info("Total flows now: {}".format(len(flowsState)))
+                    if ( flowsNum < len(flowsState) ):
+                        flowsNum = len(flowsState)
+                    print(flowsNum)
+                    for f in flowsState:
+                        # get PENDING_ADD flows
+                        if f.get("state") == "PENDING_ADD":
+                            temp = temp + 1
+
+                    flowsStateCount.append(temp)
+                    temp = 0
+
+                    for f in flowsState:
+                        # get PENDING_REMOVE flows
+                        if f.get("state") == "PENDING_REMOVE":
+                            temp = temp + 1
+
+                    flowsStateCount.append(temp)
+                    temp = 0
+
+                    for f in flowsState:
+                        # get REMOVED flows
+                        if f.get("state") == "REMOVED":
+                            temp = temp + 1
+
+                    flowsStateCount.append(temp)
+                    temp = 0
+
+                    for f in flowsState:
+                        # get FAILED flwos
+                        if f.get("state") == "FAILED":
+                            temp = temp + 1
+
+                    flowsStateCount.append(temp)
+                    temp = 0
+                    k = k + 1
+                    for c in flowsStateCount:
+                        if int(c) > 0:
+                            flowsVerify = main.FALSE
+
+                    main.log.info( "Check flows States:" )
+                    main.log.info( "PENDING_ADD: {}".format( flowsStateCount[0]) )
+                    main.log.info( "PENDING_REMOVE: {}".format( flowsStateCount[1]) )
+                    main.log.info( "REMOVED: {}".format( flowsStateCount[2]) )
+                    main.log.info( "FAILED: {}".format( flowsStateCount[3]) )
+
+                    if flowsVerify == main.TRUE:
+                        break
+
+        del main.scale[0]
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = intentVerify,
+                                 onpass = "Successfully pushed and verified intents",
+                                 onfail = "Failed to push and verify intents" )
+
+        # we need the total intents before crash
+        totalIntents = len(intentsState)
+        totalFlows = flowsNum
+
+        main.log.info( "Total Intents Installed before crash: {}".format( totalIntents ) )
+        main.log.info( "Total Flows ADDED before crash: {}".format( totalFlows ) )
+
+        main.step('clean up Mininet')
+        main.Mininet1.stopNet()
+
+        main.log.info("Writing results to DS file")
+        with open(main.dbFileName, "a") as dbFile:
+            # Scale number
+            temp = str(main.numCtrls)
+            temp += ",'" + "baremetal1" + "'"
+            # how many intents we installed before crash
+            temp += "," + str(totalIntents)
+            # how many flows we installed before crash
+            temp += "," + str(totalFlows)
+            # other columns in database, but we didn't use in this test
+            temp += "," + "0,0,0,0,0,0"
+            temp += "\n"
+            dbFile.write( temp )
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.topo b/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.topo
new file mode 100755
index 0000000..a1ec149
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/SCPFscalingMaxIntentsWithFlowObj.topo
@@ -0,0 +1,101 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+                <home>~/onos</home>
+                <nodes>7</nodes> 
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOSrest1>
+            <host>OC1</host>
+            <port>8181</port>
+            <user>onos</user>
+            <password>rocks</password>
+            <type>OnosRestDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOSrest1>
+        <ONOScli1>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli1>
+
+        <ONOScli2>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli2>
+
+        <ONOScli3>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli3>
+
+        <ONOScli4>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli4>
+
+        <ONOScli5>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli5>
+
+        <ONOScli6>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli6>
+
+        <ONOScli7>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>8</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli7>
+
+        <Mininet1>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>MininetCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </Mininet1>
+
+    </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/__init__.py b/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFscalingMaxIntentsWithFlowObj/__init__.py
diff --git a/TestON/tests/SCPF/SCPFswitchLat/Dependency/topo-perf-1sw.py b/TestON/tests/SCPF/SCPFswitchLat/Dependency/topo-perf-1sw.py
new file mode 100644
index 0000000..fad98d2
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFswitchLat/Dependency/topo-perf-1sw.py
@@ -0,0 +1,13 @@
+'''
+Simple 1 switch topology for topologoy performance test
+'''
+
+from mininet.topo import Topo
+
+class MyTopo( Topo ):
+    def __init__(self):
+        Topo.__init__(self)
+
+        s3 = self.addSwitch( "s3", dpid="0000000000000001")
+
+topos = { 'mytopo': ( lambda: MyTopo() ) }
diff --git a/TestON/tests/SCPF/SCPFswitchLat/README b/TestON/tests/SCPF/SCPFswitchLat/README
new file mode 100644
index 0000000..dfc0f42
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFswitchLat/README
@@ -0,0 +1,31 @@
+SWITCH LATENCY
+
+Summary: This is a performance test suite to measure the time it takes ONOS
+        to recognize a switch going up and down.
+
+Pre-requisites: To run out-of-the box this test requires 7 NODES.
+    OC1->OC7 must be set before initiating the test. Passwordless login
+    must be set from TestStation "sdn" root user. The 7 NODES must have
+    their clocks synced to TestStation via ptpd and be accurate to the
+    millisecond. You will also need the Wireshark disector to see openflow packets.
+
+*** If you wish to run this test with less than 7 nodes the following
+    alterations must be made:
+
+NOTE: Only scale sizes 1,3,5 and 7 will be functional
+
+Modifying .params file:
+-- Remove any values in the comma separated list in the
+    <scale> tag that are above your desired cluster size.
+
+-- Remove one instance of “1,2” from the <testcases> tag for each
+    value you removed from <scale> (case 1 and 2 are each called once
+    for each scale value)
+
+-- Change the value in the <max> tag to your desired scale size (1,3,5)
+
+Modifying .topo file:
+-- Change the <ONOSbench/COMPONENTS/nodes> tag to your
+    desired scale size
+
+-- Remove all unneeded <ONOS#cli> tags and their contents
diff --git a/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.params b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.params
new file mode 100644
index 0000000..6035fba
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.params
@@ -0,0 +1,83 @@
+<PARAMS>
+    <testcases>1,2,1,2,1,2,1,2</testcases>
+
+    <SCALE>1,3,5,7</SCALE>
+    <max>7</max>
+
+    <ENV>
+        <cellName>topo_perf_test</cellName>
+        <cellApps>drivers,metrics,openflow</cellApps>
+    </ENV>
+
+    <GIT>
+        <autopull>off</autopull>
+        <checkout>master</checkout>
+    </GIT>
+
+    <CTRL>
+        <user>sdn</user>
+        <ip1>OC1</ip1>
+        <ip2>OC2</ip2>
+        <ip3>OC3</ip3>
+        <ip4>OC4</ip4>
+        <ip5>OC5</ip5>
+        <ip6>OC6</ip6>
+        <ip7>OC7</ip7>
+    </CTRL>
+
+    <MN>
+        <ip1>localhost</ip1>
+        <ip2>localhost</ip2>
+    </MN>
+
+    <BENCH>
+        <ip>localhost</ip>
+    </BENCH>
+
+    <TSHARK>
+        <ofpPortStatus>OF 1.3 146</ofpPortStatus>
+        <ofpRoleReply>OF 1.3 90 of_role_reply</ofpRoleReply>
+        <featureReply>OF 1.3 98 of_features_reply</featureReply>
+        <roleRequest>OF 1.3 90 of_role_request</roleRequest>
+        <tcpSynAck>TCP 74 openflow</tcpSynAck>
+        <finAckSequence>FIN</finAckSequence>
+    </TSHARK>
+
+    <TEST>
+        #'on' or 'off' debug mode.
+        #If on, logging will be more verbose and
+        #tshark pcap will be enabled
+        #pcap file located at /tmp/'capture_name'
+        <debugMode>off</debugMode>
+        <onosLogFile>/opt/onos/log/karaf*</onosLogFile>
+        <mci>off</mci>
+
+        <topoConfigFile>
+        single_topo_event_accumulator.cfg
+        </topoConfigFile>
+        <topoConfigName>
+        org.onlab.onos.net.topology.impl.DefaultTopologyProvider.cfg
+        </topoConfigName>
+
+        #Number of times to iterate each case
+        <numIter>25</numIter>
+        <numSwitch>2</numSwitch>
+        #Number of iterations to ignore initially
+        <iterIgnore>5</iterIgnore>
+
+        <singleSwThreshold>0,1000</singleSwThreshold>
+
+        <tabletFile>tablets_3node.json</tabletFile>
+   </TEST>
+
+    <DB>
+        <switchEventResultPath>/tmp/switchEventResultDb</switchEventResultPath>
+    </DB>
+
+    <JSON>
+        <deviceTimestamp>topologyDeviceEventTimestamp</deviceTimestamp>
+        <hostTimestamp>topologyHostEventTimestamp</hostTimestamp>
+        <linkTimestamp>topologyLinkEventTimestamp</linkTimestamp>
+        <graphTimestamp>topologyGraphEventTimestamp</graphTimestamp>
+    </JSON>
+</PARAMS>
diff --git a/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.py b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.py
new file mode 100644
index 0000000..7c12549
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.py
@@ -0,0 +1,863 @@
+# CASE1 starts number of nodes specified in param file
+#
+# cameron@onlab.us
+
+class SCPFswitchLat:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):
+        import sys
+        import re
+        import os
+        import time
+
+        global init
+        try:
+            if type(init) is not bool:
+                init = Fals
+        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' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip' ]
+        MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+        main.maxNodes = int(main.params[ 'max' ])
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        homeDir = os.path.expanduser('~')
+        topoCfgFile = main.params['TEST']['topoConfigFile']
+        topoCfgName = main.params['TEST']['topoConfigName']
+        switchEventResultPath = main.params['DB']['switchEventResultPath']
+        skipMvn = main.params ['TEST']['mci']
+        testONpath = re.sub( "(tests)$", "bin", main.testDir )  # TestON/bin
+        user = main.params[ 'CTRL' ][ 'user' ]
+
+        # -- INIT SECTION, ONLY RUNS ONCE -- #
+        if init == False:
+            init = True
+            global clusterCount             #number of nodes running
+            global scale
+            global commit
+            global timeToPost
+            global runNum
+            global jenkinsBuildNumber
+            global CLIs
+            CLIs = []
+            main.ONOSIp = []
+
+            for i in range( 1, 8 ):
+                CLIs.append( getattr( main, 'ONOS' + str( i ) + 'cli' ) )
+
+            timeToPost = time.strftime('%Y-%m-%d %H:%M:%S')
+            runNum = time.strftime('%d%H%M%S')
+
+            try:
+                jenkinsBuildNumber = str(os.environ['BUILD_NUMBER'])
+                main.log.report( 'Jenkins build number: ' + jenkinsBuildNumber )
+            except KeyError:
+                jenkinsBuildNumber = str(0)
+                main.log.info( 'Job is not run by jenkins. ' + 'Build number set to: ' + jenkinsBuildNumber)
+
+            clusterCount = 0
+            main.ONOSIp = main.ONOSbench.getOnosIps()
+
+            scale = (main.params[ 'SCALE' ]).split(",")
+            clusterCount = int(scale[0])
+
+            #mvn clean install, for debugging set param 'skipCleanInstall' to yes to speed up test
+            if skipMvn != "off":
+                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" )
+
+            main.log.step("Grabbing commit number")
+            commit = main.ONOSbench.getVersion()       ####
+            commit = (commit.split(" "))[1]
+
+            temp = testONpath.replace("bin","") + "tests/SCPFswitchLat/dependencies/"
+            main.ONOSbench.scp( main.Mininet1,
+                                temp + "topo-perf-1sw.py",
+                                main.Mininet1.home,
+                                direction="to" )
+            #main.ONOSbench.handle.expect(":~")
+
+            main.step('Clearing previous DB log file')
+            print switchEventResultPath
+            fSwitchLog = open(switchEventResultPath, "w+")
+            fSwitchLog.write("")
+            fSwitchLog.close()
+
+        # -- END OF INIT SECTION --#
+
+        main.log.step("Adjusting scale")
+        clusterCount = int(scale[0])
+        scale.remove(scale[0])
+
+        #kill off all onos processes
+        main.log.step("Safety check, killing all ONOS processes before initiating environment setup")
+        for node in range(main.maxNodes):
+            main.ONOSbench.onosDie(main.ONOSIp[node])
+
+        #Uninstall everywhere
+        main.log.step( "Cleaning Enviornment..." )
+        for i in range(main.maxNodes):
+            main.log.info(" Uninstalling ONOS " + str(i) )
+            main.ONOSbench.onosUninstall( main.ONOSIp[i] )
+        main.log.info("Sleep 10 second for uninstall to settle...")
+        time.sleep(10)
+        main.ONOSbench.handle.sendline(" ")
+        main.ONOSbench.handle.expect(":~")
+
+        #construct the cell file
+        main.log.info("Creating cell file")
+        cellIp = []
+        for node in range (clusterCount):
+            cellIp.append(main.ONOSIp[node])
+
+        main.ONOSbench.createCellFile(main.ONOSbench.ip_address, 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.step('Starting mininet topology ')
+        main.Mininet1.startNet()
+
+        main.log.report( "Initializeing " + str( clusterCount ) + " node cluster." )
+        for node in range(clusterCount):
+            main.log.info("Starting ONOS " + str(node) + " at IP: " + main.ONOSIp[node])
+            main.ONOSbench.onosInstall( node=main.ONOSIp[node])
+
+        for i in range(50):
+            time.sleep(15)
+            print "attempt " + str(i)
+            main.ONOSbench.handle.sendline("onos $OC1 summary")
+            main.ONOSbench.handle.expect(":~")
+            print main.ONOSbench.handle.before
+            if "nodes=" in main.ONOSbench.handle.before:
+                break
+
+        for node in range(clusterCount):
+            for i in range( 2 ):
+                isup = main.ONOSbench.isup( main.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")
+
+        #time.sleep(20)
+
+        main.step('Start onos cli')
+        for i in range(0,clusterCount):
+            cli1 = CLIs[i].startOnosCli(main.ONOSIp[i])
+
+        main.step( 'Configuring application parameters' )
+
+        configName = 'org.onosproject.net.topology.impl.DefaultTopologyProvider'
+        configParam = 'maxEvents 1'
+        main.ONOSbench.onosCfgSet( main.ONOSIp[0], configName, configParam )
+        configParam = 'maxBatchMs 0'
+        main.ONOSbench.onosCfgSet( main.ONOSIp[0], configName, configParam )
+        configParam = 'maxIdleMs 0'
+        main.ONOSbench.onosCfgSet( main.ONOSIp[0], configName, configParam )
+
+    def CASE2(self, main):
+        print "Cluster size: " + str(clusterCount)
+        """
+        Assign s3 to ONOSbench and measure latency
+
+        There are 4 levels of latency measurements to this test:
+        1 ) End-to-end measurement: Complete end-to-end measurement
+           from TCP ( SYN/ACK ) handshake to Graph change
+        2 ) OFP-to-graph measurement: 'ONOS processing' snippet of
+           measurement from OFP Vendor message to Graph change
+        3 ) OFP-to-device measurement: 'ONOS processing without
+           graph change' snippet of measurement from OFP vendor
+           message to Device change timestamp
+        4 ) T0-to-device measurement: Measurement that includes
+           the switch handshake to devices timestamp without
+           the graph view change. ( TCP handshake -> Device
+           change )
+        """
+        import time
+        import subprocess
+        import json
+        import requests
+        import os
+        import numpy
+
+        ONOSUser = main.params['CTRL']['user']
+        numIter = main.params['TEST']['numIter']
+        iterIgnore = int(main.params['TEST']['iterIgnore'])
+
+        deviceTimestampKey = main.params['JSON']['deviceTimestamp']
+        graphTimestampKey = main.params['JSON']['graphTimestamp']
+
+        debugMode = main.params['TEST']['debugMode']
+        onosLog = main.params['TEST']['onosLogFile']
+        resultPath = main.params['DB']['switchEventResultPath']
+        thresholdStr = main.params['TEST']['singleSwThreshold']
+        thresholdObj = thresholdStr.split(',')
+        thresholdMin = int(thresholdObj[0])
+        thresholdMax = int(thresholdObj[1])
+
+        # Look for 'role-request' messages,
+        # which replaces the 'vendor' messages previously seen
+        # on OVS 2.0.1
+        tsharkTcpString = main.params[ 'TSHARK' ][ 'tcpSynAck' ]
+        tsharkFeatureReply = main.params[ 'TSHARK' ][ 'featureReply' ]
+        tsharkRoleRequest = main.params[ 'TSHARK' ][ 'roleRequest' ]
+        tsharkOfString = main.params[ 'TSHARK' ][ 'ofpRoleReply' ]
+        tsharkFinAckSequence = main.params[ 'TSHARK' ][ 'finAckSequence' ]
+
+        tsharkOfOutput = '/tmp/tshark_of_topo.txt'
+        tsharkTcpOutput = '/tmp/tshark_tcp_topo.txt'
+        tsharkRoleOutput = '/tmp/tshark_role_request.txt'
+        tsharkFeatureOutput = '/tmp/tshark_feature_reply.txt'
+        tsharkFinAckOutput = '/tmp/tshark_fin_ack.txt'
+
+        # Switch connect measurement list
+        # TCP Syn/Ack -> Feature Reply latency collection for each node
+        tcpToFeatureLatNodeIter = numpy.zeros((clusterCount, int(numIter)))
+        # Feature Reply -> Role Request latency collection for each node
+        featureToRoleRequestLatNodeIter = numpy.zeros((clusterCount,
+            int(numIter)))
+        # Role Request -> Role Reply latency collection for each node
+        roleRequestToRoleReplyLatNodeIter = numpy.zeros((clusterCount,
+            int(numIter)))
+        # Role Reply -> Device Update latency collection for each node
+        roleReplyToDeviceLatNodeIter = numpy.zeros((clusterCount,
+            int(numIter)))
+        # Device Update -> Graph Update latency collection for each node
+        deviceToGraphLatNodeIter = numpy.zeros((clusterCount,
+            int(numIter)))
+        endToEndLatNodeIter = numpy.zeros((clusterCount, int(numIter)))
+
+        # Switch disconnect measurement lists
+        # Mininet Fin / Ack -> Mininet Ack
+        finAckTransactionLatNodeIter = numpy.zeros((clusterCount,
+            int(numIter)))
+        # Mininet Ack -> Device Event
+        ackToDeviceLatNodeIter = numpy.zeros((clusterCount,
+            int(numIter)))
+        # Device event -> Graph event
+        deviceToGraphDiscLatNodeIter = numpy.zeros((clusterCount,
+            int(numIter)))
+        endToEndDiscLatNodeIter = numpy.zeros((clusterCount, int(numIter)))
+
+        assertion = main.TRUE
+        localTime = time.strftime('%x %X')
+        localTime = localTime.replace('/', '')
+        localTime = localTime.replace(' ', '_')
+        localTime = localTime.replace(':', '')
+
+        if debugMode == 'on':
+            main.ONOSbench.tsharkPcap('eth0', '/tmp/single_sw_lat_pcap_' + localTime)
+            main.log.info('Debug mode is on')
+
+        main.log.report('Latency of adding one switch to controller')
+        main.log.report('First ' + str(iterIgnore) + ' iterations ignored' + ' for jvm warmup time')
+        main.log.report('Total iterations of test: ' + str(numIter))
+
+        for i in range(0, int(numIter)):
+            main.log.info('Starting tshark capture')
+            main.ONOSbench.tsharkGrep(tsharkTcpString, tsharkTcpOutput)
+            main.ONOSbench.tsharkGrep(tsharkOfString, tsharkOfOutput)
+            main.ONOSbench.tsharkGrep(tsharkRoleRequest, tsharkRoleOutput)
+            main.ONOSbench.tsharkGrep(tsharkFeatureReply, tsharkFeatureOutput)
+
+            time.sleep(10)
+
+            main.log.info('Assigning s3 to controller')
+            main.Mininet1.assignSwController(sw='s3',
+                    ip=main.ONOSIp[0])
+
+            jsonStr = []
+            for node in range (0, clusterCount):
+                metricsSwUp = CLIs[node].topologyEventsMetrics()
+                jsonStr.append(metricsSwUp)
+
+            time.sleep(10)
+
+            main.log.info('Stopping all Tshark processes')
+            main.ONOSbench.tsharkStop()
+
+            time.sleep(5)
+
+            '''
+            main.log.info('Copying over tshark files')
+            os.system('scp ' + ONOSUser + '@' + main.ONOSIp[0] +
+                    ':' + tsharkTcpOutput + ' /tmp/')
+            os.system('scp ' + ONOSUser + '@' + main.ONOSIp[0] +
+                    ':' + tsharkRoleOutput + ' /tmp/')
+            os.system('scp ' + ONOSUser + '@' + main.ONOSIp[0] +
+                    ':' + tsharkFeatureOutput + ' /tmp/')
+            os.system('scp ' + ONOSUser + '@' +
+                      main.ONOSIp[0] + ':' + tsharkOfOutput + ' /tmp/')
+            '''
+
+            # Get tcp syn / ack output
+            time.sleep(1)
+
+            tcpFile = open(tsharkTcpOutput, 'r')
+            tempText = tcpFile.readline()
+            tempText = tempText.split(' ')
+            main.log.info('Object read in from TCP capture: ' + str(tempText))
+
+            if len(tempText) > 1:
+                t0Tcp = float(tempText[1]) * 1000.0
+            else:
+                main.log.error('Tshark output file for TCP' + ' returned unexpected results')
+                t0Tcp = 0
+                assertion = main.FALSE
+            tcpFile.close()
+
+            # Get Role reply output
+            ofFile = open(tsharkOfOutput, 'r')
+            lineOfp = ''
+            while True:
+                tempText = ofFile.readline()
+                if tempText != '':
+                    lineOfp = tempText
+                else:
+                    break
+            obj = lineOfp.split(' ')
+            main.log.info('Object read in from OFP capture: ' +
+                    str(lineOfp))
+            if len(obj) > 1:
+                t0Ofp = float(obj[1]) * 1000.0
+            else:
+                main.log.error('Tshark output file for OFP' +
+                        ' returned unexpected results')
+                t0Ofp = 0
+                assertion = main.FALSE
+            ofFile.close()
+
+            # Get role request output
+            roleFile = open(tsharkRoleOutput, 'r')
+            tempText = roleFile.readline()
+            tempText = tempText.split(' ')
+            if len(tempText) > 1:
+                main.log.info('Object read in from role request capture:' +
+                        str(tempText))
+                roleTimestamp = float(tempText[1]) * 1000.0
+            else:
+                main.log.error('Tshark output file for role request' +
+                        ' returned unexpected results')
+                timeRoleRequest = 0
+                assertion = main.FALSE
+            roleFile.close()
+
+            # Get feature reply output
+            featureFile = open(tsharkFeatureOutput, 'r')
+            tempText = featureFile.readline()
+            tempText = tempText.split(' ')
+            if len(tempText) > 1:
+                main.log.info('Object read in from feature reply capture: '+
+                        str(tempText))
+                if tempText[1] != ' ' and float(tempText[1]) > 1400000000.0:
+                    temp = tempText[1]
+                elif tempText[2] != ' ' and float(tempText[2]) > 1400000000.0:
+                    temp = tempText[2]
+                else:
+                    temp = 0
+                featureTimestamp = float(temp) * 1000.0
+            else:
+                main.log.error('Tshark output file for feature reply' +
+                        ' returned unexpected results')
+                timeFeatureReply = 0
+                assertion = main.FALSE
+            featureFile.close()
+
+            for node in range(0, clusterCount):
+                nodeNum = node+1
+                #metricsSwUp = CLIs[node].topologyEventsMetrics
+                #jsonStr = metricsSwUp()
+                jsonObj = json.loads(jsonStr[node])
+                if jsonObj:
+                    graphTimestamp = jsonObj[graphTimestampKey]['value']
+                    deviceTimestamp = jsonObj[deviceTimestampKey]['value']
+                else:
+                    main.log.error( "Unexpected JSON object" )
+                    # If we could not obtain the JSON object,
+                    # set the timestamps to 0, which will be
+                    # excluded from the measurement later on
+                    # (realized as invalid)
+                    graphTimestamp = 0
+                    deviceTimestamp = 0
+
+                endToEnd = int(graphTimestamp) - int(t0Tcp)
+
+                # Below are measurement breakdowns of the end-to-end
+                # measurement.
+                tcpToFeature = int(featureTimestamp) - int(t0Tcp)
+                featureToRole = int(roleTimestamp) - int(featureTimestamp)
+                roleToOfp = float(t0Ofp) - float(roleTimestamp)
+                ofpToDevice = float(deviceTimestamp) - float(t0Ofp)
+                # Timestamps gathered from ONOS are millisecond
+                # precision. They are returned as integers, thus no
+                # need to be more precise than 'int'. However,
+                # the processing seems to be mostly under 1 ms,
+                # thus this may be a problem point to handle any
+                # submillisecond output that we are unsure of.
+                # For now, this will be treated as 0 ms if less than 1 ms
+                deviceToGraph = int(graphTimestamp) - int(deviceTimestamp)
+
+                if endToEnd >= thresholdMin and\
+                   endToEnd < thresholdMax and i >= iterIgnore:
+                    endToEndLatNodeIter[node][i] = endToEnd
+                    main.log.info("ONOS "+str(nodeNum)+ " end-to-end: "+
+                            str(endToEnd) + " ms")
+                else:
+                    main.log.info("ONOS "+str(nodeNum)+ " end-to-end "+
+                            "measurement ignored due to excess in "+
+                            "threshold or premature iteration: ")
+                    main.log.info(str(endToEnd))
+
+                if tcpToFeature >= thresholdMin and\
+                   tcpToFeature < thresholdMax and i >= iterIgnore:
+                    tcpToFeatureLatNodeIter[node][i] = tcpToFeature
+                    main.log.info("ONOS "+str(nodeNum)+ " tcp-to-feature: "+
+                            str(tcpToFeature) + " ms")
+                else:
+                    main.log.info("ONOS "+str(nodeNum)+ " tcp-to-feature "+
+                            "measurement ignored due to excess in "+
+                            "threshold or premature iteration: ")
+                    main.log.info(str(tcpToFeature))
+
+                if featureToRole >= thresholdMin and\
+                   featureToRole < thresholdMax and i >= iterIgnore:
+                    featureToRoleRequestLatNodeIter[node][i] = featureToRole
+                    main.log.info("ONOS "+str(nodeNum)+ " feature-to-role: "+
+                            str(featureToRole) + " ms")
+                else:
+                    main.log.info("ONOS "+str(nodeNum)+ " feature-to-role "+
+                            "measurement ignored due to excess in "+
+                            "threshold or premature iteration: ")
+                    main.log.info(str(featureToRole))
+
+                if roleToOfp >= thresholdMin and\
+                   roleToOfp < thresholdMax and i >= iterIgnore:
+                    roleRequestToRoleReplyLatNodeIter[node][i] = roleToOfp
+                    main.log.info("ONOS "+str(nodeNum)+ " role-to-reply: "+
+                            str(roleToOfp) + " ms")
+                else:
+                    main.log.info("ONOS "+str(nodeNum)+ " role-to-reply "+
+                            "measurement ignored due to excess in "+
+                            "threshold or premature iteration: ")
+                    main.log.info(str(roleToOfp))
+
+                if ofpToDevice >= thresholdMin and\
+                   ofpToDevice < thresholdMax and i >= iterIgnore:
+                    roleReplyToDeviceLatNodeIter[node][i] = ofpToDevice
+                    main.log.info("ONOS "+str(nodeNum)+ " reply-to-device: "+
+                            str(ofpToDevice) + " ms")
+                else:
+                    main.log.info("ONOS "+str(nodeNum)+ " reply-to-device "+
+                            "measurement ignored due to excess in "+
+                            "threshold or premature iteration: ")
+                    main.log.info(str(ofpToDevice))
+
+                if deviceToGraph >= thresholdMin and\
+                   deviceToGraph < thresholdMax and i >= iterIgnore:
+                    deviceToGraphLatNodeIter[node][i] = deviceToGraph
+                    main.log.info("ONOS "+str(nodeNum)+ " device-to-graph: "+
+                            str(deviceToGraph) + " ms")
+                else:
+                    if deviceToGraph == 0:
+                        deviceToGraphLatNodeIter[node][i] = 0
+                        main.log.info("ONOS "+str(nodeNum) +
+                            " device-to-graph measurement "+
+                            "was set to 0 ms because of precision "+
+                            "uncertainty. ")
+                    else:
+                        main.log.info("ONOS "+str(nodeNum)+
+                            " device-to-graph "+
+                            "measurement ignored due to excess in "+
+                            "threshold or premature iteration: ")
+                        main.log.info(str(deviceToGraph))
+
+            # ********************
+            time.sleep(5)
+
+            # Get device id to remove
+            deviceIdJsonStr = main.ONOS1cli.devices()
+
+            main.log.info( "Device obj obtained: " + str(deviceIdJsonStr) )
+            deviceId = json.loads(deviceIdJsonStr)
+
+            deviceList = []
+            for device in deviceId:
+                deviceList.append(device['id'])
+
+            # Measure switch down metrics
+            # TCP FIN/ACK -> TCP FIN
+            # TCP FIN -> Device Event
+            # Device Event -> Graph Event
+            # Capture switch down FIN / ACK packets
+
+            # The -A 1 grep option allows us to grab 1 extra line after the
+            # last tshark output grepped originally
+            main.ONOSbench.tsharkGrep( tsharkFinAckSequence, tsharkFinAckOutput,
+                    grepOptions = '-A 1' )
+
+            time.sleep( 5 )
+
+            removeJsonList = []
+            main.step('Remove switch from controller')
+            main.Mininet1.deleteSwController('s3')
+            firstDevice = deviceList[0]
+
+            time.sleep( 5 )
+
+            # We need to get metrics before removing
+            # device from the store below.
+            for node in range(0, clusterCount):
+                metricsSwDown = CLIs[node].topologyEventsMetrics
+                jsonStr = metricsSwDown()
+                removeJsonList.append( json.loads(jsonStr) )
+
+            main.ONOSbench.tsharkStop()
+
+            main.log.info( "Removing device " +str(firstDevice)+
+                    " from ONOS" )
+
+            #if deviceId:
+            main.ONOS1cli.deviceRemove(firstDevice)
+
+            #main.log.info('Copying over tshark files')
+            #os.system('scp ' + ONOSUser + '@' + main.ONOSIp[0] + ':' + tsharkFinAckOutput + ' /tmp/')
+
+            time.sleep( 10 )
+            finAckOutputList = []
+            with open(tsharkFinAckOutput, 'r') as f:
+                tempLine = f.readlines()
+                main.log.info('Object read in from FinAck capture: ' +
+                    "\n".join(tempLine))
+
+                index = 1
+                for line in tempLine:
+                    obj = line.split(' ')
+
+                    # There are at least 3 objects in field (valid
+                    # tshark output is lengthy)
+                    if len(obj) > 2:
+                        # If first index of object is like an epoch time
+                        if obj[1] != ' ' and float(obj[1]) > 1400000000.0:
+                            temp = obj[1]
+                        elif obj[2] != ' 'and float(obj[2]) > 1400000000.0:
+                            temp = obj[2]
+                        elif obj[3] != ' 'and float(obj[3]) > 1400000000.0:
+                            temp = obj[3]
+                        else:
+                            temp = 0
+                        if index == 1:
+                            tFinAck = float(temp) * 1000.0
+                            main.log.info("DEBUG-- tFinAck: " + str(tFinAck))
+                        elif index == 3:
+                            tAck = float(temp) * 1000.0
+                            main.log.info("DEBUG-- tAck: " + str(tAck))
+                        else:
+                            tAck = 0
+                    else:
+                        main.log.error('Tshark output file for OFP' +
+                            ' returned unexpected results')
+                        tFinAck = 0
+                        tAck = 0
+                        assertion = main.FALSE
+
+                    index += 1
+                main.log.info("DEBUG-- tFinAck: " + str(tFinAck))
+                main.log.info("DEBUG-- tAck: " + str(tAck))
+
+            # with open() as f takes care of closing file
+
+            time.sleep(5)
+
+            for node in range(0, clusterCount):
+                nodeNum = node+1
+                jsonObj = removeJsonList[node]
+                if jsonObj:
+                    graphTimestamp = jsonObj[graphTimestampKey]['value']
+                    deviceTimestamp = jsonObj[deviceTimestampKey]['value']
+                    main.log.info("Graph timestamp: "+str(graphTimestamp))
+                    main.log.info("Device timestamp: "+str(deviceTimestamp))
+                else:
+                    main.log.error( "Unexpected JSON object" )
+                    # If we could not obtain the JSON object,
+                    # set the timestamps to 0, which will be
+                    # excluded from the measurement later on
+                    # (realized as invalid)
+                    graphTimestamp = 0
+                    deviceTimestamp = 0
+
+                finAckTransaction = float(tAck) - float(tFinAck)
+                ackToDevice = float(deviceTimestamp) - float(tAck)
+                deviceToGraph = float(graphTimestamp) - float(deviceTimestamp)
+                endToEndDisc = int(graphTimestamp) - int(tFinAck)
+                main.log.info("DEBUG-- endToEndDisc = graphTimestamp - tFinAck  == (" + str(graphTimestamp) + "-" + str(tFinAck) + ")") 
+
+                if endToEndDisc >= thresholdMin and\
+                   endToEndDisc < thresholdMax and i >= iterIgnore:
+                    endToEndDiscLatNodeIter[node][i] = endToEndDisc
+                    main.log.info("ONOS "+str(nodeNum) +
+                            "end-to-end disconnection: "+
+                            str(endToEndDisc) + " ms" )
+                else:
+                    main.log.info("ONOS " + str(nodeNum) +
+                            " end-to-end disconnection "+
+                            "measurement ignored due to excess in "+
+                            "threshold or premature iteration: ")
+                    main.log.info(str(endToEndDisc))
+
+                if finAckTransaction >= thresholdMin and\
+                   finAckTransaction < thresholdMax and i >= iterIgnore:
+                    finAckTransactionLatNodeIter[node][i] = finAckTransaction
+                    main.log.info("ONOS "+str(nodeNum)+
+                            " fin/ack transaction: "+
+                            str(finAckTransaction) + " ms")
+                else:
+                    main.log.info("ONOS "+str(nodeNum)+
+                            " fin/ack transaction "+
+                            "measurement ignored due to excess in "+
+                            "threshold or premature iteration: ")
+                    main.log.info(str(finAckTransaction))
+
+                if ackToDevice >= thresholdMin and\
+                   ackToDevice < thresholdMax and i >= iterIgnore:
+                    ackToDeviceLatNodeIter[node][i] = ackToDevice
+                    main.log.info("ONOS "+str(nodeNum)+
+                            " ack-to-device: "+
+                            str(ackToDevice) + " ms")
+                else:
+                    main.log.info("ONOS "+str(nodeNum)+
+                            " ack-to-device "+
+                            "measurement ignored due to excess in "+
+                            "threshold or premature iteration: ")
+                    main.log.info(str(ackToDevice))
+
+                if deviceToGraph >= thresholdMin and\
+                   deviceToGraph < thresholdMax and i >= iterIgnore:
+                    deviceToGraphDiscLatNodeIter[node][i] = deviceToGraph
+                    main.log.info("ONOS "+str(nodeNum)+
+                            " device-to-graph disconnect: "+
+                            str(deviceToGraph) + " ms")
+                else:
+                    main.log.info("ONOS "+str(nodeNum)+
+                            " device-to-graph disconnect "+
+                            "measurement ignored due to excess in "+
+                            "threshold or premature iteration: ")
+                    main.log.info(str(deviceToGraph))
+
+        endToEndAvg = 0
+        ofpToGraphAvg = 0
+        dbCmdList = []
+        for node in range(0, clusterCount):
+            # List of latency for each node
+            endToEndList = []
+            tcpToFeatureList = []
+            featureToRoleList = []
+            roleToOfpList = []
+            ofpToDeviceList = []
+            deviceToGraphList = []
+
+            finAckTransactionList = []
+            ackToDeviceList = []
+            deviceToGraphDiscList = []
+            endToEndDiscList = []
+
+            # LatNodeIter 2d arrays contain all iteration latency
+            # for each node of the current scale cluster size
+            # Switch connection measurements
+            # Set further acceptance criteria for measurements
+            # here if you would like to filter reporting results
+            for item in endToEndLatNodeIter[node]:
+                if item > 0.0:
+                    endToEndList.append(item)
+
+            for item in tcpToFeatureLatNodeIter[node]:
+                if item > 0.0:
+                    tcpToFeatureList.append(item)
+
+            for item in featureToRoleRequestLatNodeIter[node]:
+                if item > 0.0:
+                    featureToRoleList.append(item)
+
+            for item in roleRequestToRoleReplyLatNodeIter[node]:
+                if item > 0.0:
+                    roleToOfpList.append(item)
+
+            for item in roleReplyToDeviceLatNodeIter[node]:
+                if item >= 0.0:
+                    ofpToDeviceList.append(item)
+
+            for item in featureToRoleRequestLatNodeIter[node]:
+                if item > 0.0:
+                    featureToRoleList.append(item)
+
+            for item in deviceToGraphLatNodeIter[node]:
+                if item >= 0.0:
+                    deviceToGraphList.append(item)
+
+            # Switch disconnect measurements
+            for item in endToEndDiscLatNodeIter[node]:
+                if item > 0.0:
+                    endToEndDiscList.append(item)
+
+            for item in finAckTransactionLatNodeIter[node]:
+                if item > 0.0:
+                    finAckTransactionList.append(item)
+
+            for item in ackToDeviceLatNodeIter[node]:
+                if item > 0.0:
+                    ackToDeviceList.append(item)
+
+            for item in deviceToGraphDiscLatNodeIter[node]:
+                if item >= 0.0:
+                    deviceToGraphDiscList.append(item)
+
+            endToEndAvg = round(numpy.mean(endToEndList), 2)
+            endToEndStdDev = round(numpy.std(endToEndList), 2)
+            main.log.info("endToEndList: " + str(endToEndList))
+
+            tcpToFeatureAvg = round(numpy.mean(tcpToFeatureList), 2)
+            tcpToFeatureStdDev = round(numpy.std(tcpToFeatureList), 2)
+            main.log.info("tcpToFeatureList: " + str(tcpToFeatureList))
+
+            featureToRoleAvg = round(numpy.mean(featureToRoleList), 2)
+            featureToRoleStdDev = round(numpy.std(featureToRoleList), 2)
+            main.log.info("featureToRoleList: " + str(featureToRoleList)) 
+
+            roleToOfpAvg = round(numpy.mean(roleToOfpList), 2)
+            roleToOfpStdDev = round(numpy.std(roleToOfpList), 2)
+            main.log.info("roleToOfList: " + str(roleToOfpList))
+
+            ofpToDeviceAvg = round(numpy.mean(ofpToDeviceList), 2)
+            ofpToDeviceStdDev = round(numpy.std(ofpToDeviceList), 2)
+            main.log.info("ofpToDeviceList: " + str(ofpToDeviceList))
+
+            deviceToGraphAvg = round(numpy.mean(deviceToGraphList), 2)
+            deviceToGraphStdDev = round(numpy.std(deviceToGraphList), 2)
+            main.log.info("deviceToGraphList: " + str(deviceToGraphList))
+
+            endToEndDiscAvg = round(numpy.mean(endToEndDiscList), 2)
+            endToEndDiscStdDev = round(numpy.std(endToEndDiscList), 2)
+            main.log.info("endToEndDiscList: " + str(endToEndDiscList))
+
+            finAckAvg = round(numpy.mean(finAckTransactionList), 2)
+            finAckStdDev = round(numpy.std(finAckTransactionList), 2)
+            main.log.info("finAckTransactionList: " + str(finAckTransactionList))
+
+            ackToDeviceAvg = round(numpy.mean(ackToDeviceList), 2)
+            ackToDeviceStdDev = round(numpy.std(ackToDeviceList), 2)
+            main.log.info("ackToDeviceList: " + str(ackToDeviceList))
+
+            deviceToGraphDiscAvg = round(numpy.mean(deviceToGraphDiscList), 2)
+            deviceToGraphDiscStdDev = round(numpy.std(deviceToGraphDiscList), 2)
+            main.log.info("deviceToGraphDiscList: " + str(deviceToGraphDiscList))
+
+            main.log.report(' - Node ' + str(node + 1) + ' Summary - ')
+            main.log.report(' - Switch Connection Statistics - ')
+
+            main.log.report(' End-to-end Avg: ' + str(endToEndAvg) +
+                    ' ms' + ' End-to-end Std dev: ' +
+                    str(endToEndStdDev) + ' ms')
+
+            main.log.report(' Tcp-to-feature-reply Avg: ' +
+                    str(tcpToFeatureAvg) + ' ms')
+            main.log.report(' Tcp-to-feature-reply Std dev: '+
+                    str(tcpToFeatureStdDev) + ' ms')
+
+            main.log.report(' Feature-reply-to-role-request Avg: ' +
+                    str(featureToRoleAvg) + ' ms')
+            main.log.report(' Feature-reply-to-role-request Std Dev: ' +
+                    str(featureToRoleStdDev) + ' ms')
+
+            main.log.report(' Role-request-to-role-reply Avg: ' +
+                    str(roleToOfpAvg) +' ms')
+            main.log.report(' Role-request-to-role-reply Std dev: ' +
+                    str(roleToOfpStdDev) + ' ms')
+
+            main.log.report(' Role-reply-to-device Avg: ' +
+                    str(ofpToDeviceAvg) +' ms')
+            main.log.report(' Role-reply-to-device Std dev: ' +
+                    str(ofpToDeviceStdDev) + ' ms')
+
+            main.log.report(' Device-to-graph Avg: ' +
+                    str(deviceToGraphAvg) + ' ms')
+            main.log.report( 'Device-to-graph Std dev: ' +
+                    str(deviceToGraphStdDev) + ' ms')
+
+            main.log.report(' - Switch Disconnection Statistics - ')
+            main.log.report(' End-to-end switch disconnect Avg: ' +
+                    str(endToEndDiscAvg) + ' ms')
+            main.log.report(' End-to-end switch disconnect Std dev: ' +
+                    str(endToEndDiscStdDev) + ' ms')
+            main.log.report(' Fin/Ack-to-Ack Avg: ' + str(finAckAvg) + ' ms')
+            main.log.report(' Fin/Ack-to-Ack Std dev: ' +
+                    str(finAckStdDev) + ' ms')
+
+            main.log.report(' Ack-to-device Avg: ' + str(ackToDeviceAvg) +
+                    ' ms')
+            main.log.report(' Ack-to-device Std dev: ' + str(ackToDeviceStdDev) +
+                    ' ms')
+
+            main.log.report(' Device-to-graph (disconnect) Avg: ' +
+                    str(deviceToGraphDiscAvg) + ' ms')
+            main.log.report(' Device-to-graph (disconnect) Std dev: ' +
+                    str(deviceToGraphDiscStdDev) + ' ms')
+
+            # For database schema, refer to Amazon web services
+            dbCmdList.append(
+                    "'" + timeToPost + "','switch_latency_results'," +
+                    jenkinsBuildNumber + ',' + str(clusterCount) + ",'baremetal" +
+                    str(node + 1) + "'," +
+                    str(endToEndAvg) + ',' +
+                    str(tcpToFeatureAvg) + ',' +
+                    str(featureToRoleAvg) + ',' +
+                    str(roleToOfpAvg) + ',' +
+                    str(ofpToDeviceAvg) + ',' +
+                    str(deviceToGraphAvg) + ',' +
+                    str(endToEndDiscAvg) + ',' +
+                    str(finAckAvg) + ',' +
+                    str(ackToDeviceAvg) + ',' +
+                    str(deviceToGraphDiscAvg))
+
+        if debugMode == 'on':
+            main.ONOSbench.cpLogsToDir('/opt/onos/log/karaf.log',
+                    '/tmp/', copyFileName='sw_lat_karaf')
+        fResult = open(resultPath, 'a')
+        for line in dbCmdList:
+            if line:
+                fResult.write(line + '\n')
+                main.log.report(line)
+        fResult.close()
+
+        assertion = main.TRUE
+
+        utilities.assert_equals(expect=main.TRUE, actual=assertion,
+                onpass='Switch latency test successful',
+                onfail='Switch latency test failed')
+
+        main.Mininet1.stopNet()
diff --git a/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.topo b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.topo
new file mode 100644
index 0000000..8b05fd0
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.topo
@@ -0,0 +1,107 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+                <home>~/onos</home>
+                <nodes>7</nodes> 
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOS1cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1cli>
+
+        <ONOS2cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2cli>
+
+        <ONOS3cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3cli>
+
+        <ONOS4cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4cli>
+
+        <ONOS5cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5cli>
+
+        <ONOS6cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6cli>
+
+        <ONOS7cli>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</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>
+
+        <Mininet1>
+            <host>localhost</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>MininetCliDriver</type>
+            <connect_order>16</connect_order>
+            <COMPONENTS>
+                <arg1> --custom ~/mininet/custom/topo-perf-1sw.py </arg1>
+                <arg2> --topo mytopo</arg2>
+                <arg3> --switch ovsk,protocols=OpenFlow13</arg3>
+                <controller> remote </controller>
+                <home>~/mininet/custom/</home>
+            </COMPONENTS>
+        </Mininet1>
+
+    </COMPONENT>
+
+</TOPOLOGY>
+ 
diff --git a/TestON/tests/SCPF/SCPFswitchLat/__init__.py b/TestON/tests/SCPF/SCPFswitchLat/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFswitchLat/__init__.py
diff --git a/TestON/tests/SCPF/__init__.py b/TestON/tests/SCPF/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPF/__init__.py
diff --git a/TestON/tests/SCPF/dependencies/__init__.py b/TestON/tests/SCPF/dependencies/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/SCPF/dependencies/__init__.py