Merge "Update FUNCovsdbtest"
diff --git a/TestON/drivers/common/api/controller/onosrestdriver.py b/TestON/drivers/common/api/controller/onosrestdriver.py
index 979b0b6..082ab17 100755
--- a/TestON/drivers/common/api/controller/onosrestdriver.py
+++ b/TestON/drivers/common/api/controller/onosrestdriver.py
@@ -216,34 +216,6 @@
             main.cleanup()
             main.exit()
 
-    def getIntentsId( self, ip="DEFAULT", port="DEFAULT" ):
-        """
-        Description:
-           Gets all intents ID using intents function
-        Returns:
-            List of intents ID;Returns None for exception; Returns None for
-            exception; Returns None for exception
-        """
-        try:
-            intentsDict = {}
-            intentsIdList = []
-            intentsDict = json.loads( self.intents( ip=ip, port=port ) )
-            for intent in intentsDict:
-                intentsIdList.append( intent.get( 'id' ) )
-            if not intentsIdList:
-                main.log.debug( "Cannot find any intents" )
-                return main.FALSE
-            else:
-                main.log.info( "Found intents: " + str( intentsIdList ) )
-                return main.TRUE
-        except ( AttributeError, TypeError ):
-            main.log.exception( self.name + ": Object not as expected" )
-            return None
-        except Exception:
-            main.log.exception( self.name + ": Uncaught exception!" )
-            main.cleanup()
-            main.exit()
-
     def apps( self, ip="DEFAULT", port="DEFAULT" ):
         """
         Description:
@@ -474,7 +446,7 @@
                                   url="/intents", ip = ip, port = port,
                                   data=json.dumps( intentJson ) )
             if response:
-                if 201:
+                if "201" in str( response[ 0 ] ):
                     main.log.info( self.name + ": Successfully POST host" +
                                    " intent between host: " + hostIdOne +
                                    " and host: " + hostIdTwo )
@@ -615,8 +587,6 @@
 
             # TODO: Bandwidth and Lambda will be implemented if needed
 
-            main.log.debug( intentJson )
-
             output = None
             if ip == "DEFAULT":
                 main.log.warn( "No ip given, reverting to ip from topo file" )
@@ -628,8 +598,11 @@
             response = self.send( method="POST",
                                   url="/intents", ip = ip, port = port,
                                   data=json.dumps( intentJson ) )
+
+            main.log.debug( intentJson )
+
             if response:
-                if 201:
+                if "201" in str( response[ 0 ] ):
                     main.log.info( self.name + ": Successfully POST point" +
                                    " intent between ingress: " + ingressDevice +
                                    " and egress: " + egressDevice + " devices" )
@@ -647,11 +620,176 @@
             main.cleanup()
             main.exit()
 
+    def addSinglepointToMultipointIntent(self,
+                       ingressDevice,
+                       egressDeviceList,
+                       portEgressList,
+                       appId='org.onosproject.cli',
+                       portIngress="",
+                       ethType="",
+                       ethSrc="",
+                       ethDst="",
+                       bandwidth="",
+                       lambdaAlloc=False,
+                       ipProto="",
+                       ipSrc="",
+                       ipDst="",
+                       tcpSrc="",
+                       tcpDst="",
+                       partial=False,
+                       ip="DEFAULT",
+                       port="DEFAULT",
+                       vlanId="" ):
+        """
+        Description:
+            Adds a point-to-multi point intent ( uni-directional ) by
+            specifying device id's and optional fields
+        Required:
+            * ingressDevice: device id of ingress device
+            * egressDevice: device id of egress device
+            * portEgressList: a list of port id of egress device
+
+        Optional:
+            * portIngress: port id of ingress device
+            * ethType: specify ethType
+            * ethSrc: specify ethSrc ( i.e. src mac addr )
+            * ethDst: specify ethDst ( i.e. dst mac addr )
+            * bandwidth: specify bandwidth capacity of link (TODO)
+            * lambdaAlloc: if True, intent will allocate lambda
+              for the specified intent (TODO)
+            * ipProto: specify ip protocol
+            * ipSrc: specify ip source address with mask eg. ip#/24
+            * ipDst: specify ip destination address eg. ip#/24
+            * tcpSrc: specify tcp source port
+            * tcpDst: specify tcp destination port
+        Returns:
+            Returns main.TRUE for successful requests; Returns main.FALSE if
+            no ingress|egress port found and if error on requests;
+            Returns None for exceptions
+        NOTE:
+            The ip and port option are for the requests input's ip and port
+            of the ONOS node
+        """
+        try:
+
+            if "/" in ingressDevice:
+                if not portIngress:
+                    ingressPort = ingressDevice.split( "/" )[ 1 ]
+                ingressDevice = ingressDevice.split( "/" )[ 0 ]
+            else:
+                if not portIngress:
+                    main.log.debug( self.name + ": Ingress port not specified" )
+                    return main.FALSE
+            index = 0
+            for egressDevice in egressDeviceList:
+                if "/" in egressDevice:
+                    portEgressList.append( egressDevice.split( "/" )[ 1 ] )
+                    egressDeviceList[ index ] = egressDevice.split( "/" )[ 0 ]
+                else:
+                    if not portEgressList:
+                        main.log.debug( self.name + ": Egress port not specified" )
+                        return main.FALSE
+                index = index + 1
+
+            intentJson = { "ingressPoint": { "device": ingressDevice,
+                                             "port": ingressPort },
+                           "selector": { "criteria": [] },
+                           "priority": 55,
+                           "treatment": { "deferred": [],
+                                          "instructions": [] },
+                           "egressPoint": { "connectPoints": [] },
+                           "appId": appId,
+                           "type": "SinglePointToMultiPointIntent",
+                           "constraints": [ { "type": "LinkTypeConstraint",
+                                              "types": ["OPTICAL"],
+                                              "inclusive": "false" } ] }
+
+            index = 0
+            for ep in portEgressList:
+                intentJson[ 'egressPoint' ][ 'connectPoints' ].append(
+                    { "device": egressDeviceList[ index ],
+                      "port": ep } )
+                index += 1
+
+            if ethType == "IPV4":
+                intentJson[ 'selector' ][ 'criteria' ].append(
+                    { "type": "ETH_TYPE",
+                      "ethType": 2048 } )
+            elif ethType:
+                intentJson[ 'selector' ][ 'criteria' ].append(
+                    { "type": "ETH_TYPE",
+                      "ethType": ethType } )
+
+            if ethSrc:
+                intentJson[ 'selector' ][ 'criteria' ].append(
+                    { "type": "ETH_SRC",
+                      "mac": ethSrc } )
+
+            if ethDst:
+                for dst in ethDst:
+                    if dst:
+                        intentJson[ 'selector' ][ 'criteria' ].append(
+                            { "type": "ETH_DST",
+                              "mac": dst } )
+            if tcpSrc:
+                intentJson[ 'selector' ][ 'criteria' ].append(
+                    { "type": "TCP_SRC",
+                      "tcpPort": tcpSrc } )
+            if tcpDst:
+                intentJson[ 'selector' ][ 'criteria' ].append(
+                    { "type": "TCP_DST",
+                      "tcpPort": tcpDst } )
+            if ipProto:
+                intentJson[ 'selector' ][ 'criteria' ].append(
+                    { "type": "IP_PROTO",
+                      "protocol": ipProto } )
+            if vlanId:
+                intentJson[ 'selector' ][ 'criteria' ].append(
+                    { "type": "VLAN_VID",
+                      "vlanId": vlanId } )
+
+            # TODO: Bandwidth and Lambda will be implemented if needed
+
+            output = None
+            if ip == "DEFAULT":
+                main.log.warn( "No ip given, reverting to ip from topo file" )
+                ip = self.ip_address
+            if port == "DEFAULT":
+                main.log.warn( "No port given, reverting to port " +
+                               "from topo file" )
+                port = self.port
+            response = self.send( method="POST",
+                                 url="/intents", ip=ip, port=port,
+                                 data=json.dumps( intentJson ) )
+
+            main.log.debug(intentJson)
+
+            if response:
+                if "201" in str( response[ 0 ] ):
+                    main.log.info( self.name + ": Successfully POST point" +
+                                   " intent between ingress: " + ingressDevice +
+                                   " and egress: " + str(egressDeviceList) + " devices" )
+                    return main.TRUE
+                else:
+                    main.log.error( "Error with REST request, response was: " + str( response ) )
+                    return main.FALSE
+            else:
+                main.log.error( "REST request has no response." )
+                return main.FALSE
+
+        except ( AttributeError, TypeError ):
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
     def removeIntent( self, intentId, appId='org.onosproject.cli',
                        ip="DEFAULT", port="DEFAULT" ):
         """
-        Remove intent for specified application id and intent id;
-        Returns None for exception
+            Remove intent for specified application id and intent id;
+            Returns None for exception
         """
         try:
             output = None
@@ -681,16 +819,23 @@
             main.cleanup()
             main.exit()
 
-    def getIntentsId( self, ip="DEFAULT", port="DEFAULT" ):
+    def getIntentsId( self ):
         """
-        Returns a list of intents id; Returns None for exception
+        Description:
+            Gets all intents ID using intents function
+        Returns:
+            List of intents ID if found any intents; Returns main.FALSE for other exceptions
         """
         try:
             intentIdList = []
             intentsJson = json.loads( self.intents() )
             for intent in intentsJson:
                 intentIdList.append( intent.get( 'id' ) )
-            return intentIdList
+            if not intentIdList:
+                main.log.debug( "Cannot find any intents" )
+                return main.FALSE
+            else:
+                return intentIdList
         except ( AttributeError, TypeError ):
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -711,7 +856,8 @@
         try:
             results = []
             if intentIdList == 'ALL':
-                intentIdList = self.getIntentsId( ip=ip, port=port )
+                # intentIdList = self.getIntentsId( ip=ip, port=port )
+                intentIdList = self.getIntentsId()
 
             main.log.info( self.name + ": Removing intents " +
                            str( intentIdList ) )
@@ -988,7 +1134,6 @@
                 intentsId = self.getIntentsId( ip=ip, port=port )
             intentsDict = self.getIntentState( intentsId, ip=ip, port=port )
 
-            #print "len of intentsDict ", str( len( intentsDict ) )
             if len( intentsId ) != len( intentsDict ):
                 main.log.error( self.name + ": There is something wrong " +
                                 "getting intents state" )
@@ -1152,7 +1297,7 @@
                                   url=url, ip = ip, port = port,
                                   data=json.dumps( flowJson ) )
             if response:
-                if 201:
+                if "201" in str( response[ 0 ] ):
                     main.log.info( self.name + ": Successfully POST flow" +
                                    "in device: " + str( deviceId ) )
                     return main.TRUE
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index ac3a9a2..2d61501 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -3794,6 +3794,43 @@
             main.cleanup()
             main.exit()
 
+    def changeInterfaceStatus( self, devicename, intf, status ):
+        '''
+
+        Args:
+            devicename: switch name
+            intf: port name on switch
+            status: up or down
+
+        Returns: boolean to show success change status
+
+        '''
+        if status == "down" or status == "up":
+            try:
+                cmd = devicename + " ifconfig " + intf + " " + status
+                self.handle.sendline( cmd )
+                self.handle.expect("mininet>")
+                return main.TRUE
+            except pexpect.TIMEOUT:
+                main.log.exception(self.name + ": Command timed out")
+                return main.FALSE
+            except pexpect.EOF:
+                main.log.exception(self.name + ": connection closed.")
+                main.cleanup()
+                main.exit()
+            except TypeError:
+                main.log.exception(self.name + ": TypeError")
+                main.cleanup()
+                main.exit()
+            except Exception:
+                main.log.exception(self.name + ": Uncaught exception!")
+                main.cleanup()
+                main.exit()
+        else:
+            main.log.warn("Interface status should be up or down!")
+            return main.FALSE
+
+
 
 if __name__ != "__main__":
     sys.modules[ __name__ ] = MininetCliDriver()
diff --git a/TestON/drivers/common/cli/onosclidriver.py b/TestON/drivers/common/cli/onosclidriver.py
index 306680e..ff3a56c 100755
--- a/TestON/drivers/common/cli/onosclidriver.py
+++ b/TestON/drivers/common/cli/onosclidriver.py
@@ -4711,7 +4711,9 @@
         '''
         try:
             if type( device ) is str:
-                device = list( device )
+                deviceStr = device
+                device = []
+                device.append( deviceStr )
 
             for d in device:
                 time.sleep( 1 )
diff --git a/TestON/drivers/common/cli/onosdriver.py b/TestON/drivers/common/cli/onosdriver.py
index 635178e..d120951 100755
--- a/TestON/drivers/common/cli/onosdriver.py
+++ b/TestON/drivers/common/cli/onosdriver.py
@@ -358,6 +358,51 @@
             main.cleanup()
             main.exit()
 
+    def buckBuild( self, timeout=180 ):
+        """
+        Build onos using buck.
+        """
+        try:
+            ret = main.TRUE
+            self.handle.sendline( "buck build onos" )
+            self.handle.expect( "buck build onos" )
+            output = ""
+            while True:
+                i = self.handle.expect( [ "This does not appear to be the root of a Buck project.",
+                                          "\n",
+                                          "BUILD FAILED",
+                                          "\$" ],
+                                        timeout=timeout )
+                output += str( self.handle.before + self.handle.after )
+                if i == 0:
+                    main.log.error( "Wrong location" )
+                    ret = main.FALSE
+                elif i == 1:
+                    # end of a line, buck is still printing output
+                    pass
+                elif i == 2:
+                    # Build failed
+                    main.log.error( "Build failed" )
+                    ret = main.FALSE
+                elif i == 3:
+                    # Prompt returned
+                    break
+            main.log.debug( output )
+            return ret
+        except pexpect.TIMEOUT:
+            main.log.exception( self.name + ": TIMEOUT exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            return main.FALSE
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( "Failed to build and package ONOS" )
+            main.cleanup()
+            main.exit()
+
     def gitPull( self, comp1="", fastForward=True ):
         """
         Assumes that "git pull" works without login
@@ -956,31 +1001,38 @@
                                       "onos\sstart/running,\sprocess",
                                       "ONOS\sis\salready\sinstalled",
                                       "already\sup-to-date",
+                                      "does not exist",
                                       "\$",
                                       pexpect.TIMEOUT ], timeout=180 )
             if i == 0:
+                # can't reach ONOS node
                 main.log.warn( "Network is unreachable" )
                 self.handle.expect( "\$" )
                 return main.FALSE
             elif i == 1:
+                # Process started
                 main.log.info(
                     "ONOS was installed on " +
                     node +
                     " and started" )
                 self.handle.expect( "\$" )
                 return main.TRUE
-            elif i == 2:
-                main.log.info( "ONOS is already installed on " + node )
-                self.handle.expect( "\$" )
-                return main.TRUE
-            elif i == 3:
+            elif i == 2 or i == 3:
+                # same bits are already on ONOS node
                 main.log.info( "ONOS is already installed on " + node )
                 self.handle.expect( "\$" )
                 return main.TRUE
             elif i == 4:
+                # onos not packaged
+                main.log.error( "ONOS package not found." )
+                self.handle.expect( "\$" )
+                return main.FALSE
+            elif i == 5:
+                # prompt
                 main.log.info( "ONOS was installed on " + node )
                 return main.TRUE
-            elif i == 5:
+            elif i == 6:
+                # timeout
                 main.log.info(
                     "Installation of ONOS on " +
                     node +
diff --git a/TestON/drivers/common/clidriver.py b/TestON/drivers/common/clidriver.py
index 283088d..c9a19bb 100644
--- a/TestON/drivers/common/clidriver.py
+++ b/TestON/drivers/common/clidriver.py
@@ -67,6 +67,9 @@
                 maxread=1000000,
                 timeout=60 )
 
+        # set tty window size
+        self.handle.setwinsize( 24, 250 )
+
         self.handle.logfile = self.logfile_handler
         i = 5
         while i == 5:
diff --git a/TestON/tests/FUNC/FUNCflow/FUNCflow.py b/TestON/tests/FUNC/FUNCflow/FUNCflow.py
index 80bd618..54c81a5 100644
--- a/TestON/tests/FUNC/FUNCflow/FUNCflow.py
+++ b/TestON/tests/FUNC/FUNCflow/FUNCflow.py
@@ -69,9 +69,9 @@
                                          direction="to" )
 
         utilities.assert_equals( expect=main.TRUE,
-                                actual=copyResult,
-                                onpass="Successfully copy " + "test variables ",
-                                onfail="Failed to copy test variables" )
+                                 actual=copyResult,
+                                 onpass="Successfully copy " + "test variables ",
+                                 onfail="Failed to copy test variables" )
 
 
         if main.CLIs:
@@ -157,7 +157,7 @@
         onosUninstallResult = main.TRUE
         for ip in main.ONOSip:
             onosUninstallResult = onosUninstallResult and \
-                    main.ONOSbench.onosUninstall( nodeIp = ip )
+                    main.ONOSbench.onosUninstall( nodeIp=ip )
         stepResult = onosUninstallResult
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
@@ -168,7 +168,7 @@
         onosInstallResult = main.TRUE
         for i in range( main.numCtrls ):
             onosInstallResult = onosInstallResult and \
-                    main.ONOSbench.onosInstall( node = main.ONOSip[ i ] )
+                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
         stepResult = onosInstallResult
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
diff --git a/TestON/tests/FUNC/FUNCintent/FUNCintent.py b/TestON/tests/FUNC/FUNCintent/FUNCintent.py
index 5ee3f70..989fd56 100644
--- a/TestON/tests/FUNC/FUNCintent/FUNCintent.py
+++ b/TestON/tests/FUNC/FUNCintent/FUNCintent.py
@@ -301,7 +301,7 @@
                     try:
                         deviceData = json.loads( devices[ controller ] )
                         portData = json.loads( ports[ controller ] )
-                    except (TypeError,ValueError):
+                    except( TypeError, ValueError ):
                         main.log.error( "Could not load json: {0} or {1}".format( str( devices[ controller ] ), str( ports[ controller ] ) ) )
                         currentDevicesResult = main.FALSE
                     else:
@@ -316,8 +316,8 @@
                 if links[ controller ] and "Error" not in links[ controller ]:
                     try:
                         linkData = json.loads( links[ controller ] )
-                    except (TypeError,ValueError):
-                        main.log.error("Could not load json:" + str( links[ controller ] ) )
+                    except( TypeError, ValueError ):
+                        main.log.error( "Could not load json:" + str( links[ controller ] ) )
                         currentLinksResult = main.FALSE
                     else:
                         currentLinksResult = main.Mininet1.compareLinks(
@@ -331,8 +331,8 @@
                 if hosts[ controller ] and "Error" not in hosts[ controller ]:
                     try:
                         hostData = json.loads( hosts[ controller ] )
-                    except (TypeError,ValueError):
-                        main.log.error("Could not load json:" + str( hosts[ controller ] ) )
+                    except( TypeError, ValueError ):
+                        main.log.error( "Could not load json:" + str( hosts[ controller ] ) )
                         currentHostsResult = main.FALSE
                     else:
                         currentHostsResult = main.Mininet1.compareHosts(
@@ -583,6 +583,7 @@
         """
         if main.initialized == main.FALSE:
             main.log.error( "Test components did not start correctly, skipping further tests" )
+            main.stop()
             main.skipCase()
         main.case( "Balance mastership of switches" )
         main.step( "Balancing mastership of switches" )
@@ -648,7 +649,7 @@
                                  onfail="Failed to stop mininet and scapy" )
 
         main.step( "Stopping Mininet Topology" )
-        mininetResult = main.Mininet1.stopNet( )
+        mininetResult = main.Mininet1.stopNet()
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=mininetResult,
@@ -733,8 +734,8 @@
         try:
             assert main.numSwitch
         except AssertionError:
-            main.log.error( "Place the total number of switch topology in \
-                             main.numSwitch" )
+            main.log.error( "Place the total number of switch topology in " +\
+                             main.numSwitch )
             main.initialized = main.FALSE
             main.skipCase()
 
@@ -750,7 +751,7 @@
                                 "each step such as IPV4, Dual stack, VLAN " +\
                                 "etc;\nThe test will use OF " + main.OFProtocol +\
                                 " OVS running in Mininet and compile intents" +\
-                               " using " + main.flowCompiler
+                                " using " + main.flowCompiler
 
         main.step( "IPV4: Add host intents between h1 and h9" )
         main.assertReturnString = "Assertion Result for IPV4 host intent with mac addresses\n"
@@ -762,7 +763,7 @@
                                               name='IPV4',
                                               onosNode='0',
                                               host1=host1,
-                                              host2=host2)
+                                              host2=host2 )
         if installResult:
             testResult = main.intentFunction.testHostIntent( main,
                                               name='IPV4',
@@ -772,14 +773,14 @@
                                               host2=host2,
                                               sw1='s5',
                                               sw2='s2',
-                                              expectedLink = 18)
+                                              expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
                                  onpass=main.assertReturnString,
-                                 onfail=main.assertReturnString)
+                                 onfail=main.assertReturnString )
 
         main.step( "DUALSTACK1: Add host intents between h3 and h11" )
         main.assertReturnString = "Assertion Result for dualstack IPV4 with MAC addresses\n"
@@ -791,7 +792,7 @@
                                               name='DUALSTACK',
                                               onosNode='0',
                                               host1=host1,
-                                              host2=host2)
+                                              host2=host2 )
 
         if installResult:
             testResult = main.intentFunction.testHostIntent( main,
@@ -802,12 +803,12 @@
                                               host2=host2,
                                               sw1='s5',
                                               sw2='s2',
-                                              expectedLink = 18)
+                                              expectedLink=18 )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
                                  onpass=main.assertReturnString,
-                                 onfail=main.assertReturnString)
+                                 onfail=main.assertReturnString )
 
         main.step( "DUALSTACK2: Add host intents between h1 and h11" )
         main.assertReturnString = "Assertion Result for dualstack2 host intent\n"
@@ -819,7 +820,7 @@
                                               name='DUALSTACK2',
                                               onosNode='0',
                                               host1=host1,
-                                              host2=host2)
+                                              host2=host2 )
 
         if installResult:
             testResult = main.intentFunction.testHostIntent( main,
@@ -830,14 +831,14 @@
                                               host2=host2,
                                               sw1='s5',
                                               sw2='s2',
-                                              expectedLink = 18)
+                                              expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
                                  onpass=main.assertReturnString,
-                                 onfail=main.assertReturnString)
+                                 onfail=main.assertReturnString )
 
         main.step( "1HOP: Add host intents between h1 and h3" )
         main.assertReturnString = "Assertion Result for 1HOP for IPV4 same switch\n"
@@ -849,7 +850,7 @@
                                               name='1HOP',
                                               onosNode='0',
                                               host1=host1,
-                                              host2=host2)
+                                              host2=host2 )
 
         if installResult:
             testResult = main.intentFunction.testHostIntent( main,
@@ -860,14 +861,14 @@
                                               host2=host2,
                                               sw1='s5',
                                               sw2='s2',
-                                              expectedLink = 18)
+                                              expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
                                  onpass=main.assertReturnString,
-                                 onfail=main.assertReturnString)
+                                 onfail=main.assertReturnString )
 
         main.step( "VLAN1: Add vlan host intents between h4 and h12" )
         main.assertReturnString = "Assertion Result vlan IPV4\n"
@@ -879,7 +880,7 @@
                                               name='VLAN1',
                                               onosNode='0',
                                               host1=host1,
-                                              host2=host2)
+                                              host2=host2 )
 
         if installResult:
             testResult = main.intentFunction.testHostIntent( main,
@@ -890,14 +891,14 @@
                                               host2=host2,
                                               sw1='s5',
                                               sw2='s2',
-                                              expectedLink = 18)
+                                              expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
                                  onpass=main.assertReturnString,
-                                 onfail=main.assertReturnString)
+                                 onfail=main.assertReturnString )
 
         main.step( "VLAN2: Add vlan host intents between h4 and h13" )
         main.assertReturnString = "Assertion Result vlan IPV4\n"
@@ -909,7 +910,7 @@
                                               name='VLAN2',
                                               onosNode='0',
                                               host1=host1,
-                                              host2=host2)
+                                              host2=host2 )
 
         if installResult:
             testResult = main.intentFunction.testHostIntent( main,
@@ -920,14 +921,14 @@
                                               host2=host2,
                                               sw1='s5',
                                               sw2='s2',
-                                              expectedLink = 18)
+                                              expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
                                  onpass=main.assertReturnString,
-                                 onfail=main.assertReturnString)
+                                 onfail=main.assertReturnString )
 
         main.step( "Encapsulation: Add host intents between h1 and h9" )
         main.assertReturnString = "Assertion Result for VLAN Encapsulated host intent\n"
@@ -950,16 +951,16 @@
                                               host2=host2,
                                               sw1='s5',
                                               sw2='s2',
-                                              expectedLink = 18)
+                                              expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
                                  onpass=main.assertReturnString,
-                                 onfail=main.assertReturnString)
+                                 onfail=main.assertReturnString )
 
-        main.step( "Confirm that ONOS leadership is unchanged")
+        main.step( "Confirm that ONOS leadership is unchanged" )
         intentLeadersNew = main.CLIs[ 0 ].leaderCandidates()
         main.intentFunction.checkLeaderChange( intentLeadersOld,
                                                 intentLeadersNew )
@@ -967,7 +968,7 @@
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
                                  onpass="ONOS Leaders Unchanged",
-                                 onfail="ONOS Leader Mismatch")
+                                 onfail="ONOS Leader Mismatch" )
 
         main.intentFunction.report( main )
 
@@ -1014,8 +1015,8 @@
         try:
             assert main.numSwitch
         except AssertionError:
-            main.log.error( "Place the total number of switch topology in \
-                             main.numSwitch" )
+            main.log.error( "Place the total number of switch topology in " +\
+                             main.numSwitch )
             main.initialized = main.FALSE
             main.skipCase()
 
@@ -1057,7 +1058,7 @@
                                          recipients=recipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
@@ -1093,7 +1094,7 @@
                                          recipients=recipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
@@ -1127,7 +1128,7 @@
                                          recipients=recipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
@@ -1172,7 +1173,7 @@
                                          sw1="s5",
                                          sw2="s2",
                                          expectedLink=18,
-                                         useTCP=True)
+                                         useTCP=True )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
@@ -1238,7 +1239,7 @@
                                          recipients=recipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
@@ -1261,7 +1262,7 @@
                                        main,
                                        name="VLAN",
                                        senders=senders,
-                                       recipients=recipients)
+                                       recipients=recipients )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
@@ -1272,7 +1273,7 @@
                                          recipients=recipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
@@ -1294,7 +1295,7 @@
                                        name="VLAN2",
                                        senders=senders,
                                        recipients=recipients,
-                                       setVlan=200)
+                                       setVlan=200 )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
@@ -1305,7 +1306,7 @@
                                          recipients=recipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
@@ -1338,7 +1339,7 @@
                                          recipients=recipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
@@ -1373,7 +1374,7 @@
                                          recipients=recipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
@@ -1422,8 +1423,8 @@
         try:
             assert main.numSwitch
         except AssertionError:
-            main.log.error( "Place the total number of switch topology in \
-                             main.numSwitch" )
+            main.log.error( "Place the total number of switch topology in "+ \
+                             main.numSwitch )
             main.initialized = main.FALSE
             main.skipCase()
 
@@ -1458,7 +1459,7 @@
                                          senders=senders,
                                          recipients=recipients,
                                          sw1="s5",
-                                         sw2="s2")
+                                         sw2="s2" )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
@@ -1471,7 +1472,7 @@
                                          badRecipients=badRecipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
@@ -1500,7 +1501,7 @@
                                          recipients=recipients,
                                          ethType="IPV4",
                                          sw1="s5",
-                                         sw2="s2")
+                                         sw2="s2" )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
@@ -1513,7 +1514,7 @@
                                          badRecipients=badRecipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
@@ -1542,7 +1543,7 @@
                                          recipients=recipients,
                                          ethType="IPV4",
                                          sw1="s5",
-                                         sw2="s2")
+                                         sw2="s2" )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
@@ -1555,7 +1556,7 @@
                                          badRecipients=badRecipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
@@ -1583,7 +1584,7 @@
                                          senders=senders,
                                          recipients=recipients,
                                          sw1="s5",
-                                         sw2="s2")
+                                         sw2="s2" )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
@@ -1596,7 +1597,7 @@
                                          badRecipients=badRecipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
@@ -1625,7 +1626,7 @@
                                          recipients=recipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         setVlan=100)
+                                         setVlan=100 )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
@@ -1638,7 +1639,7 @@
                                          badRecipients=badRecipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
@@ -1680,7 +1681,7 @@
                                          badRecipients=badRecipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
@@ -1729,8 +1730,8 @@
         try:
             assert main.numSwitch
         except AssertionError:
-            main.log.error( "Place the total number of switch topology in \
-                             main.numSwitch" )
+            main.log.error( "Place the total number of switch topology in "+\
+                             main.numSwitch )
             main.initialized = main.FALSE
             main.skipCase()
 
@@ -1807,7 +1808,7 @@
                                          recipients=recipients,
                                          ethType="IPV4",
                                          sw1="s5",
-                                         sw2="s2")
+                                         sw2="s2" )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
@@ -1820,7 +1821,7 @@
                                          badRecipients=badRecipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
@@ -1849,7 +1850,7 @@
                                          recipients=recipients,
                                          ethType="IPV4",
                                          sw1="s5",
-                                         sw2="s2")
+                                         sw2="s2" )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
@@ -1862,7 +1863,7 @@
                                          badRecipients=badRecipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
@@ -1890,7 +1891,7 @@
                                          senders=senders,
                                          recipients=recipients,
                                          sw1="s5",
-                                         sw2="s2")
+                                         sw2="s2" )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
@@ -1903,7 +1904,7 @@
                                          badRecipients=badRecipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
@@ -1933,7 +1934,7 @@
                                          recipients=recipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         setVlan=100)
+                                         setVlan=100 )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
@@ -1946,7 +1947,7 @@
                                          badRecipients=badRecipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
         else:
             main.CLIs[ 0 ].removeAllIntents( purge=True )
 
@@ -2023,15 +2024,15 @@
         try:
             assert main.numSwitch
         except AssertionError:
-            main.log.error( "Place the total number of switch topology in \
-                             main.numSwitch" )
+            main.log.error( "Place the total number of switch topology in "+\
+                             main.numSwitch )
             main.initialized = main.FALSE
             main.skipCase()
         main.case( "Test host mobility with host intents " )
         main.step( "Testing host mobility by moving h1 from s5 to s6" )
         h1PreMove = main.hostsData[ "h1" ][ "location" ][ 0:19 ]
 
-        main.log.info( "Moving h1 from s5 to s6")
+        main.log.info( "Moving h1 from s5 to s6" )
         main.Mininet1.moveHost( "h1","s5","s6" )
 
         # Send discovery ping from moved host
@@ -2112,8 +2113,8 @@
         try:
             assert main.numSwitch
         except AssertionError:
-            main.log.error( "Place the total number of switch topology in \
-                             main.numSwitch" )
+            main.log.error( "Place the total number of switch topology in "+\
+                             main.numSwitch )
             main.initialized = main.FALSE
             main.skipCase()
         main.case( "Test Multi to Single End Point Failure" )
@@ -2238,7 +2239,7 @@
                                          senders=senders,
                                          recipients=recipients,
                                          sw1="s5",
-                                         sw2="s2")
+                                         sw2="s2" )
 
         if installResult:
             testResult = main.intentFunction.testEndPointFail(
@@ -2288,7 +2289,7 @@
                                          recipients=recipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         partial=True)
+                                         partial=True )
 
         if installResult:
             testResult = main.intentFunction.testEndPointFail(
diff --git a/TestON/tests/FUNC/FUNCintent/dependencies/FuncIntentFunction.py b/TestON/tests/FUNC/FUNCintent/dependencies/FuncIntentFunction.py
index 89695a2..0e563be 100755
--- a/TestON/tests/FUNC/FUNCintent/dependencies/FuncIntentFunction.py
+++ b/TestON/tests/FUNC/FUNCintent/dependencies/FuncIntentFunction.py
@@ -83,7 +83,7 @@
                                                         vlanId=vlanId,
                                                         setVlan=setVlan,
                                                         encap=encap )
-    except (KeyError, TypeError):
+    except( KeyError, TypeError ):
         errorMsg = "There was a problem loading the hosts data."
         if intentId:
             errorMsg += "  There was a problem installing host to host intent."
@@ -113,7 +113,7 @@
                     onosNode=0,
                     sw1="s5",
                     sw2="s2",
-                    expectedLink=0):
+                    expectedLink=0 ):
     """
     Test a Host Intent
 
@@ -184,7 +184,7 @@
         vlanId = host1.get( "vlan" )
 
         testResult = main.TRUE
-    except (KeyError, TypeError):
+    except( KeyError, TypeError ):
         main.log.error( "There was a problem loading the hosts data." )
         return main.FALSE
 
@@ -400,7 +400,7 @@
                                             vlanId=vlanId,
                                             setVlan=setVlan,
                                             encap=encap )
-    except (KeyError, TypeError):
+    except( KeyError, TypeError ):
         errorMsg = "There was a problem loading the hosts data."
         if intentId:
             errorMsg += "  There was a problem installing Point to Point intent."
@@ -597,7 +597,7 @@
     checkFlowsState( main )
 
     # Run iperf to both host
-    iperfTemp = main.Mininet1.iperftcp( host1,host2,10 )
+    iperfTemp = main.Mininet1.iperftcp( host1, host2 ,10 )
     iperfResult = iperfResult and iperfTemp
     if iperfTemp:
         main.assertReturnString += 'Initial Iperf Passed\n'
@@ -627,7 +627,7 @@
             main.assertReturnString += 'Link Down Topology State Failed\n'
 
         # Run iperf to both host
-        iperfTemp = main.Mininet1.iperftcp( host1,host2,10 )
+        iperfTemp = main.Mininet1.iperftcp( host1, host2, 10 )
         iperfResult = iperfResult and iperfTemp
         if iperfTemp:
             main.assertReturnString += 'Link Down Iperf Passed\n'
@@ -671,7 +671,7 @@
             main.assertReturnString += 'Link Up Topology State Failed\n'
 
         # Run iperf to both host
-        iperfTemp = main.Mininet1.iperftcp( host1,host2,10 )
+        iperfTemp = main.Mininet1.iperftcp( host1, host2, 10 )
         iperfResult = iperfResult and iperfTemp
         if iperfTemp:
             main.assertReturnString += 'Link Up Iperf Passed\n'
@@ -810,7 +810,7 @@
                                             setVlan=setVlan,
                                             partial=partial,
                                             encap=encap )
-    except (KeyError, TypeError):
+    except( KeyError, TypeError ):
         errorMsg = "There was a problem loading the hosts data."
         if intentId:
             errorMsg += "  There was a problem installing Singlepoint to Multipoint intent."
@@ -936,7 +936,7 @@
                                             setVlan=setVlan,
                                             partial=partial,
                                             encap=encap )
-    except (KeyError, TypeError):
+    except( KeyError, TypeError ):
         errorMsg = "There was a problem loading the hosts data."
         if intentId:
             errorMsg += "  There was a problem installing Multipoint to Singlepoint intent."
@@ -974,7 +974,7 @@
                      sw1="s5",
                      sw2="s2",
                      expectedLink=0,
-                     useTCP=False):
+                     useTCP=False ):
     """
     Test a Point Intent
 
@@ -1053,7 +1053,7 @@
                 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
                 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
         vlanId = senders[ 0 ].get( "vlan" )
-    except (KeyError, TypeError):
+    except( KeyError, TypeError ):
         main.log.error( "There was a problem loading the hosts data." )
         return main.FALSE
 
@@ -1239,7 +1239,7 @@
                 main.log.warn( "Device not given for recipient {0}. Loading from " +\
                                 main.hostData.format( recipient.get( "name" ) ) )
                 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
-    except (KeyError, TypeError):
+    except( KeyError, TypeError ):
         main.log.error( "There was a problem loading the hosts data." )
         return main.FALSE
 
@@ -1577,7 +1577,7 @@
             return main.FALSE
 
     if hostFails:
-        main.log.error( "List of failed ONOS Nodes:" + ', '.join(map(str, hostFails )) )
+        main.log.error( "List of failed ONOS Nodes:" + ', '.join( map( str, hostFails ) ) )
         return main.FALSE
     else:
         return main.TRUE
@@ -1591,7 +1591,7 @@
     if not hosts:
         hosts = main.scapyHosts
     for host in hosts:
-        pkt = 'Ether( src="{0}")/ARP( psrc="{1}")'.format( host.hostMac ,host.hostIp )
+        pkt = 'Ether( src="{0}")/ARP( psrc="{1}")'.format( host.hostMac, host.hostIp )
         # Send from the VLAN interface if there is one so ONOS discovers the VLAN correctly
         iface = None
         for interface in host.getIfList():
@@ -1628,7 +1628,7 @@
         main.log.error( "ValueError while populating hostsData" )
         return main.FALSE
     except KeyError:
-        main.log.error( "KeyError while populating hostsData")
+        main.log.error( "KeyError while populating hostsData" )
         return main.FALSE
     except IndexError:
         main.log.error( "IndexError while populating hostsData" )
@@ -1696,7 +1696,7 @@
     checkFlowsResult = main.CLIs[ 0 ].checkFlowsState( isPENDING=False )
     return checkFlowsResult
 
-def link( main, sw1, sw2, option):
+def link( main, sw1, sw2, option ):
 
     # link down
     main.log.info( itemName + ": Bring link " + option + "between " +
@@ -1861,7 +1861,7 @@
     try:
         leaders1 = json.loads( leaders1 )
         leaders2 = json.loads( leaders2 )
-    except ( AttributeError, TypeError):
+    except( AttributeError, TypeError ):
         main.log.exception( self.name + ": Object not as expected" )
         return main.FALSE
     except Exception:
diff --git a/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.params b/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.params
index 4b3af6a..7e8b105 100644
--- a/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.params
+++ b/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.params
@@ -20,8 +20,7 @@
     # 4000 - Test multi to single point intents
     # 5000 - Test host mobility
 
-    <testcases>1,[2,10,12,13,15,16,1000,2000,5000,18,19]*2,[2,10,12,13,15,16,17,1000,2000,5000,18,19]*2,[2,11,12,13,15,16,1000,2000,5000,18,19]*2,[2,11,12,13,15,16,17,1000,2000,5000,18,19]*2</testcases>
-
+    <testcases>1,[2,10,12,13,15,16,1000,2000,3000,5000,18,19]*2,[2,10,12,13,15,16,17,1000,2000,3000,5000,18,19]*2,[2,11,12,13,15,16,1000,2000,3000,5000,18,19]*2,[2,11,12,13,15,16,17,1000,2000,3000,5000,18,19]*2</testcases>
     <SCALE>
         <size>1,3,1,3,1,3,1,3</size>
     </SCALE>
@@ -66,6 +65,7 @@
     <SDNIP>
         <tcpProto>6</tcpProto>
         <icmpProto>1</icmpProto>
+        <ipPrototype>6</ipPrototype>
         <srcPort>5001</srcPort>
         <dstPort>5001</dstPort>
     </SDNIP>
diff --git a/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.py b/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.py
index 26dabed..7a9d295 100644
--- a/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.py
+++ b/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.py
@@ -65,8 +65,8 @@
             main.numLinks = int( main.params[ 'MININET' ][ 'links' ] )
             main.cellData = {} # for creating cell file
             main.hostsData = {}
+            main.RESTs = []
             main.CLIs = []
-            main.CLIs2 = []
             main.ONOSip = []
             main.scapyHostNames = main.params[ 'SCAPY' ][ 'HOSTNAMES' ].split( ',' )
             main.scapyHosts = []  # List of scapy hosts for iterating
@@ -79,14 +79,14 @@
             # Assigning ONOS cli handles to a list
             try:
                 for i in range( 1,  main.maxNodes + 1 ):
-                    main.CLIs.append( getattr( main, 'ONOSrest' + str( i ) ) )
-                    main.CLIs2.append( getattr( main, 'ONOScli' + str( i ) ) )
+                    main.RESTs.append( getattr( main, 'ONOSrest' + str( i ) ) )
+                    main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
             except AttributeError:
                 main.log.warn( "A " + str( main.maxNodes ) + " node cluster " +
                                "was defined in env variables, but only " +
-                               str( len( main.CLIs ) ) +
+                               str( len( main.RESTs ) ) +
                                " nodes were defined in the .topo file. " +
-                               "Using " + str( len( main.CLIs ) ) +
+                               "Using " + str( len( main.RESTs ) ) +
                                " nodes for the test." )
 
             # -- INIT SECTION, ONLY RUNS ONCE -- #
@@ -110,13 +110,13 @@
                                               main.topology,
                                               main.Mininet1.home + "custom/",
                                               direction="to" )
-            if main.CLIs and main.CLIs2:
+            if main.RESTs and main.CLIs:
                 stepResult = main.TRUE
             else:
                 main.log.error( "Did not properly created list of ONOS CLI handle" )
                 stepResult = main.FALSE
         except Exception as e:
-            main.log.exception(e)
+            main.log.exception( e )
             main.cleanup()
             main.exit()
 
@@ -263,7 +263,7 @@
         cliResult = main.TRUE
         for i in range( main.numCtrls ):
             cliResult = cliResult and \
-                        main.CLIs2[ i ].startOnosCli( main.ONOSip[ i ] )
+                        main.CLIs[ i ].startOnosCli( main.ONOSip[ i ] )
         stepResult = cliResult
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
@@ -405,7 +405,8 @@
                         deviceData = json.loads( devices[ controller ] )
                         portData = json.loads( ports[ controller ] )
                     except (TypeError,ValueError):
-                        main.log.error( "Could not load json: {0} or {1}".format( str( devices[ controller ] ), str( ports[ controller ] ) ) )
+                        main.log.error( "Could not load json: {0} or {1}".format( str( devices[ controller ] ),
+                                                                                  str( ports[ controller ] ) ) )
                         currentDevicesResult = main.FALSE
                     else:
                         currentDevicesResult = main.Mininet1.compareSwitches(
@@ -475,7 +476,7 @@
             Report errors/warnings/exceptions
         '''
         main.log.info( "Error report: \n" )
-        main.ONOSbench.logReport( globalONOSip[0],
+        main.ONOSbench.logReport( globalONOSip[ 0 ],
                 [ "INFO", "FOLLOWER", "WARN", "flow", "ERROR" , "Except" ],
                 "s" )
         #main.ONOSbench.logReport( globalONOSip[1], [ "INFO" ], "d" )
@@ -702,7 +703,7 @@
         main.step( "Balancing mastership of switches" )
 
         balanceResult = main.FALSE
-        balanceResult = utilities.retry( f=main.CLIs2[ 0 ].balanceMasters, retValue=main.FALSE, args=[] )
+        balanceResult = utilities.retry( f=main.CLIs[ 0 ].balanceMasters, retValue=main.FALSE, args=[] )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
@@ -725,7 +726,7 @@
 
         cmd = "org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator"
 
-        stepResult = main.CLIs2[ 0 ].setCfg( component=cmd,
+        stepResult = main.CLIs[ 0 ].setCfg( component=cmd,
                                             propName="useFlowObjectives", value="true" )
 
         utilities.assert_equals( expect=main.TRUE,
@@ -787,7 +788,7 @@
         scpResult = main.TRUE
         copyResult = main.TRUE
         for i in range( main.numCtrls ):
-            main.node = main.CLIs2[ i ]
+            main.node = main.CLIs[ i ]
             ip = main.ONOSip[ i ]
             main.node.ip_address = ip
             scpResult = scpResult and main.ONOSbench.scp( main.node ,
@@ -795,7 +796,8 @@
                                             "/tmp/karaf.log",
                                             direction="from" )
             copyResult = copyResult and main.ONOSbench.cpLogsToDir( "/tmp/karaf.log", main.logdir,
-                                                                    copyFileName=( "karaf.log.node{0}.cycle{1}".format( str( i + 1 ), str( main.cycle ) ) ) )
+                                                                    copyFileName=( "karaf.log.node{0}.cycle{1}".format(
+                                                                        str( i + 1 ), str( main.cycle ) ) ) )
             if scpResult and copyResult:
                 stepResult =  main.TRUE and stepResult
             else:
@@ -834,9 +836,9 @@
         # if you want to use the wrapper function
         assert main, "There is no main"
         try:
-            assert main.CLIs
+            assert main.RESTs
         except AssertionError:
-            main.log.error( "There is no main.CLIs, skipping test cases" )
+            main.log.error( "There is no main.RESTs, skipping test cases" )
             main.initialized = main.FALSE
             main.skipCase()
         try:
@@ -848,13 +850,13 @@
         try:
             assert main.numSwitch
         except AssertionError:
-            main.log.error( "Place the total number of switch topology in \
-                             main.numSwitch" )
+            main.log.error( "Place the total number of switch topology in "+\
+                             main.numSwitch )
             main.initialized = main.FALSE
             main.skipCase()
 
         # Save leader candidates
-        intentLeadersOld = main.CLIs2[ 0 ].leaderCandidates()
+        intentLeadersOld = main.CLIs[ 0 ].leaderCandidates()
 
         main.case( "Host Intents Test - " + str( main.numCtrls ) +
                    " NODE(S) - OF " + main.OFProtocol + " - Using " + main.flowCompiler )
@@ -886,7 +888,7 @@
                                               host2=host2,
                                               sw1='s5',
                                               sw2='s2',
-                                              expectedLink = 18 )
+                                              expectedLink=18 )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
@@ -896,7 +898,7 @@
         main.step( "DUALSTACK1: Add host intents between h3 and h11" )
         main.assertReturnString = "Assertion Result for dualstack IPV4 with MAC addresses\n"
         host1 = { "name":"h3", "id":"00:00:00:00:00:03/-1" }
-        host2 = { "name":"h11","id":"00:00:00:00:00:0B/-1"}
+        host2 = { "name":"h11","id":"00:00:00:00:00:0B/-1" }
         testResult = main.FALSE
         installResult = main.intentFunction.installHostIntent( main,
                                               name='DUALSTACK1',
@@ -913,12 +915,12 @@
                                               host2=host2,
                                               sw1='s5',
                                               sw2='s2',
-                                              expectedLink = 18 )
+                                              expectedLink=18 )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
                                  onpass=main.assertReturnString,
-                                 onfail=main.assertReturnString)
+                                 onfail=main.assertReturnString )
 
         main.step( "DUALSTACK2: Add host intents between h1 and h11" )
         main.assertReturnString = "Assertion Result for dualstack2 host intent\n"
@@ -940,7 +942,7 @@
                                               host2=host2,
                                               sw1='s5',
                                               sw2='s2',
-                                              expectedLink = 18 )
+                                              expectedLink=18 )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
@@ -967,7 +969,7 @@
                                               host2=host2,
                                               sw1='s5',
                                               sw2='s2',
-                                              expectedLink = 18 )
+                                              expectedLink=18 )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
@@ -994,7 +996,7 @@
                                               host2=host2,
                                               sw1='s5',
                                               sw2='s2',
-                                              expectedLink = 18 )
+                                              expectedLink=18 )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
@@ -1022,7 +1024,7 @@
         #                                       host2=host2,
         #                                       sw1='s5',
         #                                       sw2='s2',
-        #                                       expectedLink = 18 )
+        #                                       expectedLink=18 )
 
         # utilities.assert_equals( expect=main.TRUE,
         #                          actual=testResult,
@@ -1032,8 +1034,8 @@
         # Change the following to use the REST API when leader checking is
         # supported by it
 
-        main.step( "Confirm that ONOS leadership is unchanged")
-        intentLeadersNew = main.CLIs2[ 0 ].leaderCandidates()
+        main.step( "Confirm that ONOS leadership is unchanged" )
+        intentLeadersNew = main.CLIs[ 0 ].leaderCandidates()
         main.intentFunction.checkLeaderChange( intentLeadersOld,
                                                 intentLeadersNew )
 
@@ -1063,19 +1065,16 @@
                     - Ping hosts
                 - Remove intents
         """
-        import time
-        import json
-        import re
         if main.initialized == main.FALSE:
             main.log.error( "Test components did not start correctly, skipping further tests" )
             main.skipCase()
-        # Assert variables - These variable's name|format must be followed
-        # if you want to use the wrapper function
+            # Assert variables - These variable's name|format must be followed
+            # if you want to use the wrapper function
         assert main, "There is no main"
         try:
-            assert main.CLIs
+            assert main.RESTs
         except AssertionError:
-            main.log.error( "There is no main.CLIs, skipping test cases" )
+            main.log.error( "There is no main.RESTs, skipping test cases" )
             main.initialized = main.FALSE
             main.skipCase()
         try:
@@ -1087,37 +1086,37 @@
         try:
             assert main.numSwitch
         except AssertionError:
-            main.log.error( "Place the total number of switch topology in \
-                             main.numSwitch" )
+            main.log.error( "Place the total number of switch topology in "+\
+                             main.numSwitch )
             main.initialized = main.FALSE
             main.skipCase()
 
         main.case( "Point Intents Test - " + str( main.numCtrls ) +
-                   " NODE(S) - OF " + main.OFProtocol + " - Using " + main.flowCompiler )
-        main.caseExplanation = "This test case will test point to point" +\
-                               " intents using " + str( main.numCtrls ) +\
-                               " node(s) cluster;\n" +\
-                               "Different type of hosts will be tested in " +\
-                               "each step such as IPV4, Dual stack, VLAN etc" +\
-                               ";\nThe test will use OF " + main.OFProtocol +\
-                               " OVS running in Mininet and compile intents" +\
+                  " NODE(S) - OF " + main.OFProtocol + " - Using " + main.flowCompiler )
+        main.caseExplanation = "This test case will test point to point" + \
+                               " intents using " + str( main.numCtrls ) + \
+                               " node(s) cluster;\n" + \
+                               "Different type of hosts will be tested in " + \
+                               "each step such as IPV4, Dual stack, VLAN etc" + \
+                               ";\nThe test will use OF " + main.OFProtocol + \
+                               " OVS running in Mininet and compile intents" + \
                                " using " + main.flowCompiler
 
-        # No option point intents
+        # No option point intent
         main.step( "NOOPTION: Add point intents between h1 and h9" )
         main.assertReturnString = "Assertion Result for NOOPTION point intent\n"
         senders = [
-            { "name":"h1","device":"of:0000000000000005/1" }
+            { "name": "h1", "device": "of:0000000000000005/1" }
         ]
         recipients = [
-            { "name":"h9","device":"of:0000000000000006/1" }
+            { "name": "h9", "device": "of:0000000000000006/1" }
         ]
         testResult = main.FALSE
         installResult = main.intentFunction.installPointIntent(
-                                       main,
-                                       name="NOOPTION",
-                                       senders=senders,
-                                       recipients=recipients )
+            main,
+            name="NOOPTION",
+            senders=senders,
+            recipients=recipients )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
@@ -1128,7 +1127,7 @@
                                          recipients=recipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
@@ -1138,17 +1137,17 @@
         main.step( "IPV4: Add point intents between h1 and h9" )
         main.assertReturnString = "Assertion Result for IPV4 point intent\n"
         senders = [
-            { "name":"h1","device":"of:0000000000000005/1","mac":"00:00:00:00:00:01" }
+            { "name": "h1", "device": "of:0000000000000005/1", "mac": "00:00:00:00:00:01" }
         ]
         recipients = [
-            { "name":"h9","device":"of:0000000000000006/1","mac":"00:00:00:00:00:09" }
+            { "name": "h9", "device": "of:0000000000000006/1", "mac": "00:00:00:00:00:09" }
         ]
         installResult = main.intentFunction.installPointIntent(
-                                       main,
-                                       name="IPV4",
-                                       senders=senders,
-                                       recipients=recipients,
-                                       ethType="IPV4" )
+            main,
+            name="IPV4",
+            senders=senders,
+            recipients=recipients,
+            ethType="IPV4" )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
@@ -1159,26 +1158,27 @@
                                          recipients=recipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
                                  onpass=main.assertReturnString,
                                  onfail=main.assertReturnString )
+
         main.step( "IPV4_2: Add point intents between h1 and h9" )
         main.assertReturnString = "Assertion Result for IPV4 no mac address point intents\n"
         senders = [
-            { "name":"h1","device":"of:0000000000000005/1" }
+            { "name": "h1", "device": "of:0000000000000005/1" }
         ]
         recipients = [
-            { "name":"h9","device":"of:0000000000000006/1" }
+            { "name": "h9", "device": "of:0000000000000006/1" }
         ]
         installResult = main.intentFunction.installPointIntent(
-                                       main,
-                                       name="IPV4_2",
-                                       senders=senders,
-                                       recipients=recipients,
-                                       ethType="IPV4" )
+            main,
+            name="IPV4_2",
+            senders=senders,
+            recipients=recipients,
+            ethType="IPV4" )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
@@ -1189,7 +1189,7 @@
                                          recipients=recipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
@@ -1199,39 +1199,40 @@
         main.step( "SDNIP-ICMP: Add point intents between h1 and h9" )
         main.assertReturnString = "Assertion Result for SDNIP-ICMP IPV4 using TCP point intents\n"
         senders = [
-            { "name":"h1","device":"of:0000000000000005/1","mac":"00:00:00:00:00:01",
-              "ip":main.h1.hostIp }
+            { "name": "h1", "device": "of:0000000000000005/1", "mac": "00:00:00:00:00:01",
+              "ip": ( main.h1.hostIp + "/24" ) }
         ]
         recipients = [
-            { "name":"h9","device":"of:0000000000000006/1","mac":"00:00:00:00:00:09",
-              "ip":main.h9.hostIp }
+            { "name": "h9", "device": "of:0000000000000006/1", "mac": "00:00:00:00:00:09",
+              "ip": ( main.h9.hostIp + "/24" ) }
         ]
-        ipProto = main.params[ 'SDNIP' ][ 'icmpProto' ]
+        # ipProto = main.params['SDNIP']['icmpProto']
+        ipProto = main.params[ 'SDNIP' ][ 'ipPrototype' ]
         # Uneccessary, not including this in the selectors
-        tcpSrc = main.params[ 'SDNIP' ][ 'srcPort' ]
-        tcpDst = main.params[ 'SDNIP' ][ 'dstPort' ]
+        tcpSrc = main.params['SDNIP']['srcPort']
+        tcpDst = main.params['SDNIP']['dstPort']
 
         installResult = main.intentFunction.installPointIntent(
-                                       main,
-                                       name="SDNIP-ICMP",
-                                       senders=senders,
-                                       recipients=recipients,
-                                       ethType="IPV4",
-                                       ipProto=ipProto,
-                                       tcpSrc=tcpSrc,
-                                       tcpDst=tcpDst )
+            main,
+            name="SDNIP-ICMP",
+            senders=senders,
+            recipients=recipients,
+            ethType="IPV4",
+            ipProto=ipProto,
+            tcpSrc=tcpSrc,
+            tcpDst=tcpDst )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
-                                         main,
-                                         intentId=installResult,
-                                         name="SDNIP_ICMP",
-                                         senders=senders,
-                                         recipients=recipients,
-                                         sw1="s5",
-                                         sw2="s2",
-                                         expectedLink=18,
-                                         useTCP=True )
+                main,
+                intentId=installResult,
+                name="SDNIP_ICMP",
+                senders=senders,
+                recipients=recipients,
+                sw1="s5",
+                sw2="s2",
+                expectedLink=18,
+                useTCP=True )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
@@ -1240,60 +1241,60 @@
 
         main.step( "SDNIP-TCP: Add point intents between h1 and h9" )
         main.assertReturnString = "Assertion Result for SDNIP-TCP IPV4 using ICMP point intents\n"
-        mac1 = main.hostsData[ 'h1' ][ 'mac' ]
-        mac2 = main.hostsData[ 'h9' ][ 'mac' ]
-        ip1 = str( main.hostsData[ 'h1' ][ 'ipAddresses' ][ 0 ] ) + "/32"
-        ip2 = str( main.hostsData[ 'h9' ][ 'ipAddresses' ][ 0 ] ) + "/32"
-        ipProto = main.params[ 'SDNIP' ][ 'tcpProto' ]
-        tcp1 = main.params[ 'SDNIP' ][ 'srcPort' ]
-        tcp2 = main.params[ 'SDNIP' ][ 'dstPort' ]
+        mac1 = main.hostsData['h1']['mac']
+        mac2 = main.hostsData['h9']['mac']
+        ip1 = str(main.hostsData['h1']['ipAddresses'][0]) + "/32"
+        ip2 = str(main.hostsData['h9']['ipAddresses'][0]) + "/32"
+        ipProto = main.params['SDNIP']['tcpProto']
+        tcp1 = main.params['SDNIP']['srcPort']
+        tcp2 = main.params['SDNIP']['dstPort']
 
         stepResult = main.intentFunction.pointIntentTcp(
-                                           main,
-                                           name="SDNIP-TCP",
-                                           host1="h1",
-                                           host2="h9",
-                                           deviceId1="of:0000000000000005/1",
-                                           deviceId2="of:0000000000000006/1",
-                                           mac1=mac1,
-                                           mac2=mac2,
-                                           ethType="IPV4",
-                                           ipProto=ipProto,
-                                           ip1=ip1,
-                                           ip2=ip2,
-                                           tcp1=tcp1,
-                                           tcp2=tcp2 )
+            main,
+            name="SDNIP-TCP",
+            host1="h1",
+            host2="h9",
+            deviceId1="of:0000000000000005/1",
+            deviceId2="of:0000000000000006/1",
+            mac1=mac1,
+            mac2=mac2,
+            ethType="IPV4",
+            ipProto=ipProto,
+            ip1=ip1,
+            ip2=ip2,
+            tcp1=tcp1,
+            tcp2=tcp2 )
 
         utilities.assert_equals( expect=main.TRUE,
-                             actual=stepResult,
+                                 actual=stepResult,
                                  onpass=main.assertReturnString,
                                  onfail=main.assertReturnString )
 
         main.step( "DUALSTACK1: Add point intents between h3 and h11" )
         main.assertReturnString = "Assertion Result for Dualstack1 IPV4 with mac address point intents\n"
         senders = [
-            { "name":"h3","device":"of:0000000000000005/3","mac":"00:00:00:00:00:03" }
+            { "name": "h3", "device": "of:0000000000000005/3", "mac": "00:00:00:00:00:03" }
         ]
         recipients = [
-            { "name":"h11","device":"of:0000000000000006/3","mac":"00:00:00:00:00:0B" }
+            { "name": "h11", "device": "of:0000000000000006/3", "mac": "00:00:00:00:00:0B" }
         ]
         installResult = main.intentFunction.installPointIntent(
-                                       main,
-                                       name="DUALSTACK1",
-                                       senders=senders,
-                                       recipients=recipients,
-                                       ethType="IPV4" )
+            main,
+            name="DUALSTACK1",
+            senders=senders,
+            recipients=recipients,
+            ethType="IPV4" )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
-                                         main,
-                                         intentId=installResult,
-                                         name="DUALSTACK1",
-                                         senders=senders,
-                                         recipients=recipients,
-                                         sw1="s5",
-                                         sw2="s2",
-                                         expectedLink=18)
+                                        main,
+                                        intentId=installResult,
+                                        name="DUALSTACK1",
+                                        senders=senders,
+                                        recipients=recipients,
+                                        sw1="s5",
+                                        sw2="s2",
+                                        expectedLink=18 )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
@@ -1303,16 +1304,16 @@
         main.step( "VLAN: Add point intents between h5 and h21" )
         main.assertReturnString = "Assertion Result for VLAN IPV4 with mac address point intents\n"
         senders = [
-            { "name":"h5","device":"of:0000000000000005/5","mac":"00:00:00:00:00:05", "vlanId":"200" }
+            { "name": "h5", "device": "of:0000000000000005/5", "mac": "00:00:00:00:00:05", "vlanId": "200" }
         ]
         recipients = [
-            { "name":"h21","device":"of:0000000000000007/5","mac":"00:00:00:00:00:15", "vlanId":"200" }
+            { "name": "h21", "device": "of:0000000000000007/5", "mac": "00:00:00:00:00:15", "vlanId": "200" }
         ]
         installResult = main.intentFunction.installPointIntent(
-                                       main,
-                                       name="VLAN",
-                                       senders=senders,
-                                       recipients=recipients )
+            main,
+            name="VLAN",
+            senders=senders,
+            recipients=recipients )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
@@ -1323,7 +1324,7 @@
                                          recipients=recipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
@@ -1335,17 +1336,17 @@
         main.step( "1HOP: Add point intents between h1 and h3" )
         main.assertReturnString = "Assertion Result for 1HOP IPV4 with no mac address point intents\n"
         senders = [
-            { "name":"h1","device":"of:0000000000000005/1","mac":"00:00:00:00:00:01" }
+            { "name": "h1", "device": "of:0000000000000005/1", "mac": "00:00:00:00:00:01" }
         ]
         recipients = [
-            { "name":"h3","device":"of:0000000000000005/3","mac":"00:00:00:00:00:03" }
+            { "name": "h3", "device": "of:0000000000000005/3", "mac": "00:00:00:00:00:03" }
         ]
         installResult = main.intentFunction.installPointIntent(
-                                       main,
-                                       name="1HOP IPV4",
-                                       senders=senders,
-                                       recipients=recipients,
-                                       ethType="IPV4" )
+            main,
+            name="1HOP IPV4",
+            senders=senders,
+            recipients=recipients,
+            ethType="IPV4" )
 
         if installResult:
             testResult = main.intentFunction.testPointIntent(
@@ -1356,7 +1357,7 @@
                                          recipients=recipients,
                                          sw1="s5",
                                          sw2="s2",
-                                         expectedLink=18)
+                                         expectedLink=18 )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=testResult,
@@ -1365,6 +1366,7 @@
 
         main.intentFunction.report( main )
 
+
     def CASE3000( self, main ):
         """
             Add single point to multi point intents
@@ -1384,127 +1386,229 @@
                     - Ping hosts
                 - Remove intents
         """
+        if main.initialized == main.FALSE:
+            main.log.error( "Test components did not start correctly, skipping further tests" )
+            main.skipCase()
         assert main, "There is no main"
-        assert main.CLIs, "There is no main.CLIs"
-        assert main.Mininet1, "Mininet handle should be named Mininet1"
-        assert main.numSwitch, "Placed the total number of switch topology in \
-                                main.numSwitch"
 
-        main.case( "Single To Multi Point Intents Test - " +
-                   str( main.numCtrls ) + " NODE(S) - OF " + main.OFProtocol + " - Using " + main.flowCompiler )
-        main.caseExplanation = "This test case will test single point to" +\
-                               " multi point intents using " +\
-                               str( main.numCtrls ) + " node(s) cluster;\n" +\
-                               "Different type of hosts will be tested in " +\
-                               "each step such as IPV4, Dual stack, VLAN etc" +\
-                               ";\nThe test will use OF " + main.OFProtocol +\
-                               " OVS running in Mininet and compile intents" +\
+        try:
+            assert main.CLIs, "There is no main.CLIs, skipping test cases"
+            assert main.Mininet1, "Mininet handle should be named Mininet1, skipping test cases"
+            assert main.numSwitch, "Place the total number of switch topology in main.numSwitch"
+        except AssertionError:
+            main.initialized = main.FALSE
+            main.skipCase()
+
+        main.testName = "Single to Multi Point Intents"
+        main.case( main.testName + " Test - " + str( main.numCtrls ) +
+                  " NODE(S) - OF " + main.OFProtocol + " - Using " + main.flowCompiler )
+        main.caseExplanation = "This test case will test single point to" + \
+                               " multi point intents using " + \
+                               str( main.numCtrls ) + " node(s) cluster;\n" + \
+                               "Different type of hosts will be tested in " + \
+                               "each step such as IPV4, Dual stack, VLAN etc" + \
+                               ";\nThe test will use OF " + main.OFProtocol + \
+                               " OVS running in Mininet and compile intents" + \
                                " using " + main.flowCompiler
 
-        main.step( "NOOPTION: Add single point to multi point intents" )
-        stepResult = main.TRUE
-        hostNames = [ 'h8', 'h16', 'h24' ]
-        devices = [ 'of:0000000000000005/8', 'of:0000000000000006/8', \
-                    'of:0000000000000007/8' ]
-        macs = [ '00:00:00:00:00:08', '00:00:00:00:00:10', '00:00:00:00:00:18' ]
-        stepResult = main.intentFunction.singleToMultiIntent(
-                                         main,
-                                         name="NOOPTION",
-                                         hostNames=hostNames,
-                                         devices=devices,
-                                         sw1="s5",
-                                         sw2="s2",
-                                         expectedLink=18 )
+        main.step( "NOOPTION: Install and test single point to multi point intents" )
+        main.assertReturnString = "Assertion results for IPV4 single to multi point intent with no options set\n"
+        senders = [
+            { "name": "h8", "device": "of:0000000000000005/8" }
+        ]
+        recipients = [
+            { "name": "h16", "device": "of:0000000000000006/8" },
+            { "name": "h24", "device": "of:0000000000000007/8" }
+        ]
+        badSenders = [ { "name": "h9" } ]  # Senders that are not in the intent
+        badRecipients = [ { "name": "h17" } ]  # Recipients that are not in the intent
+        testResult = main.FALSE
+        installResult = main.intentFunction.installSingleToMultiIntent(
+            main,
+            name="NOOPTION",
+            senders=senders,
+            recipients=recipients )
+
+        if installResult:
+            testResult = main.intentFunction.testPointIntent(
+                main,
+                intentId=installResult,
+                name="NOOPTION",
+                senders=senders,
+                recipients=recipients,
+                badSenders=badSenders,
+                badRecipients=badRecipients,
+                sw1="s5",
+                sw2="s2",
+                expectedLink=18 )
+        else:
+            main.CLIs[ 0 ].removeAllIntents( purge=True )
 
         utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="NOOPTION: Successfully added single "
-                                        + " point to multi point intents" +
-                                        " with no match action",
-                                 onfail="NOOPTION: Failed to add single point"
-                                        + " point to multi point intents" +
-                                        " with no match action" )
+                                 actual=testResult,
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
-        main.step( "IPV4: Add single point to multi point intents" )
-        stepResult = main.TRUE
-        stepResult = main.intentFunction.singleToMultiIntent(
-                                         main,
-                                         name="IPV4",
-                                         hostNames=hostNames,
-                                         devices=devices,
-                                         ports=None,
-                                         ethType="IPV4",
-                                         macs=macs,
-                                         bandwidth="",
-                                         lambdaAlloc=False,
-                                         ipProto="",
-                                         ipAddresses="",
-                                         tcp="",
-                                         sw1="s5",
-                                         sw2="s2",
-                                         expectedLink=18 )
+        main.step("IPV4: Install and test single point to multi point intents")
+        main.assertReturnString = "Assertion results for IPV4 single to multi point intent " \
+                                  "with IPV4 type and MAC addresses\n"
+        senders = [
+            {"name": "h8", "device": "of:0000000000000005/8", "mac": "00:00:00:00:00:08"}
+        ]
+        recipients = [
+            {"name": "h16", "device": "of:0000000000000006/8", "mac": "00:00:00:00:00:10"},
+            {"name": "h24", "device": "of:0000000000000007/8", "mac": "00:00:00:00:00:18"}
+        ]
+        badSenders = [{"name": "h9"}]  # Senders that are not in the intent
+        badRecipients = [{"name": "h17"}]  # Recipients that are not in the intent
+        installResult = main.intentFunction.installSingleToMultiIntent(
+            main,
+            name="IPV4",
+            senders=senders,
+            recipients=recipients,
+            ethType="IPV4")
+
+        if installResult:
+            testResult = main.intentFunction.testPointIntent(
+                main,
+                intentId=installResult,
+                name="IPV4",
+                senders=senders,
+                recipients=recipients,
+                badSenders=badSenders,
+                badRecipients=badRecipients,
+                sw1="s5",
+                sw2="s2",
+                expectedLink=18 )
+        else:
+            main.CLIs[ 0 ].removeAllIntents( purge=True )
 
         utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="IPV4: Successfully added single "
-                                        + " point to multi point intents" +
-                                        " with IPV4 type and MAC addresses",
-                                 onfail="IPV4: Failed to add single point"
-                                        + " point to multi point intents" +
-                                        " with IPV4 type and MAC addresses" )
+                                 actual=testResult,
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         main.step( "IPV4_2: Add single point to multi point intents" )
-        stepResult = main.TRUE
-        hostNames = [ 'h8', 'h16', 'h24' ]
-        stepResult = main.intentFunction.singleToMultiIntent(
-                                         main,
-                                         name="IPV4",
-                                         hostNames=hostNames,
-                                         ethType="IPV4",
-                                         lambdaAlloc=False )
+        main.assertReturnString = "Assertion results for IPV4 single to multi point intent " \
+                                  "with IPV4 type and no MAC addresses\n"
+        senders = [
+            { "name": "h8", "device": "of:0000000000000005/8" }
+        ]
+        recipients = [
+            { "name": "h16", "device": "of:0000000000000006/8" },
+            { "name": "h24", "device": "of:0000000000000007/8" }
+        ]
+        badSenders = [ { "name": "h9" } ]  # Senders that are not in the intent
+        badRecipients = [ { "name": "h17" } ]  # Recipients that are not in the intent
+        installResult = main.intentFunction.installSingleToMultiIntent(
+            main,
+            name="IPV4_2",
+            senders=senders,
+            recipients=recipients,
+            ethType="IPV4" )
+
+        if installResult:
+            testResult = main.intentFunction.testPointIntent(
+                main,
+                intentId=installResult,
+                name="IPV4_2",
+                senders=senders,
+                recipients=recipients,
+                badSenders=badSenders,
+                badRecipients=badRecipients,
+                sw1="s5",
+                sw2="s2",
+                expectedLink=18 )
+        else:
+            main.CLIs[ 0 ].removeAllIntents( purge=True )
 
         utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="IPV4_2: Successfully added single "
-                                        + " point to multi point intents" +
-                                        " with IPV4 type and no MAC addresses",
-                                 onfail="IPV4_2: Failed to add single point"
-                                        + " point to multi point intents" +
-                                        " with IPV4 type and no MAC addresses" )
+                                 actual=testResult,
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         main.step( "VLAN: Add single point to multi point intents" )
-        stepResult = main.TRUE
-        hostNames = [ 'h4', 'h12', 'h20' ]
-        devices = [ 'of:0000000000000005/4', 'of:0000000000000006/4', \
-                    'of:0000000000000007/4' ]
-        macs = [ '00:00:00:00:00:04', '00:00:00:00:00:0C', '00:00:00:00:00:14' ]
-        stepResult = main.intentFunction.singleToMultiIntent(
-                                         main,
-                                         name="VLAN",
-                                         hostNames=hostNames,
-                                         devices=devices,
-                                         ports=None,
-                                         ethType="IPV4",
-                                         macs=macs,
-                                         bandwidth="",
-                                         lambdaAlloc=False,
-                                         ipProto="",
-                                         ipAddresses="",
-                                         tcp="",
-                                         sw1="s5",
-                                         sw2="s2",
-                                         expectedLink=18 )
+        main.assertReturnString = "Assertion results for IPV4 single to multi point intent with IPV4 type " \
+                                  "and MAC addresses in the same VLAN\n"
+        senders = [
+            { "name": "h4", "device": "of:0000000000000005/4", "mac": "00:00:00:00:00:04", "vlan": "100" }
+        ]
+        recipients = [
+            { "name": "h12", "device": "of:0000000000000006/4", "mac": "00:00:00:00:00:0C", "vlan": "100" },
+            { "name": "h20", "device": "of:0000000000000007/4", "mac": "00:00:00:00:00:14", "vlan": "100" }
+        ]
+        badSenders = [ { "name": "h13" } ]  # Senders that are not in the intent
+        badRecipients = [ { "name": "h21" } ]  # Recipients that are not in the intent
+        installResult = main.intentFunction.installSingleToMultiIntent(
+            main,
+            name="VLAN",
+            senders=senders,
+            recipients=recipients,
+            sw1="s5",
+            sw2="s2" )
+
+        if installResult:
+            testResult = main.intentFunction.testPointIntent(
+                main,
+                intentId=installResult,
+                name="VLAN",
+                senders=senders,
+                recipients=recipients,
+                badSenders=badSenders,
+                badRecipients=badRecipients,
+                sw1="s5",
+                sw2="s2",
+                expectedLink=18 )
+        else:
+            main.CLIs[ 0 ].removeAllIntents()
 
         utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="VLAN: Successfully added single "
-                                        + " point to multi point intents" +
-                                        " with IPV4 type and MAC addresses" +
-                                        " in the same VLAN",
-                                 onfail="VLAN: Failed to add single point"
-                                        + " point to multi point intents" +
-                                        " with IPV4 type and MAC addresses" +
-                                        " in the same VLAN")
+                                 actual=testResult,
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
+
+        main.step( "VLAN: Add single point to multi point intents" )
+        main.assertReturnString = "Assertion results for single to multi point intent with VLAN treatment\n"
+        senders = [
+            { "name": "h5", "vlan": "200" }
+        ]
+        recipients = [
+            { "name": "h12", "device": "of:0000000000000006/4", "mac": "00:00:00:00:00:0C", "vlan": "100" },
+            { "name": "h20", "device": "of:0000000000000007/4", "mac": "00:00:00:00:00:14", "vlan": "100" }
+        ]
+        badSenders = [ { "name": "h13" } ]  # Senders that are not in the intent
+        badRecipients = [ { "name": "h21" } ]  # Recipients that are not in the intent
+        testResult = main.FALSE
+        installResult = main.intentFunction.installSingleToMultiIntent(
+            main,
+            name="VLAN2",
+            senders=senders,
+            recipients=recipients,
+            sw1="s5",
+            sw2="s2" )
+            #setVlan=100 )
+
+        if installResult:
+            testResult = main.intentFunction.testPointIntent(
+                main,
+                intentId=installResult,
+                name="VLAN2",
+                senders=senders,
+                recipients=recipients,
+                badSenders=badSenders,
+                badRecipients=badRecipients,
+                sw1="s5",
+                sw2="s2",
+                expectedLink=18 )
+        else:
+            main.CLIs[ 0 ].removeAllIntents()
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=testResult,
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
+
+        main.intentFunction.report( main )
 
     def CASE4000( self, main ):
         """
@@ -1657,9 +1761,9 @@
         # if you want to use the wrapper function
         assert main, "There is no main"
         try:
-            assert main.CLIs
+            assert main.RESTs
         except AssertionError:
-            main.log.error( "There is no main.CLIs, skipping test cases" )
+            main.log.error( "There is no main.RESTs, skipping test cases" )
             main.initialized = main.FALSE
             main.skipCase()
         try:
@@ -1671,16 +1775,16 @@
         try:
             assert main.numSwitch
         except AssertionError:
-            main.log.error( "Place the total number of switch topology in \
-                             main.numSwitch" )
+            main.log.error( "Place the total number of switch topology in " +\
+                             main.numSwitch )
             main.initialized = main.FALSE
             main.skipCase()
         main.case( "Test host mobility with host intents " )
         main.step( "Testing host mobility by moving h1 from s5 to s6" )
         h1PreMove = main.hostsData[ "h1" ][ "location" ][ 0:19 ]
 
-        main.log.info( "Moving h1 from s5 to s6")
-        main.Mininet1.moveHost( "h1","s5","s6" )
+        main.log.info( "Moving h1 from s5 to s6" )
+        main.Mininet1.moveHost( "h1", "s5", "s6" )
 
         # Send discovery ping from moved host
         # Moving the host brings down the default interfaces and creates a new one.
@@ -1712,7 +1816,7 @@
                                               name='IPV4 Mobility IPV4',
                                               onosNode='0',
                                               host1=host1,
-                                              host2=host2)
+                                              host2=host2 )
         if installResult:
             testResult = main.intentFunction.testHostIntent( main,
                                                   name='Host Mobility IPV4',
@@ -1729,5 +1833,4 @@
                                  onpass=main.assertReturnString,
                                  onfail=main.assertReturnString )
 
-        main.intentFunction.report( main )
-
+        main.intentFunction.report( main )
\ No newline at end of file
diff --git a/TestON/tests/FUNC/FUNCintentRest/dependencies/FuncIntentFunction.py b/TestON/tests/FUNC/FUNCintentRest/dependencies/FuncIntentFunction.py
index 92d100f..088d38d 100755
--- a/TestON/tests/FUNC/FUNCintentRest/dependencies/FuncIntentFunction.py
+++ b/TestON/tests/FUNC/FUNCintentRest/dependencies/FuncIntentFunction.py
@@ -23,7 +23,7 @@
                        ipAddresses="",
                        tcp="",
                        sw1="",
-                       sw2=""):
+                       sw2="" ):
     """
     Installs a Host Intent
 
@@ -46,7 +46,7 @@
         host2 - Dictionary for host2
             { "name":"h16", "id":"of:0000000000000006/8" }
     Optional:
-        onosNode - ONOS node to install the intents in main.CLIs[ ]
+        onosNode - ONOS node to install the intents in main.RESTs[ ]
                    0 by default so that it will always use the first
                    ONOS node
         ethType - Ethernet type eg. IPV4, IPV6
@@ -80,14 +80,14 @@
         # Adding host intents
         main.log.info( itemName + ": Adding host intents" )
 
-        intent1 = main.CLIs[ onosNode ].addHostIntent( hostIdOne=host1.get( "id" ),
+        intent1 = main.RESTs[ onosNode ].addHostIntent( hostIdOne=host1.get( "id" ),
                                                        hostIdTwo=host2.get( "id" ),
                                                        vlanId=vlanId )
 
         # Get all intents ID in the system, time delay right after intents are added
         time.sleep( main.addIntentSleep )
-        intentsId = main.CLIs[ 0 ].getIntentsId()
-    except (KeyError, TypeError):
+        intentsId = main.RESTs[ 0 ].getIntentsId()
+    except( KeyError, TypeError ):
         errorMsg = "There was a problem loading the hosts data."
         if intentsId:
             errorMsg += "  There was a problem installing host to host intent."
@@ -116,7 +116,7 @@
                     onosNode=0,
                     sw1="s5",
                     sw2="s2",
-                    expectedLink=0):
+                    expectedLink=0 ):
     """
     Test a Host Intent
 
@@ -150,7 +150,7 @@
         host2 - Dictionary for host2
             { "name":"h16", "id":"of:0000000000000006/8" }
     Optional:
-        onosNode - ONOS node to install the intents in main.CLIs[ ]
+        onosNode - ONOS node to install the intents in main.RESTs[ ]
                    0 by default so that it will always use the first
                    ONOS node
         sw1 - First switch to bring down & up for rerouting purpose
@@ -185,7 +185,7 @@
         senderNames = [ host1.get( "name" ), host2.get( "name" ) ]
         recipientNames = [ host1.get( "name" ), host2.get( "name" ) ]
         vlanId = host1.get( "vlanId" )
-    except ( KeyError, TypeError ):
+    except( KeyError, TypeError ):
         main.log.error( "There was a problem loading the hosts data." )
         return main.FALSE
 
@@ -309,7 +309,7 @@
                         ipSrc="",
                         ipDst="",
                         tcpSrc="",
-                        tcpDst=""):
+                        tcpDst="" ):
     """
     Installs a Single to Single Point Intent
 
@@ -331,7 +331,7 @@
         recipients - List of host dictionaries i.e.
             [ { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" } ]
     Optional:
-        onosNode - ONOS node to install the intents in main.CLIs[ ]
+        onosNode - ONOS node to install the intents in main.RESTs[ ]
                    0 by default so that it will always use the first
                    ONOS node
         ethType - Ethernet type eg. IPV4, IPV6
@@ -384,7 +384,7 @@
         ipSrc = senders[ 0 ].get( "ip" )
         ipDst = recipients[ 0 ].get( "ip" )
 
-        intent1 = main.CLIs[ onosNode ].addPointIntent(
+        intent1 = main.RESTs[ onosNode ].addPointIntent(
                                             ingressDevice=ingressDevice,
                                             egressDevice=egressDevice,
                                             ingressPort=portIngress,
@@ -402,8 +402,8 @@
                                             vlanId=vlanId )
 
         time.sleep( main.addIntentSleep )
-        intentsId = main.CLIs[ 0 ].getIntentsId()
-    except (KeyError, TypeError):
+        intentsId = main.RESTs[ 0 ].getIntentsId()
+    except( KeyError, TypeError ):
         errorMsg = "There was a problem loading the hosts data."
         if intentsId:
             errorMsg += "  There was a problem installing Point to Point intent."
@@ -476,7 +476,7 @@
         recipients - List of host dictionaries i.e.
             { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" }
     Optional:
-        onosNode - ONOS node to install the intents in main.CLIs[ ]
+        onosNode - ONOS node to install the intents in main.RESTs[ ]
                    0 by default so that it will always use the first
                    ONOS node
         ethType - Ethernet type eg. IPV4, IPV6
@@ -521,7 +521,7 @@
                 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
                 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
         vlanId=senders[ 0 ].get( "vlanId" )
-    except (KeyError, TypeError):
+    except( KeyError, TypeError ):
         main.log.error( "There was a problem loading the hosts data." )
         return main.FALSE
 
@@ -697,7 +697,7 @@
         host1 - Name of first host
         host2 - Name of second host
     Optional:
-        onosNode - ONOS node to install the intents in main.CLIs[ ]
+        onosNode - ONOS node to install the intents in main.RESTs[ ]
                    0 by default so that it will always use the first
                    ONOS node
         deviceId1 - ONOS device id of the first switch, the same as the
@@ -745,7 +745,7 @@
 
     # Adding bidirectional point  intents
     main.log.info( itemName + ": Adding point intents" )
-    intent1 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
+    intent1 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
                                                     egressDevice=deviceId2,
                                                     ingressPort=port1,
                                                     egressPort=port2,
@@ -760,7 +760,7 @@
                                                     tcpSrc=tcp1,
                                                     tcpDst="" )
 
-    intent2 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
+    intent2 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
                                                     egressDevice=deviceId1,
                                                     ingressPort=port2,
                                                     egressPort=port1,
@@ -775,7 +775,7 @@
                                                     tcpSrc=tcp2,
                                                     tcpDst="" )
 
-    intent3 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
+    intent3 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
                                                     egressDevice=deviceId2,
                                                     ingressPort=port1,
                                                     egressPort=port2,
@@ -790,7 +790,7 @@
                                                     tcpSrc="",
                                                     tcpDst=tcp2 )
 
-    intent4 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
+    intent4 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
                                                     egressDevice=deviceId1,
                                                     ingressPort=port2,
                                                     egressPort=port1,
@@ -807,7 +807,7 @@
 
     # Get all intents ID in the system, time delay right after intents are added
     time.sleep( main.addIntentSleep )
-    intentsId = main.CLIs[ 0 ].getIntentsId()
+    intentsId = main.RESTs[ 0 ].getIntentsId()
     # Check intents state
     time.sleep( main.checkIntentSleep )
     intentResult = checkIntentState( main, intentsId )
@@ -886,22 +886,21 @@
 
     return stepResult
 
-def singleToMultiIntent( main,
-                         name,
-                         hostNames,
-                         onosNode=0,
-                         devices="",
-                         ports=None,
-                         ethType="",
-                         macs=None,
-                         bandwidth="",
-                         lambdaAlloc=False,
-                         ipProto="",
-                         ipAddresses="",
-                         tcp="",
-                         sw1="",
-                         sw2="",
-                         expectedLink=0 ):
+
+def installSingleToMultiIntent( main,
+                                name,
+                                senders,
+                                recipients,
+                                onosNode=0,
+                                ethType="",
+                                bandwidth="",
+                                lambdaAlloc=False,
+                                ipProto="",
+                                ipAddresses="",
+                                tcp="",
+                                sw1="",
+                                sw2="",
+                                partial=False ):
     """
         Verify Single to Multi Point intents
         NOTE:If main.hostsData is not defined, variables data should be passed
@@ -934,7 +933,7 @@
             name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
             hostNames - List of host names
         Optional:
-            onosNode - ONOS node to install the intents in main.CLIs[ ]
+            onosNode - ONOS node to install the intents in main.RESTs[ ]
                        0 by default so that it will always use the first
                        ONOS node
             devices - List of device ids in the same order as the hosts
@@ -958,176 +957,85 @@
     """
 
     assert main, "There is no main variable"
-    assert hostNames, "You must specify hosts"
-    assert devices or main.hostsData, "You must specify devices"
+    assert senders, "You must specify a sender"
+    assert recipients, "You must specify a recipient"
+    # Assert devices or main.hostsData, "You must specify devices"
 
-    global itemName
+    global itemName  # The name of this run. Used for logs.
     itemName = name
-    tempHostsData = {}
-    intentsId = []
     onosNode = int( onosNode )
 
-    macsDict = {}
-    ipDict = {}
-    if hostNames and devices:
-        if len( hostNames ) != len( devices ):
-            main.log.debug( "hosts and devices does not have the same length" )
-            #print "len hostNames = ", len( hostNames )
-            #print "len devices = ", len( devices )
-            return main.FALSE
-        if ports:
-            if len( ports ) != len( devices ):
-                main.log.error( "Ports and devices does " +
-                                "not have the same length" )
-                #print "len devices = ", len( devices )
-                #print "len ports = ", len( ports )
-                return main.FALSE
-        else:
-            main.log.info( "Device Ports are not specified" )
-        if macs:
-            for i in range( len( devices ) ):
-                macsDict[ devices[ i ] ] = macs[ i ]
-
-    elif hostNames and not devices and main.hostsData:
-        devices = []
-        main.log.info( "singleToMultiIntent function is using main.hostsData" )
-        for host in hostNames:
-               devices.append( main.hostsData.get( host ).get( 'location' ) )
-               macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
-                           main.hostsData.get( host ).get( 'mac' )
-               ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
-                           main.hostsData.get( host ).get( 'ipAddresses' )
-        #print main.hostsData
-
-    #print 'host names = ', hostNames
-    #print 'devices = ', devices
-    #print "macsDict = ", macsDict
-
-    pingResult = main.TRUE
-    intentResult = main.TRUE
-    removeIntentResult = main.TRUE
-    flowResult = main.TRUE
-    topoResult = main.TRUE
-    linkDownResult = main.TRUE
-    linkUpResult = main.TRUE
-
-    devicesCopy = copy.copy( devices )
-    if ports:
-        portsCopy = copy.copy( ports )
     main.log.info( itemName + ": Adding single point to multi point intents" )
 
-    # Check flows count in each node
-    checkFlowsCount( main )
+    try:
+        for sender in senders:
+            if not sender.get( "device" ):
+                main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
+                sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
 
-    # Adding bidirectional point  intents
-    for i in range( len( devices ) ):
-        ingressDevice = devicesCopy[ i ]
-        egressDeviceList = copy.copy( devicesCopy )
-        egressDeviceList.remove( ingressDevice )
-        if ports:
-            portIngress = portsCopy[ i ]
-            portEgressList = copy.copy( portsCopy )
-            del portEgressList[ i ]
-        else:
-            portIngress = ""
-            portEgressList = None
-        if not macsDict:
-            srcMac = ""
-        else:
-            srcMac = macsDict[ ingressDevice ]
-            if srcMac == None:
-                main.log.debug( "There is no MAC in device - " + ingressDevice )
-                srcMac = ""
+        for recipient in recipients:
+            if not recipient.get( "device" ):
+                main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
+                recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
+        vlanId = senders[ 0 ].get( "vlanId" )
 
-        intentsId.append(
-                        main.CLIs[ onosNode ].addSinglepointToMultipointIntent(
+        ingressDevice = senders[ 0 ].get( "device" )
+        egressDeviceList = [ x.get( "device" ) for x in recipients if x.get( "device" ) ]
+
+        portIngress = senders[ 0 ].get( "port", "" )
+        portEgressList = [ x.get( "port" ) for x in recipients if x.get( "port" ) ]
+        if not portEgressList:
+            portEgressList = []
+
+        main.log.debug( ingressDevice )
+        main.log.debug( egressDeviceList )
+
+        srcMac = senders[ 0 ].get( "mac" )
+        dstMac = []
+        for r in recipients:
+            mac = r.get( "mac" )
+            dstMac.append( mac )
+
+        ipSrc = senders[ 0 ].get( "ip" )
+        ipDst = []
+        for r in recipients:
+            ip = r.get( "ip" )
+            ipDst.append( ip )
+
+        # Adding point intent
+        intentId = main.RESTs[ onosNode ].addSinglepointToMultipointIntent(
                                             ingressDevice=ingressDevice,
                                             egressDeviceList=egressDeviceList,
                                             portIngress=portIngress,
                                             portEgressList=portEgressList,
                                             ethType=ethType,
                                             ethSrc=srcMac,
+                                            #ethDst=dstMac, #Isn't working because of ONOS itself
                                             bandwidth=bandwidth,
                                             lambdaAlloc=lambdaAlloc,
                                             ipProto=ipProto,
-                                            ipSrc="",
-                                            ipDst="",
+                                            ipSrc=ipSrc,
+                                            ipDst=ipDst,
                                             tcpSrc="",
-                                            tcpDst="" ) )
+                                            tcpDst="",
+                                            vlanId=vlanId,
+                                            partial=partial )
 
-    # Wait some time for the flow to go through when using multi instance
-    pingResult = pingallHosts( main, hostNames )
+        time.sleep( main.addIntentSleep )
+        intentsId = main.RESTs[ 0 ].getIntentsId()
+    except ( KeyError, TypeError ):
+        errorMsg = "There was a problem loading the hosts data."
+        if intentId:
+            errorMsg += "  There was a problem installing Singlepoint to Multipoint intent."
+        main.log.error( errorMsg )
+        return main.FALSE
 
     # Check intents state
-    time.sleep( main.checkIntentSleep )
-    intentResult = checkIntentState( main, intentsId )
-
-    # Check intents state again if first check fails...
-    if not intentResult:
-        intentResult = checkIntentState( main, intentsId )
-
-    # Check flows count in each node
-    checkFlowsCount( main )
-    # Verify flows
-    checkFlowsState( main )
-
-    pingResult = pingResult and pingallHosts( main, hostNames )
-
-    # Test rerouting if these variables exist
-    if sw1 and sw2 and expectedLink:
-        # link down
-        linkDownResult = link( main, sw1, sw2, "down" )
-        intentResult = intentResult and checkIntentState( main, intentsId )
-
-        # Check flows count in each node
-        checkFlowsCount( main )
-        # Verify flows
-        checkFlowsState( main )
-
-        # Check OnosTopology
-        topoResult = checkTopology( main, expectedLink )
-
-        # Ping hosts
-        pingResult = pingResult and pingallHosts( main, hostNames )
-
-        intentResult = checkIntentState( main, intentsId )
-
-        # Checks ONOS state in link down
-        if linkDownResult and topoResult and pingResult and intentResult:
-            main.log.info( itemName + ": Successfully brought link down" )
-        else:
-            main.log.error( itemName + ": Failed to bring link down" )
-
-        # link up
-        linkUpResult = link( main, sw1, sw2, "up" )
-        time.sleep( main.rerouteSleep )
-
-        # Check flows count in each node
-        checkFlowsCount( main )
-        # Verify flows
-        checkFlowsState( main )
-
-        # Check OnosTopology
-        topoResult = checkTopology( main, main.numLinks )
-
-        # Ping hosts
-        pingResult = pingResult and pingallHosts( main, hostNames )
-
-        intentResult = checkIntentState( main, intentsId )
-
-        # Checks ONOS state in link up
-        if linkUpResult and topoResult and pingResult and intentResult:
-            main.log.info( itemName + ": Successfully brought link back up" )
-        else:
-            main.log.error( itemName + ": Failed to bring link back up" )
-
-    # Remove all intents
-    removeIntentResult = removeAllIntents( main, intentsId )
-
-    stepResult = pingResult and linkDownResult and linkUpResult \
-                 and intentResult and removeIntentResult
-
-    return stepResult
+    if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentsId ), sleep=main.checkIntentSleep ):
+        return intentsId
+    else:
+        main.log.error( "Single to Multi Intent did not install correctly" )
+        return main.FALSE
 
 def multiToSingleIntent( main,
                          name,
@@ -1176,7 +1084,7 @@
             name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
             hostNames - List of host names
         Optional:
-            onosNode - ONOS node to install the intents in main.CLIs[ ]
+            onosNode - ONOS node to install the intents in main.RESTs[ ]
                        0 by default so that it will always use the first
                        ONOS node
             devices - List of device ids in the same order as the hosts
@@ -1281,7 +1189,7 @@
                 dstMac = ""
 
         intentsId.append(
-                        main.CLIs[ onosNode ].addMultipointToSinglepointIntent(
+                        main.RESTs[ onosNode ].addMultipointToSinglepointIntent(
                                             ingressDeviceList=ingressDeviceList,
                                             egressDevice=egressDevice,
                                             portIngressList=portIngressList,
@@ -1388,7 +1296,7 @@
     appCheck = main.TRUE
     getDataResult = main.TRUE
     main.log.info( "Activating reactive forwarding app " )
-    activateResult = main.CLIs[ 0 ].activateApp( "org.onosproject.fwd" )
+    activateResult = main.RESTs[ 0 ].activateApp( "org.onosproject.fwd" )
     if not activateResult:
         main.log.error( "Something went wrong installing fwd app" )
     time.sleep( main.fwdSleep )
@@ -1398,7 +1306,7 @@
         for i in xrange( len( hostList ) ):
             main.Mininet1.pingallHosts( hostList[ i ] )
 
-    hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
+    hostsJson = json.loads( main.RESTs[ 0 ].hosts() )
     hosts = main.Mininet1.getHosts().keys()
     # TODO: Make better use of new getHosts function
     for host in hosts:
@@ -1415,7 +1323,7 @@
                 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
 
     main.log.info( "Deactivating reactive forwarding app " )
-    deactivateResult = main.CLIs[ 0 ].deactivateApp( "org.onosproject.fwd" )
+    deactivateResult = main.RESTs[ 0 ].deactivateApp( "org.onosproject.fwd" )
     if activateResult and deactivateResult and main.hostsData:
         main.log.info( "Successfully used fwd app to discover hosts " )
         getDataResult = main.TRUE
@@ -1433,7 +1341,7 @@
     main.log.info( itemName + ": Checking ONOS topology " )
 
     for i in range( main.numCtrls ):
-        statusResult = main.CLIs[ i ].checkStatus( main.numSwitch,
+        statusResult = main.RESTs[ i ].checkStatus( main.numSwitch,
                                                    expectedLink )\
                        and statusResult
     if not statusResult:
@@ -1454,7 +1362,7 @@
     main.log.info( itemName + ": Checking intents state" )
     # First check of intents
     for i in range( main.numCtrls ):
-        tempResult = main.CLIs[ i ].checkIntentState( intentsId=intentsId )
+        tempResult = main.RESTs[ i ].checkIntentState( intentsId=intentsId )
         results.append( tempResult )
 
     expectedState = [ 'INSTALLED', 'INSTALLING' ]
@@ -1469,7 +1377,7 @@
         # Second check of intents since some of the intents may be in
         # INSTALLING state, they should be in INSTALLED at this time
         for i in range( main.numCtrls ):
-            tempResult = main.CLIs[ i ].checkIntentState( intentsId=intentsId )
+            tempResult = main.RESTs[ i ].checkIntentState( intentsId=intentsId )
             results.append( tempResult )
         if all( result == main.TRUE for result in results ):
             main.log.info( itemName + ": Intents are installed correctly" )
@@ -1483,7 +1391,7 @@
 def checkFlowsState( main ):
 
     main.log.info( itemName + ": Check flows state" )
-    checkFlowsResult = main.CLIs[ 0 ].checkFlowsState()
+    checkFlowsResult = main.RESTs[ 0 ].checkFlowsState()
     return checkFlowsResult
 
 def link( main, sw1, sw2, option):
@@ -1502,7 +1410,7 @@
     onosSummary = []
     removeIntentResult = main.TRUE
     # Remove intents
-    removeIntentResult = main.CLIs[ 0 ].removeAllIntents( )
+    removeIntentResult = main.RESTs[ 0 ].removeAllIntents( )
 
     if removeIntentResult:
         main.log.info( itemName + ": There are no more intents remaining, " +
@@ -1518,7 +1426,7 @@
     flowsCount = []
     main.log.info( itemName + ": Checking flows count in each ONOS node" )
     for i in range( main.numCtrls ):
-        flowsCount.append( len( json.loads( main.CLIs[ i ].flows() ) ) )
+        flowsCount.append( len( json.loads( main.RESTs[ i ].flows() ) ) )
 
     if flowsCount:
         if all( flows==flowsCount[ 0 ] for flows in flowsCount ):
@@ -1595,7 +1503,7 @@
             return main.FALSE
 
     if hostFails:
-        main.log.error( "List of failed ONOS Nodes:" + ', '.join(map(str, hostFails )) )
+        main.log.error( "List of failed ONOS Nodes:" + ', '.join( map( str, hostFails ) ) )
         return main.FALSE
     else:
         return main.TRUE
@@ -1606,7 +1514,7 @@
     """
     import json
     try:
-        hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
+        hostsJson = json.loads( main.RESTs[ 0 ].hosts() )
         hosts = main.Mininet1.getHosts().keys()
         # TODO: Make better use of new getHosts function
         for host in hosts:
@@ -1650,7 +1558,7 @@
     if not packetFilter:
         packetFilter = 'ether host {}'
     if useTCP:
-        packetFilter += ' ip proto \\tcp tcp port {}'.format(main.params[ 'SDNIP' ][ 'dstPort' ])
+        packetFilter += ' ip proto \\tcp tcp port {}'.format( main.params[ 'SDNIP' ][ 'dstPort' ] )
     if expectFailure:
         timeout = 1
     else:
@@ -1766,7 +1674,7 @@
                                 "flow",
                                 "ERROR",
                                 "Except" ],
-                              "s" )
+                                "s" )
 
     main.log.info( "ERROR report: \n" )
     for i in range( main.numCtrls ):
@@ -1792,7 +1700,7 @@
     """
     import time
     main.log.info( "Getting current flow durations" )
-    flowsJson1 = main.CLIs[ 0 ].flows()
+    flowsJson1 = main.RESTs[ 0 ].flows()
     try:
         flowsJson1 = json.loads( flowsJson1 )
     except ValueError:
@@ -1806,7 +1714,7 @@
     main.log.info( "Sleeping for {} seconds".format( main.flowDurationSleep ) )
     time.sleep( main.flowDurationSleep )
     main.log.info( "Getting new flow durations" )
-    flowsJson2 = main.CLIs[ 0 ].flows()
+    flowsJson2 = main.RESTs[ 0 ].flows()
     try:
         flowsJson2 = json.loads( flowsJson2 )
     except ValueError:
@@ -1817,9 +1725,9 @@
             waitFlowLife.append( flow[ 'life' ] )
     main.log.info( "Determining whether flows where overwritten" )
     if len( flowLife ) == len( waitFlowLife ):
-        for i in range( len( flowLife) ):
+        for i in range( len( flowLife ) ):
             if waitFlowLife[ i ] - flowLife[ i ] < main.flowDurationSleep:
                 return main.FALSE
     else:
         return main.FALSE
-    return main.TRUE
\ No newline at end of file
+    return main.TRUE
diff --git a/TestON/tests/SCPF/SCPFportLat/SCPFportLat.params b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.params
index 0a81dc6..4fc830f 100644
--- a/TestON/tests/SCPF/SCPFportLat/SCPFportLat.params
+++ b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.params
@@ -1,5 +1,5 @@
 <PARAMS>
-    <testcases>1,2,1,2,1,2,1,2</testcases>
+    <testcases>0,1,2,1,2,1,2,1,2</testcases>
 
     <SCALE>1,3,5,7</SCALE>
     <max>7</max>
@@ -9,76 +9,56 @@
         <cellApps>drivers,metrics,openflow</cellApps>
     </ENV>
 
-    <DEPENDENCY>
-        <path>/tests/SCPF/SCPFportLat/dependencies/</path>
-        <topology>topo-perf-2sw.py</topology>
-    </DEPENDENCY>
-
-    <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>OCN</ip1>
     </MN>
 
-    <BENCH>
-        <ip>localhost</ip>
-    </BENCH>
+    <DEPENDENCY>
+        <path>/tests/SCPF/SCPFportLat/dependencies/</path>
+        <topology>topo-perf-2sw.py</topology>
+        <function>portFunc</function>
+    </DEPENDENCY>
+
+    <GIT>
+        <gitPull>off</gitPull>
+        <gitBranch>master</gitBranch>
+    </GIT>
 
     <TSHARK>
+        <tsharkReusltPath>/tmp/tshark_portStatus</tsharkReusltPath>
         <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>
+    <SLEEP>
+        <startup>5</startup>
+        <measure>5</measure>
+        <mininet>5</mininet>
+    </SLEEP>
+
+    <TIMEOUT>
+        <timeout>60</timeout>
+    </TIMEOUT>
 
     <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>
+        <debug>True</debug>
+        #Number of iterations to ignore initially
+        <warmUp>5</warmUp>
 
         #Number of times to iterate each case
-        <numIter>25</numIter>
-        <numSwitch>2</numSwitch>
-        #Number of iterations to ignore initially
-        <iterIgnore>5</iterIgnore>
+        <sampleSize>20</sampleSize>
 
-        <portUpThreshold>0,5000</portUpThreshold>
-        <portDownThreshold>0,1000</portDownThreshold>
+        <maxProcessTime>5000</maxProcessTime>
 
-        <tabletFile>tablets_3node.json</tabletFile>
+        <interface>s1-eth1</interface>
+        <device>s1</device>
    </TEST>
 
-    <DB>
-        <postToDB>no</postToDB>
-        <portEventResultPath>/tmp/portEventResultDb</portEventResultPath>
-    </DB>
+    <DATABASE>
+        <dbName>/tmp/portEventResultDb</dbName>
+    </DATABASE>
 
     <JSON>
         <deviceTimestamp>topologyDeviceEventTimestamp</deviceTimestamp>
diff --git a/TestON/tests/SCPF/SCPFportLat/SCPFportLat.py b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.py
index e6f62ef..29d71e5 100644
--- a/TestON/tests/SCPF/SCPFportLat/SCPFportLat.py
+++ b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.py
@@ -1,558 +1,319 @@
-# CASE1 starts number of nodes specified in param file
-#
-# cameron@onlab.us
+'''
+    SCPFportLat test
+    Test latency for port status change
+    Up & Down:
+    PortStatus --- Device --- Link --- Graph
 
+    yunpeng@onlab.us
+'''
 class SCPFportLat:
-
     def __init__( self ):
         self.default = ''
 
-    def CASE1( self, main ):
-        import sys
-        import re
+    def CASE0( self, main ):
         import os
-        import time
+        import imp
+        '''
+        - GIT
+        - BUILDING ONOS
+            Pull specific ONOS branch, then Build ONOS ono ONOS Bench.
+            This step is usually skipped. Because in a Jenkins driven automated
+            test env. We want Jenkins jobs to pull&build for flexibility to handle
+            different versions of ONOS.
+        - Construct tests variables
+        '''
+        gitPull = main.params['GIT']['gitPull']
+        gitBranch = main.params['GIT']['gitBranch']
 
-        global init
-        try:
-            if type(init) is not bool:
-                init = Fals
-        except NameError:
-            init = False
+        main.case( "Pull onos branch and build onos on Teststation." )
 
-        #Load values from params file
-        main.testOnDirectory = os.path.dirname(os.getcwd())
-        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']
-        main.topology = main.params['DEPENDENCY']['topology']
+        if gitPull == 'True':
+            main.step( "Git Checkout ONOS branch: " + gitBranch )
+            stepResult = main.ONOSbench.gitCheckout( branch=gitBranch )
+            utilities.assert_equals(expect=main.TRUE,
+                                    actual=stepResult,
+                                    onpass="Successfully checkout onos branch.",
+                                    onfail="Failed to checkout onos branch. Exiting test...")
+            if not stepResult: main.exit()
+
+            main.step( "Git Pull on ONOS branch:" + gitBranch )
+            stepResult = main.ONOSbench.gitPull()
+            utilities.assert_equals(expect=main.TRUE,
+                                    actual=stepResult,
+                                    onpass="Successfully pull onos. ",
+                                    onfail="Failed to pull onos. Exiting test ...")
+            if not stepResult: main.exit()
+
+            main.step( "Building ONOS branch: " + gitBranch )
+            stepResult = main.ONOSbench.cleanInstall( skipTest=True )
+            utilities.assert_equals(expect=main.TRUE,
+                                    actual=stepResult,
+                                    onpass="Successfully build onos.",
+                                    onfail="Failed to build onos. Exiting test...")
+            if not stepResult: main.exit()
+
+        else:
+            main.log.warn( "Skipped pulling onos and Skipped building ONOS" )
+
+        main.testOnDirectory = os.path.dirname( os.getcwd() )
+        main.MN1Ip = main.params['MN']['ip1']
         main.dependencyPath = main.testOnDirectory + \
                               main.params['DEPENDENCY']['path']
-        testONpath = re.sub( "(tests)$", "bin", main.testDir )  # TestON/bin
+        main.dependencyFunc = main.params['DEPENDENCY']['function']
+        main.topoName = main.params['DEPENDENCY']['topology']
+        main.cellName = main.params['ENV']['cellName']
+        main.Apps = main.params['ENV']['cellApps']
+        main.scale = (main.params['SCALE']).split(",")
+        main.ofportStatus = main.params['TSHARK']['ofpPortStatus']
+        main.tsharkResultPath = main.params['TSHARK']['tsharkReusltPath']
+        main.sampleSize = int( main.params['TEST']['sampleSize'] )
+        main.warmUp = int( main.params['TEST']['warmUp'] )
+        main.maxProcessTime = int( main.params['TEST']['maxProcessTime'])
+        main.dbFileName = main.params['DATABASE']['dbName']
+        main.startUpSleep = int( main.params['SLEEP']['startup'] )
+        main.measurementSleep = int( main.params['SLEEP']['measure'] )
+        main.maxScale = int( main.params['max'] )
+        main.interface = main.params['TEST']['interface']
+        main.timeout = int( main.params['TIMEOUT']['timeout'] )
+        main.MNSleep = int( main.params['SLEEP']['mininet'])
+        main.device = main.params['TEST']['device']
+        main.debug = main.params['TEST']['debug']
 
-        # -- 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 = []
+        if main.debug == "True":
+            main.debug = True
+        else:
+            main.debug = False
 
-            timeToPost = time.strftime('%Y-%m-%d %H:%M:%S')
-            runNum = time.strftime('%d%H%M%S')
-            ONOSIp = main.ONOSbench.getOnosIps()
+        main.log.info( "Create Database file " + main.dbFileName )
+        resultsDB = open( main.dbFileName, "w+" )
+        resultsDB.close()
 
-            #Assigning ONOS cli handles to a list
-            for i in range(main.maxNodes):
-                CLIs.append( getattr( main, 'ONOS' + str(i+1) + 'cli'))
+        main.portFunc = imp.load_source(main.dependencyFunc,
+                                       main.dependencyPath +
+                                       main.dependencyFunc +
+                                       ".py")
 
-            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)
+    def CASE1( self, main ):
+        # Clean up test environment and set up
+        import time
+        main.log.info( "Get ONOS cluster IP" )
+        print( main.scale )
+        main.numCtrls = int( main.scale.pop(0) )
+        main.ONOSip = []
+        main.maxNumBatch = 0
+        main.AllONOSip = main.ONOSbench.getOnosIps()
+        for i in range( main.numCtrls ):
+            main.ONOSip.append( main.AllONOSip[i] )
+        main.log.info( main.ONOSip )
+        main.CLIs = []
+        main.log.info( "Creating list of ONOS cli handles" )
+        for i in range( main.numCtrls ):
+            main.CLIs.append( getattr(main, 'ONOS%scli' % (i + 1)) )
 
-            clusterCount = 0
-            ONOSIp = main.ONOSbench.getOnosIps()
+        if not main.CLIs:
+            main.log.error( "Failed to create the list of ONOS cli handles" )
+            main.cleanup()
+            main.exit()
 
-            scale = (main.params[ 'SCALE' ]).split(",")
-            clusterCount = int(scale[0])
+        main.commit = main.ONOSbench.getVersion( report=True )
+        main.commit = main.commit.split(" ")[1]
+        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")
 
-            #mvn clean install, for debugging set param 'skipCleanInstall' to yes to speed up test
-            if skipMvn != "off":
-                mvnResult = main.ONOSbench.cleanInstall()
+        for i in range( main.numCtrls ):
+            main.ONOSbench.onosDie( main.ONOSip[i] )
 
-            #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.log.info( "NODE COUNT = %s" % main.numCtrls )
+        main.ONOSbench.createCellFile(main.ONOSbench.ip_address,
+                                      main.cellName,
+                                      main.MN1Ip,
+                                      main.Apps,
+                                      main.ONOSip)
+        main.step( "Apply cell to environment" )
+        cellResult = main.ONOSbench.setCell( main.cellName )
+        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( "verify cells" )
-        verifyCellResult = main.ONOSbench.verifyCell()
+        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('Starting mininet topology ')
-        copyResult = main.ONOSbench.copyMininetFile(main.topology,
-                                                    main.dependencyPath,
-                                                    main.Mininet1.user_name,
-                                                    main.Mininet1.ip_address)
+        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
+        time.sleep(2)
+        main.step( "Start ONOS CLI on all nodes" )
+        cliResult = main.TRUE
+        main.step( " Start ONOS cli using thread " )
+        startCliResult = main.TRUE
+        pool = []
+        main.threadID = 0
+        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 )
+
+        main.log.info( "Configure apps" )
+        main.CLIs[0].setCfg("org.onosproject.net.topology.impl.DefaultTopologyProvider",
+                            "maxEvents 1")
+        main.CLIs[0].setCfg("org.onosproject.net.topology.impl.DefaultTopologyProvider",
+                            "maxBatchMs 0")
+        main.CLIs[0].setCfg("org.onosproject.net.topology.impl.DefaultTopologyProvider",
+                            "maxIdleMs 0")
+        time.sleep(1)
+        main.log.info( "Copy topology file to Mininet" )
+        main.ONOSbench.copyMininetFile(main.topoName,
+                                       main.dependencyPath,
+                                       main.Mininet1.user_name,
+                                       main.Mininet1.ip_address)
+        main.log.info( "Stop Mininet..." )
+        main.Mininet1.stopNet()
+        time.sleep( main.MNSleep )
+        main.log.info( "Start new mininet topology" )
         main.Mininet1.startNet()
+        main.log.info( "Assign switch to controller to ONOS node 1" )
+        time.sleep(1)
+        main.Mininet1.assignSwController( sw='s1', ip=main.ONOSip[0] )
+        main.Mininet1.assignSwController( sw='s2', ip=main.ONOSip[0] )
 
-        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 )
+        time.sleep(2)
 
     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)
+        # dictionary for each node and each timestamps
+        resultDict = {'up' : {}, 'down' : {}}
+        for d in resultDict:
+            for i in range( 1, main.numCtrls + 1 ):
+                resultDict[d][ 'node' + str(i) ] = {}
+                resultDict[d][ 'node' + str(i) ][ 'Ave' ] = {}
+                resultDict[d][ 'node' + str(i) ][ 'Std' ] = {}
+                resultDict[d][ 'node' + str(i) ][ 'EtoE' ] = []
+                resultDict[d][ 'node' + str(i) ][ 'PtoD' ] = []
+                resultDict[d][ 'node' + str(i) ][ 'DtoL' ] = []
+                resultDict[d][ 'node' + str(i) ][ 'LtoG' ] = []
+        for i in range( 1, main.sampleSize + main.warmUp ):
+            main.log.info( "==========================================" )
+            main.log.info( "================iteration:{}==============".format(str (i) ) )
+            if i > main.warmUp:
+                # Portdown iteration
+                main.portFunc.capturePortStatusPack( main, main.device, main.interface, "down", resultDict, False )
+                time.sleep(2)
+                # PortUp iteration
+                main.portFunc.capturePortStatusPack( main, main.device, main.interface, "up", resultDict, False )
             else:
-                main.log.info('Tshark output file returned unexpected' +
-                        ' results: ' + str(objDown))
-                timestampBeginPtDown = 0
-            fPortDown.close()
+                # if warm up, keep old result dictionary
+                main.portFunc.capturePortStatusPack( main, main.device, main.interface, "down", resultDict, True)
+                main.portFunc.capturePortStatusPack( main, main.device, main.interface, "up", resultDict, True)
 
-            for node in range(0, clusterCount):
-                nodeNum = node+1
-                metricsDown = CLIs[node].topologyEventsMetrics
-                jsonStrPtDown[node] = metricsDown()
-                jsonObj = json.loads(jsonStrPtDown[node])
+        # Dictionary for result
+        maxDict  = {}
+        maxDict['down'] = {}
+        maxDict['up'] = {}
+        maxDict['down']['max'] = 0
+        maxDict['up']['max'] = 0
+        maxDict['down']['node'] = 0
+        maxDict['up']['node'] = 0
+        EtoEtemp = 0
+        for d in resultDict:
+            for i in range( 1, main.numCtrls + 1 ):
+                # calculate average and std for result, and grep the max End to End data
+                EtoEtemp = numpy.average( resultDict[d][ 'node' + str(i) ]['EtoE'] )
+                resultDict[d][ 'node' + str(i) ][ 'Ave' ][ 'EtoE' ] = EtoEtemp
+                if maxDict[d]['max'] < EtoEtemp:
+                    # get max End to End latency
+                    maxDict[d]['max'] = EtoEtemp
+                    maxDict[d]['node'] = i
+                resultDict[d]['node' + str(i)]['Ave']['PtoD'] = numpy.average(resultDict[d]['node' + str(i)]['PtoD'])
+                resultDict[d]['node' + str(i)]['Ave']['DtoL'] = numpy.average(resultDict[d]['node' + str(i)]['DtoL'])
+                resultDict[d]['node' + str(i)]['Ave']['LtoG'] = numpy.average(resultDict[d]['node' + str(i)]['LtoG'])
 
-                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
+                resultDict[d]['node' + str(i)]['Std']['EtoE'] = numpy.std(resultDict[d]['node' + str(i)]['EtoE'])
+                resultDict[d]['node' + str(i)]['Std']['PtoD'] = numpy.std(resultDict[d]['node' + str(i)]['PtoD'])
+                resultDict[d]['node' + str(i)]['Std']['DtoL'] = numpy.std(resultDict[d]['node' + str(i)]['DtoL'])
+                resultDict[d]['node' + str(i)]['Std']['LtoG'] = numpy.std(resultDict[d]['node' + str(i)]['LtoG'])
 
-                main.log.info('ptDownTimestamp: ' + str(timestampBeginPtDown))
-                main.log.info("graphTimestamp: " + str(graphTimestamp))
-                main.log.info("deviceTimestamp: " + str(deviceTimestamp))
-                main.log.info("linkTimestamp: " + str(linkTimestamp))
+                main.log.report( "=====node{} Summary:=====".format( str(i) ) )
+                main.log.report( "=============Port {}=======".format( str(d) ) )
+                main.log.report(
+                    "End to End average: {}".format( str(resultDict[d][ 'node' + str(i) ][ 'Ave' ][ 'EtoE' ]) ) )
+                main.log.report(
+                    "End to End Std: {}".format( str(resultDict[d][ 'node' + str(i) ][ 'Std' ][ 'EtoE' ]) ) )
+                main.log.report(
+                    "Package to Device average: {}".format( str(resultDict[d]['node' + str(i)]['Ave']['PtoD']) ) )
+                main.log.report(
+                    "Package to Device Std: {}".format( str( resultDict[d]['node' + str(i)]['Std']['PtoD'])))
+                main.log.report(
+                    "Device to Link average: {}".format( str( resultDict[d]['node' + str(i)]['Ave']['DtoL']) ) )
+                main.log.report(
+                    "Device to Link Std: {}".format( str( resultDict[d]['node' + str(i)]['Std']['DtoL'])))
+                main.log.report(
+                    "Link to Grapg average: {}".format( str( resultDict[d]['node' + str(i)]['Ave']['LtoG']) ) )
+                main.log.report(
+                    "Link to Grapg Std: {}".format( str( resultDict[d]['node' + str(i)]['Std']['LtoG'] ) ) )
 
-                ptDownEndToEnd = int(graphTimestamp) - int(timestampBeginPtDown)
-                ptDownOfpToDevice = float(deviceTimestamp) - float(timestampBeginPtDown)
-                ptDownDeviceToLink = float(linkTimestamp) - float(deviceTimestamp)
-                ptDownLinkToGraph = float(graphTimestamp) - float(linkTimestamp)
+        with open( main.dbFileName, "a" ) as dbFile:
+            # Scale number
+            temp = str( main.numCtrls )
+            temp += ",'baremetal1'"
+            # put result
+            temp += "," + str( resultDict['up'][ 'node' + str(maxDict['up']['node']) ][ 'Ave' ][ 'EtoE' ] )
+            temp += "," + str( resultDict['up'][ 'node' + str(maxDict['up']['node']) ][ 'Ave' ][ 'PtoD' ] )
+            temp += "," + str( resultDict['up'][ 'node' + str(maxDict['up']['node']) ][ 'Ave' ][ 'DtoL' ] )
+            temp += "," + str( resultDict['up'][ 'node' + str(maxDict['up']['node']) ][ 'Ave' ][ 'LtoG' ] )
+            temp += "," + str( resultDict['down'][ 'node' + str(maxDict['down']['node']) ][ 'Ave' ][ 'EtoE' ] )
+            temp += "," + str( resultDict['down'][ 'node' + str(maxDict['down']['node']) ][ 'Ave' ][ 'PtoD' ] )
+            temp += "," + str( resultDict['down'][ 'node' + str(maxDict['down']['node']) ][ 'Ave' ][ 'DtoL' ] )
+            temp += "," + str( resultDict['down'][ 'node' + str(maxDict['down']['node']) ][ 'Ave' ][ 'LtoG' ] )
 
-                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")
+            temp += "," + str( resultDict['up'][ 'node' + str(maxDict['up']['node']) ][ 'Std' ][ 'EtoE' ] )
+            temp += "," + str( resultDict['down'][ 'node' + str(maxDict['down']['node']) ][ 'Std' ][ 'EtoE' ] )
 
-                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()
+            temp += "\n"
+            dbFile.write( temp )
+            dbFile.close()
diff --git a/TestON/tests/SCPF/SCPFportLat/dependencies/portFunc.py b/TestON/tests/SCPF/SCPFportLat/dependencies/portFunc.py
new file mode 100644
index 0000000..98ed397
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFportLat/dependencies/portFunc.py
@@ -0,0 +1,79 @@
+import time
+import json
+'''
+    Warp function for SCPFportLat test
+'''
+
+def capturePortStatusPack( main, deviceName, interface, portStatus, resultDict, warmup ):
+    '''
+    Change device port status and use tshark to capture openflow port package
+    Args:
+        main: TestON class
+        deviceName: Device to change portStatus
+        interface: port number
+        portStatus: up or down
+        resultDict: put result to dictionary
+        warmup: if warmpu, ignore results
+
+    '''
+    main.log.info( "Clean up tshark" )
+    with open( main.tsharkResultPath, "w" ) as tshark:
+        tshark.write("")
+    main.log.info( "Starting tshark capture" )
+    main.ONOSbench.tsharkGrep( main.ofportStatus, main.tsharkResultPath )
+    time.sleep( main.measurementSleep )
+    main.log.info( "{} port {} {}".format( deviceName, interface, portStatus ) )
+    main.Mininet1.changeInterfaceStatus( deviceName, interface, portStatus )
+    time.sleep( main.measurementSleep )
+    main.log.info( "Stopping all Tshark processes" )
+    main.ONOSbench.tsharkStop()
+
+    # 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 = int( float( resultText[1] ) * 1000.0 )
+            resultFile.close()
+            for i in range( 1, main.numCtrls + 1 ):
+                main.log.info( "================================================" )
+                # get onos metrics timestamps
+                try:
+                    response = json.loads( main.CLIs[i - 1].topologyEventsMetrics() )
+                    deviceTime = int( response.get( "topologyDeviceEventTimestamp" ).get( "value" ) )
+                    main.log.info( "ONOS{} device Event timestemp: {}".format( i, deviceTime ) )
+
+                    linkTime = int( response.get( "topologyLinkEventTimestamp" ).get( "value" ) )
+                    main.log.info( "ONOS{} Link Event timestemp: {}".format( i, linkTime ) )
+
+                    graphTime = int( response.get( "topologyGraphEventTimestamp" ).get( "value" ) )
+                    main.log.info( "ONOS{} Graph Event timestemp: {}".format( i, graphTime ) )
+                except TypeError:
+                    main.log.warn( "TypeError!" )
+                    break
+                except ValueError:
+                    main.log.warn( "Unable to decode Json object!" )
+                    break
+                main.log.info( "================================================" )
+                # calculate latency
+                EtoE = graphTime - tsharkResultTime
+                PtoD = deviceTime - tsharkResultTime
+                DtoL = linkTime - deviceTime
+                LtoG = graphTime - linkTime
+                main.log.info( "ONOS{} End to End time: {}".format( i, EtoE ) )
+                main.log.info( "ONOS{} Package to Device time: {}".format( i, PtoD ) )
+                main.log.info( "ONOS{} Device to Link time: {}".format( i, DtoL ) )
+                main.log.info( "ONOS{} Link to Graph time: {}".format( i, LtoG ) )
+                # if less than 0 waring
+                if EtoE < 0 or PtoD < 0 or DtoL < 0 or LtoG < 0:
+                    main.log.warn( "Latency less than 0! Ingore this loop." )
+                else:
+                    # put result to dictionary
+                    if not warmup:
+                        resultDict[ portStatus ][ 'node' + str(i) ]['EtoE'].append( EtoE )
+                        resultDict[ portStatus ][ 'node' + str(i) ]['PtoD'].append( PtoD )
+                        resultDict[ portStatus ][ 'node' + str(i) ]['DtoL'].append( DtoL )
+                        resultDict[ portStatus ][ 'node' + str(i) ]['LtoG'].append( LtoG )
+        else:
+            main.log.error( "Tshark output file for packet_in returned unexpected results" )
diff --git a/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.params b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.params
index da371c3..fe3896e 100644
--- a/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.params
+++ b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.params
@@ -1,5 +1,5 @@
 <PARAMS>
-    <testcases>1,2,1,2,1,2,1,2</testcases>
+    <testcases>0,1,2,1,2,1,2,1,2</testcases>
 
     <SCALE>1,3,5,7</SCALE>
     <max>7</max>
@@ -9,9 +9,15 @@
         <cellApps>drivers,metrics,openflow</cellApps>
     </ENV>
 
+    <DEPENDENCY>
+        <path>/tests/SCPF/SCPFswitchLat/dependencies/</path>
+        <topology>topo-perf-1sw.py</topology>
+        <function>switchFunc</function>
+    </DEPENDENCY>
+
     <GIT>
-        <autopull>off</autopull>
-        <checkout>master</checkout>
+        <gitPull>off</gitPull>
+        <gitBranch>master</gitBranch>
     </GIT>
 
     <CTRL>
@@ -29,17 +35,26 @@
         <ip1>OCN</ip1>
     </MN>
 
+    <TIMEOUT>
+        <timeout>60</timeout>
+    </TIMEOUT>
+
     <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>
+        <up>
+            <TCP>openflow\ \[SYN\]</TCP>  #1
+            <RQ>OF 1.3 90 of_role_request</RQ> #2
+            <RR>OF 1.3 90 of_role_reply</RR> #3
+            <Feature>OF 1.3 98 of_features_reply</Feature>#4
+        </up>
+
+        <down>
+            <FA>\[FIN,\ ACK\]</FA>
+            <ACK>openflow\ \[ACK\]</ACK>
+        </down>
     </TSHARK>
 
     <TEST>
@@ -58,20 +73,41 @@
         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>
+        <warmUp>5</warmUp>
+
+        #Number of times to iterate each case
+        <sampleSize>20</sampleSize>
+        <device>s3</device>
+        <tsharkResultPath>
+            <up>
+                <TCP>/tmp/Tshark_TCP</TCP>
+                <RQ>/tmp/Tshark_RQ</RQ> #role request
+                <RR>/tmp/Tshark_RR</RR> #role reply OF output
+                <Feature>/tmp/Tshark_Feature</Feature>
+            </up>
+
+            <down>
+                <FA>/tmp/Tshark_FA</FA>#Fin_ack
+                <ACK>/tmp/Tshark_ACK</ACK>
+            </down>
+
+        </tsharkResultPath>
 
         <singleSwThreshold>0,1000</singleSwThreshold>
 
         <tabletFile>tablets_3node.json</tabletFile>
    </TEST>
 
-    <DB>
-        <switchEventResultPath>/tmp/switchEventResultDb</switchEventResultPath>
-    </DB>
+    <SLEEP>
+        <startup>5</startup>
+        <measure>5</measure>
+        <mininet>5</mininet>
+    </SLEEP>
+
+    <DATABASE>
+        <dbName>/tmp/switchEventResultDb</dbName>
+    </DATABASE>
 
     <JSON>
         <deviceTimestamp>topologyDeviceEventTimestamp</deviceTimestamp>
diff --git a/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.py b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.py
index 55cef23..b00b7be 100644
--- a/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.py
+++ b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.py
@@ -1,863 +1,383 @@
-# CASE1 starts number of nodes specified in param file
-#
-# cameron@onlab.us
+'''
+    SCPFswitchLat
+    Test Switch add/remove latency
+    calculate package latency between switch and ONOS
+    Switch UP:
+    TCP -- Feature Reply -- Role Request -- Role Reply -- Device -- Graph
+    Siwtch Down:
+    Openflow FIN/ACK -- ACK -- Device -- Graph
+'''
 
 class SCPFswitchLat:
 
-    def __init__( self ):
+    def __init__(self):
         self.default = ''
 
-    def CASE1( self, main ):
-        import sys
-        import re
+    def CASE0( self, main ):
         import os
+        import imp
+        '''
+        - GIT
+        - BUILDING ONOS
+            Pull specific ONOS branch, then Build ONOS ono ONOS Bench.
+            This step is usually skipped. Because in a Jenkins driven automated
+            test env. We want Jenkins jobs to pull&build for flexibility to handle
+            different versions of ONOS.
+        - Construct tests variables
+        '''
+        gitPull = main.params['GIT']['gitPull']
+        gitBranch = main.params['GIT']['gitBranch']
+
+        main.case( "Pull onos branch and build onos on Teststation." )
+
+        if gitPull == 'True':
+            main.step( "Git Checkout ONOS branch: " + gitBranch )
+            stepResult = main.ONOSbench.gitCheckout( branch=gitBranch )
+            utilities.assert_equals(expect=main.TRUE,
+                                    actual=stepResult,
+                                    onpass="Successfully checkout onos branch.",
+                                    onfail="Failed to checkout onos branch. Exiting test...")
+            if not stepResult: main.exit()
+
+            main.step( "Git Pull on ONOS branch:" + gitBranch )
+            stepResult = main.ONOSbench.gitPull()
+            utilities.assert_equals(expect=main.TRUE,
+                                    actual=stepResult,
+                                    onpass="Successfully pull onos. ",
+                                    onfail="Failed to pull onos. Exiting test ...")
+            if not stepResult: main.exit()
+
+            main.step( "Building ONOS branch: " + gitBranch )
+            stepResult = main.ONOSbench.cleanInstall( skipTest=True )
+            utilities.assert_equals(expect=main.TRUE,
+                                    actual=stepResult,
+                                    onpass="Successfully build onos.",
+                                    onfail="Failed to build onos. Exiting test...")
+            if not stepResult: main.exit()
+
+        else:
+            main.log.warn( "Skipped pulling onos and Skipped building ONOS" )
+
+        main.testOnDirectory = os.path.dirname(os.getcwd())
+        main.MN1Ip = main.params['MN']['ip1']
+        main.dependencyPath = main.testOnDirectory + \
+                              main.params['DEPENDENCY']['path']
+        main.topoName = main.params['DEPENDENCY']['topology']
+        main.dependencyFunc = main.params['DEPENDENCY']['function']
+        main.cellName = main.params['ENV']['cellName']
+        main.Apps = main.params['ENV']['cellApps']
+        main.scale = (main.params['SCALE']).split(",")
+
+        main.ofPackage = main.params['TSHARK']
+
+        main.tsharkResultPath = main.params['TEST']['tsharkResultPath']
+        main.sampleSize = int(main.params['TEST']['sampleSize'])
+        main.warmUp = int(main.params['TEST']['warmUp'])
+        main.dbFileName = main.params['DATABASE']['dbName']
+        main.startUpSleep = int(main.params['SLEEP']['startup'])
+        main.measurementSleep = int( main.params['SLEEP']['measure'] )
+        main.maxScale = int( main.params['max'] )
+        main.timeout = int( main.params['TIMEOUT']['timeout'] )
+        main.MNSleep = int( main.params['SLEEP']['mininet'])
+        main.device = main.params['TEST']['device']
+ 
+        main.log.info("Create Database file " + main.dbFileName)
+        resultsDB = open(main.dbFileName, "w+")
+        resultsDB.close()
+
+        main.switchFunc = imp.load_source(main.dependencyFunc,
+                                       main.dependencyPath +
+                                       main.dependencyFunc +
+                                       ".py")
+
+    def CASE1(self, main):
+        # Clean up test environment and set up
         import time
+        main.log.info("Get ONOS cluster IP")
+        print(main.scale)
+        main.numCtrls = int(main.scale.pop(0))
+        main.ONOSip = []
+        main.maxNumBatch = 0
+        main.AllONOSip = main.ONOSbench.getOnosIps()
+        for i in range(main.numCtrls):
+            main.ONOSip.append(main.AllONOSip[i])
+        main.log.info(main.ONOSip)
+        main.CLIs = []
+        main.log.info("Creating list of ONOS cli handles")
+        for i in range(main.numCtrls):
+            main.CLIs.append(getattr(main, 'ONOS%scli' % (i + 1)))
 
-        global init
-        try:
-            if type(init) is not bool:
-                init = Fals
-        except NameError:
-            init = False
+        if not main.CLIs:
+            main.log.error("Failed to create the list of ONOS cli handles")
+            main.cleanup()
+            main.exit()
 
-        #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' ]
+        main.commit = main.ONOSbench.getVersion(report=True)
+        main.commit = main.commit.split(" ")[1]
+        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")
 
-        # -- 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(main.numCtrls):
+            main.ONOSbench.onosDie(main.ONOSip[i])
 
-            for i in range( 1, 8 ):
-                CLIs.append( getattr( main, 'ONOS' + str( i ) + 'cli' ) )
+        main.log.info("NODE COUNT = %s" % main.numCtrls)
+        main.ONOSbench.createCellFile(main.ONOSbench.ip_address,
+                                      main.cellName,
+                                      main.MN1Ip,
+                                      main.Apps,
+                                      main.ONOSip)
+        main.step("Apply cell to environment")
+        cellResult = main.ONOSbench.setCell(main.cellName)
+        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 ")
 
-            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.step("Grabbing commit number")
-            commit = main.ONOSbench.getVersion()       ####
-            commit = (commit.split(" "))[1]
-
-            temp = testONpath.replace("bin","") + "tests/SCPF/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.step("Adjusting scale")
-        clusterCount = int(scale[0])
-        scale.remove(scale[0])
-
-        #kill off all onos processes
-        main.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.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" )
+        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( "verify cells" )
-        verifyCellResult = main.ONOSbench.verifyCell()
+        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('Starting mininet topology ')
+        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)
+        time.sleep(2)
+        main.step("Start ONOS CLI on all nodes")
+        cliResult = main.TRUE
+        main.step(" Start ONOS cli using thread ")
+        startCliResult = main.TRUE
+        pool = []
+        main.threadID = 0
+        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)
+
+        main.log.info("Configure apps")
+        main.CLIs[0].setCfg("org.onosproject.net.topology.impl.DefaultTopologyProvider",
+                            "maxEvents 1")
+        main.CLIs[0].setCfg("org.onosproject.net.topology.impl.DefaultTopologyProvider",
+                            "maxBatchMs 0")
+        main.CLIs[0].setCfg("org.onosproject.net.topology.impl.DefaultTopologyProvider",
+                            "maxIdleMs 0")
+        time.sleep(1)
+
+        main.log.info("Copy topology file to Mininet")
+        main.ONOSbench.copyMininetFile(main.topoName,
+                                       main.dependencyPath,
+                                       main.Mininet1.user_name,
+                                       main.Mininet1.ip_address)
+        main.log.info("Stop Mininet...")
+        main.Mininet1.stopNet()
+        time.sleep(main.MNSleep)
+        main.log.info("Start new mininet topology")
         main.Mininet1.startNet()
+        main.log.info("Assign switch to controller to ONOS node 1")
 
-        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])
+        time.sleep(2)
 
-        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 )
-        """
+    def CASE2(self,main):
         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'])
+        resultDict = {'up' : {}, 'down' : {}}
+        for i in range(1, main.numCtrls + 1):
+            resultDict['up'][ 'node' + str(i) ] = {}
+            resultDict['up'][ 'node' + str(i) ][ 'Ave' ] = {}
+            resultDict['up'][ 'node' + str(i) ][ 'Std' ] = {}
+            resultDict['up'][ 'node' + str(i) ][ 'T_F' ] = []#TCP to Feature
+            resultDict['up'][ 'node' + str(i) ][ 'F_R' ] = []#Feature to Role
+            resultDict['up'][ 'node' + str(i) ][ 'RQ_RR' ] = []#role request to role reply
+            resultDict['up'][ 'node' + str(i) ][ 'RR_D' ] = []#role reply to Device
+            resultDict['up'][ 'node' + str(i) ][ 'D_G' ] = []#Device to Graph
+            resultDict['up'][ 'node' + str(i) ][ 'E_E' ] = []#TCP to Graph
 
-        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
+        for i in range(1,main.numCtrls + 1):
+            resultDict['down'][ 'node' + str(i) ] = {}
+            resultDict['down'][ 'node' + str(i) ][ 'Ave' ] = {}
+            resultDict['down'][ 'node' + str(i) ][ 'Std' ] = {}
+            resultDict['down'][ 'node' + str(i) ][ 'FA_A' ] = []#Fin_ack to ACK
+            resultDict['down'][ 'node' + str(i) ][ 'A_D' ] = []#Ack to Device
+            resultDict['down'][ 'node' + str(i) ][ 'D_G' ] = []#Device to Graph
+            resultDict['down'][ 'node' + str(i) ][ 'E_E' ] = []#fin_ack to Graph
+        for i in range(1 , main.sampleSize + main.warmUp):
+            main.log.info("************************************************************")
+            main.log.info("************************ Iteration: {} **********************" .format(str( i )) )
+            if i < main.warmUp:
+                main.switchFunc.captureOfPack( main, main.device, main.ofPackage,
+                                               "up", resultDict, True )
+                main.switchFunc.captureOfPack( main, main.device, main.ofPackage,
+                                               "down", resultDict, True )
             else:
-                main.log.error('Tshark output file for TCP' + ' returned unexpected results')
-                t0Tcp = 0
-                assertion = main.FALSE
-            tcpFile.close()
+                main.switchFunc.captureOfPack( main, main.device, main.ofPackage,
+                                               "up", resultDict, False )
+                main.switchFunc.captureOfPack (main, main.device, main.ofPackage,
+                                               "down", resultDict, False )
+        # Dictionary for result
+        maxDict  = {}
+        maxDict['down'] = {}
+        maxDict['up'] = {}
+        maxDict['down']['max'] = 0
+        maxDict['up']['max'] = 0
+        maxDict['down']['node'] = 0
+        maxDict['up']['node'] = 0
 
-            # 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()
+        for i in range(1, main.numCtrls + 1):
+            # calculate average and std for result, and grep the max End to End data
+            EtoEtemp = numpy.average( resultDict['up'][ 'node' + str(i) ]['E_E'] )
+            resultDict['up'][ 'node' + str(i) ][ 'Ave' ][ 'E_E' ] = EtoEtemp
+            if maxDict['up']['max'] < EtoEtemp:
+                # get max End to End latency
+                maxDict['up']['max'] = EtoEtemp
+                maxDict['up']['node'] = i
+            resultDict['up']['node' + str(i)]['Ave']['T_F'] = numpy.average(resultDict['up']['node' + str(i)]['T_F'])
+            resultDict['up']['node' + str(i)]['Ave']['F_R'] = numpy.average(resultDict['up']['node' + str(i)]['F_R'])
+            resultDict['up']['node' + str(i)]['Ave']['RQ_RR'] = numpy.average(resultDict['up']['node' + str(i)]['RQ_RR'])
+            resultDict['up']['node' + str(i)]['Ave']['RR_D'] = numpy.average(resultDict['up']['node' + str(i)]['RR_D'])
+            resultDict['up']['node' + str(i)]['Ave']['D_G'] = numpy.average(resultDict['up']['node' + str(i)]['D_G'])
 
-            # 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()
+            resultDict['up'][ 'node' + str(i) ][ 'Std' ][ 'E_E' ] = numpy.std( resultDict['up'][ 'node' + str(i) ]['E_E'] )
+            resultDict['up']['node' + str(i)]['Std']['T_F'] = numpy.std(resultDict['up']['node' + str(i)]['T_F'])
+            resultDict['up']['node' + str(i)]['Std']['F_R'] = numpy.std(resultDict['up']['node' + str(i)]['F_R'])
+            resultDict['up']['node' + str(i)]['Std']['RQ_RR'] = numpy.std(resultDict['up']['node' + str(i)]['RQ_RR'])
+            resultDict['up']['node' + str(i)]['Std']['RR_D'] = numpy.std(resultDict['up']['node' + str(i)]['RR_D'])
+            resultDict['up']['node' + str(i)]['Std']['D_G'] = numpy.std(resultDict['up']['node' + str(i)]['D_G'])
 
-            # 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()
+            # calculate average and std for result, and grep the max End to End data
+            EtoEtemp = numpy.average( resultDict['down'][ 'node' + str(i) ]['E_E'] )
+            resultDict['down'][ 'node' + str(i) ][ 'Ave' ][ 'E_E' ] = EtoEtemp
+            if maxDict['down']['max'] < EtoEtemp:
+                # get max End to End latency
+                maxDict['down']['max'] = EtoEtemp
+                maxDict['down']['node'] = i
+            resultDict['down']['node' + str(i)]['Ave']['FA_A'] = numpy.average(resultDict['down']['node' + str(i)]['FA_A'])
+            resultDict['down']['node' + str(i)]['Ave']['A_D'] = numpy.average(resultDict['down']['node' + str(i)]['A_D'])
+            resultDict['down']['node' + str(i)]['Ave']['D_G'] = numpy.average(resultDict['down']['node' + str(i)]['D_G'])
 
-            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
+            resultDict['down'][ 'node' + str(i) ][ 'Std' ][ 'E_E' ] = numpy.std( resultDict['down'][ 'node' + str(i) ]['E_E'] )
+            resultDict['down']['node' + str(i)]['Std']['FA_A'] = numpy.std(resultDict['down']['node' + str(i)]['FA_A'])
+            resultDict['down']['node' + str(i)]['Std']['A_D'] = numpy.std(resultDict['down']['node' + str(i)]['A_D'])
+            resultDict['down']['node' + str(i)]['Std']['D_G'] = numpy.std(resultDict['down']['node' + str(i)]['D_G'])
 
-                endToEnd = int(graphTimestamp) - int(t0Tcp)
+            main.log.report( "=====node{} Summary:=====".format( str(i) ) )
+            main.log.report( "=============Switch up=======" )
 
-                # 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)
+            main.log.report(
+                            "End to End average: {}".format( str(resultDict["up"][ 'node' + str(i) ][ 'Ave' ][ 'E_E' ]) ) )
+            main.log.report(
+                            "End to End Std: {}".format( str(resultDict["up"][ 'node' + str(i) ][ 'Std' ][ 'E_E' ]) ) )
 
-                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))
+            main.log.report(
+                            "TCP to Feature average: {}".format( str(resultDict["up"][ 'node' + str(i) ][ 'Ave' ][ 'T_F' ]) ) )
+            main.log.report(
+                            "TCP to Feature Std: {}".format( str(resultDict["up"][ 'node' + str(i) ][ 'Std' ][ 'T_F' ]) ) )
 
-                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))
+            main.log.report(
+                            "Feature to Role average: {}".format( str(resultDict["up"][ 'node' + str(i) ][ 'Ave' ][ 'F_R' ]) ) )
+            main.log.report(
+                            "Feature to Role Std: {}".format( str(resultDict["up"][ 'node' + str(i) ][ 'Std' ][ 'F_R' ]) ) )
 
-                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))
+            main.log.report(
+                            "Role request to Role reply average: {}".format( str(resultDict["up"][ 'node' + str(i) ][ 'Ave' ][ 'RQ_RR' ]) ) )
+            main.log.report(
+                            "Role request to Role reply Std: {}".format( str(resultDict["up"][ 'node' + str(i) ][ 'Std' ][ 'RQ_RR' ]) ) )
 
-                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))
+            main.log.report(
+                            "Role reply to Device average: {}".format( str(resultDict["up"][ 'node' + str(i) ][ 'Ave' ][ 'RR_D' ]) ) )
+            main.log.report(
+                            "Role reply to Device Std: {}".format( str(resultDict["up"][ 'node' + str(i) ][ 'Std' ][ 'RR_D' ]) ) )
 
-                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))
+            main.log.report(
+                            "Device to Graph average: {}".format( str(resultDict["up"][ 'node' + str(i) ][ 'Ave' ][ 'D_G' ]) ) )
+            main.log.report(
+                            "Device to Graph Std: {}".format( str(resultDict["up"][ 'node' + str(i) ][ 'Std' ][ 'D_G' ]) ) )
 
-                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))
+            main.log.report( "=============Switch down=======" )
 
-            # ********************
-            time.sleep(5)
+            main.log.report(
+                            "End to End average: {}".format( str(resultDict["down"][ 'node' + str(i) ][ 'Ave' ][ 'E_E' ]) ) )
+            main.log.report(
+                            "End to End Std: {}".format( str(resultDict["down"][ 'node' + str(i) ][ 'Std' ][ 'E_E' ]) ) )
 
-            # Get device id to remove
-            deviceIdJsonStr = main.ONOS1cli.devices()
+            main.log.report(
+                            "Fin_ACK to ACK average: {}".format( str(resultDict["down"][ 'node' + str(i) ][ 'Ave' ][ 'FA_A' ]) ) )
+            main.log.report(
+                            "Fin_ACK to ACK Std: {}".format( str(resultDict["down"][ 'node' + str(i) ][ 'Std' ][ 'FA_A' ]) ) )
 
-            main.log.info( "Device obj obtained: " + str(deviceIdJsonStr) )
-            deviceId = json.loads(deviceIdJsonStr)
+            main.log.report(
+                            "ACK to Device average: {}".format( str(resultDict["down"][ 'node' + str(i) ][ 'Ave' ][ 'A_D' ]) ) )
+            main.log.report(
+                            "ACK to Device Std: {}".format( str(resultDict["down"][ 'node' + str(i) ][ 'Std' ][ 'A_D' ]) ) )
 
-            deviceList = []
-            for device in deviceId:
-                deviceList.append(device['id'])
+            main.log.report(
+                            "Device to Graph average: {}".format( str(resultDict["down"][ 'node' + str(i) ][ 'Ave' ][ 'D_G' ]) ) )
+            main.log.report(
+                            "Device to Graph Std: {}".format( str(resultDict["down"][ 'node' + str(i) ][ 'Std' ][ 'D_G' ]) ) )
 
-            # Measure switch down metrics
-            # TCP FIN/ACK -> TCP FIN
-            # TCP FIN -> Device Event
-            # Device Event -> Graph Event
-            # Capture switch down FIN / ACK packets
+        with open(main.dbFileName, "a") as dbFile:
+            # TODO: Save STD to Database
+            # Scale number
+            temp = str(main.numCtrls)
+            temp += ",'baremetal1'"
+            # put result
+            temp += "," + str( "%.2f" % resultDict['up'][ 'node' + str(maxDict['up']['node']) ][ 'Ave' ][ 'E_E' ] )
+            temp += "," + str( "%.2f" % resultDict['up'][ 'node' + str(maxDict['up']['node']) ][ 'Ave' ][ 'T_F' ] )
+            temp += "," + str( "%.2f" % resultDict['up'][ 'node' + str(maxDict['up']['node']) ][ 'Ave' ][ 'F_R' ] )
+            temp += "," + str( "%.2f" % resultDict['up'][ 'node' + str(maxDict['up']['node']) ][ 'Ave' ][ 'RQ_RR' ] )
+            temp += "," + str( "%.2f" % resultDict['up'][ 'node' + str(maxDict['up']['node']) ][ 'Ave' ][ 'RR_D' ] )
+            temp += "," + str( "%.2f" % resultDict['up'][ 'node' + str(maxDict['up']['node']) ][ 'Ave' ][ 'D_G' ] )
 
-            # 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' )
+            temp += "," + str( "%.2f" % resultDict['down'][ 'node' + str(maxDict['down']['node']) ][ 'Ave' ][ 'E_E' ] )
+            temp += "," + str( "%.2f" % resultDict['down'][ 'node' + str(maxDict['down']['node']) ][ 'Ave' ][ 'FA_A' ] )
+            temp += "," + str( "%.2f" % resultDict['down'][ 'node' + str(maxDict['down']['node']) ][ 'Ave' ][ 'A_D' ] )
+            temp += "," + str( "%.2f" % resultDict['down'][ 'node' + str(maxDict['down']['node']) ][ 'Ave' ][ 'D_G' ] )
 
-            time.sleep( 5 )
+            temp += "," + str( "%.2f" % resultDict['up'][ 'node' + str(maxDict['up']['node']) ][ 'Std' ][ 'E_E' ] )
+            temp += "," + str( "%.2f" % resultDict['down'][ 'node' + str(maxDict['down']['node']) ][ 'Std' ][ 'E_E' ] )
 
-            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()
+            temp += "\n"
+            dbFile.write( temp )
+            dbFile.close()
diff --git a/TestON/tests/SCPF/SCPFswitchLat/dependencies/switchFunc.py b/TestON/tests/SCPF/SCPFswitchLat/dependencies/switchFunc.py
new file mode 100644
index 0000000..77a6c7e
--- /dev/null
+++ b/TestON/tests/SCPF/SCPFswitchLat/dependencies/switchFunc.py
@@ -0,0 +1,251 @@
+'''
+    Wrapper function for SCPFswitchLat test
+    Assign switch and capture openflow package
+    remove switch and caputer openflow package
+    calculate latency
+'''
+
+
+import time
+import json
+def processPackage( package ):
+    '''
+    split package information to dictionary
+    Args:
+        package: Package String
+
+    Returns:
+
+    '''
+    pacakge = package.split(" ")
+    dic = {}
+    for s in pacakge:
+        try:
+            [key, value] = s.split("=")
+            dic[key] = value
+        except:
+            continue
+    return dic
+
+def findSeqBySeqAck( seq, packageList):
+    '''
+    Find specific Seq of package in packageList
+    Args:
+        seq: seq from last TCP package
+        packageList: find package in packageList
+
+    Returns:
+
+    '''
+    for l in packageList:
+        temp = processPackage(l)
+        tA = temp['Ack']
+        if int(seq) + 1 == int(tA):
+            return temp['Seq']
+
+def captureOfPack( main, deviceName, ofPack, switchStatus, resultDict, warmup ):
+    '''
+
+    Args:
+        main: TestON class
+        deviceName: device name
+        ofPack: openflow package key word
+        switchStatus: Up -- assign, down -- remove
+        resultDict: dictionary to contain result
+        warmup: warm up boolean
+
+    Returns:
+
+    '''
+    for d in ofPack[switchStatus]:
+        main.log.info("Clean up Tshark")
+        with open(main.tsharkResultPath[switchStatus][d], "w") as tshark:
+            tshark.write("")
+        main.log.info( "Starting tshark capture" )
+        main.ONOSbench.tsharkGrep(ofPack[switchStatus][d], main.tsharkResultPath[switchStatus][d])
+    if switchStatus == 'up':
+        # if up, assign switch to controller
+        time.sleep(main.measurementSleep)
+        main.log.info('Assigning {} to controller'.format(deviceName))
+        main.Mininet1.assignSwController(sw=deviceName, ip=main.ONOSip[0])
+        time.sleep(main.measurementSleep)
+    if switchStatus == 'down':
+        # if down, remove switch from topology
+        time.sleep(main.measurementSleep)
+        main.step('Remove switch from controller')
+        main.Mininet1.deleteSwController(deviceName)
+        time.sleep(10)
+    main.log.info( "Stopping all Tshark processes" )
+    main.ONOSbench.tsharkStop()
+    tempResultDict = {}
+    if switchStatus == 'up':
+        for d in main.tsharkResultPath['up']:
+            with open(main.tsharkResultPath[switchStatus][d], "r") as resultFile:
+                # grep tshark result timestamp
+                resultText = resultFile.readlines()
+                if d == "TCP":
+                    # if TCP package, we should use the latest one package
+                    resultText = resultText[len(resultText) - 1]
+                else:
+                    resultText = resultText[0]
+                main.log.info("Capture result:" + resultText)
+                resultText = resultText.strip()
+                resultText = resultText.split( " " )
+                if len(resultText) > 1:
+                    tempResultDict[d]= int( ( float(resultText[1]) * 1000 ) )
+                resultFile.close()
+    elif switchStatus == 'down':
+        # if state is down, we should capture Fin/Ack and ACK package
+        # Use seq number in FIN/ACK package to located ACK package
+        with open(main.tsharkResultPath['down']['FA']) as resultFile:
+            resultText = resultFile.readlines()
+            FinAckText = resultText.pop(0)
+            resultFile.close()
+        FinAckSeq = processPackage(FinAckText)['Seq']
+        FinAckOFseq = findSeqBySeqAck(FinAckSeq, resultText)
+
+        with open(main.tsharkResultPath['down']['ACK']) as resultFile:
+            ACKlines = resultFile.readlines()
+            resultFile.close()
+
+        AckPackage = ""
+        for l in ACKlines:
+            temp = processPackage(l)
+            if temp['Seq'] == findSeqBySeqAck(FinAckOFseq, ACKlines):
+                AckPackage = l
+        if len(AckPackage) > 0:
+            FinAckText = FinAckText.strip()
+            FinAckText = FinAckText.split(" ")
+            AckPackage = AckPackage.strip()
+            AckPackage = AckPackage.split(" ")
+            tempResultDict['ACK'] = float("%.2f" % (float(AckPackage[1]) * 1000) )
+            tempResultDict['FA'] = float("%.2f" % (float(FinAckText[1]) * 1000) )
+        else:
+            return
+    # calculate latency
+    if switchStatus == "up":
+        # up Latency
+        for d in resultDict[switchStatus]:
+            T_Ftemp = 0
+            F_Rtemp = 0
+            RQ_RRtemp = 0
+            try:
+                T_Ftemp = tempResultDict['Feature'] - tempResultDict['TCP']
+                F_Rtemp = tempResultDict['RQ'] - tempResultDict['Feature']
+                RQ_RRtemp = tempResultDict['RR'] - tempResultDict['RQ']
+            except KeyError:
+                main.log.warn("Tshark Result was incorrect!")
+                main.log.warn(tempResultDict)
+                return
+            if not warmup:
+                resultDict[switchStatus][d][ 'T_F' ].append( T_Ftemp )
+                resultDict[switchStatus][d][ 'F_R' ].append( F_Rtemp  )
+                resultDict[switchStatus][d][ 'RQ_RR' ].append( RQ_RRtemp )
+
+            main.log.info("{} TCP to Feature: {}".format(d, str( T_Ftemp ) ) )
+            main.log.info("{} Feature to Role Request: {}".format(d, str(F_Rtemp)))
+            main.log.info("{} Role Request to Role Reply: {}".format(d, str(RQ_RRtemp)))
+
+        for i in range(1, main.numCtrls + 1):
+            RR_Dtemp = 0
+            D_Gtemp = 0
+            E_Etemp = 0
+            main.log.info("================================================")
+            # get onos metrics timestamps
+            try:
+                response = json.loads(main.CLIs[i - 1].topologyEventsMetrics())
+                DeviceTime = int( response.get("topologyDeviceEventTimestamp").get("value") )
+                main.log.info("ONOS{} device Event timestamp: {}".format(i, "%.2f" % DeviceTime))
+                GraphTime = int( response.get("topologyGraphEventTimestamp").get("value") )
+                main.log.info("ONOS{} Graph Event timestamp: {}".format(i, GraphTime))
+            except TypeError:
+                main.log.warn("TypeError")
+                break
+            except ValueError:
+                main.log.warn("Error to decode Json object!")
+                break
+            try:
+                RR_Dtemp = DeviceTime - tempResultDict['RR']
+                D_Gtemp = GraphTime - DeviceTime
+                E_Etemp = GraphTime - tempResultDict['TCP']
+                main.log.info("Role reply to Device:{}".format(RR_Dtemp))
+                main.log.info("Device to Graph:{}".format(D_Gtemp))
+                main.log.info("End to End:{}".format(E_Etemp))
+                main.log.info("================================================")
+            except KeyError:
+                main.log.warn("Tshark Result was incorrect!")
+                main.log.warn(tempResultDict)
+                return
+            except TypeError:
+                main.log.warn("TypeError")
+                break
+            except ValueError:
+                main.log.warn("Error to decode Json object!")
+                break
+            if not warmup:
+                resultDict[switchStatus]['node' + str(i)][ 'RR_D' ].append( RR_Dtemp )
+                resultDict[switchStatus]['node' + str(i)][ 'D_G' ].append( D_Gtemp )
+                resultDict[switchStatus]['node' + str(i)][ 'E_E' ].append( E_Etemp )
+
+            main.log.info( "Node {} Role Reply to Device: {}".format(str(i), str(RR_Dtemp) ) )
+            main.log.info( "Node {} Device to Graph: {}".format(str(i), str(D_Gtemp) ) )
+            main.log.info( "Node {} End to End: {}".format(str(i), str(E_Etemp) ) )
+
+    if switchStatus == "down":
+        # down Latency
+        for d in resultDict[switchStatus]:
+            FA_Atemp = 0
+            try:
+                FA_Atemp = float("%.2f" % (tempResultDict['ACK'] - tempResultDict['FA']) )
+            except KeyError:
+                main.log.warn("Tshark Result was incorrect!")
+                main.log.warn(tempResultDict)
+                return
+
+            if not warmup:
+                resultDict[switchStatus][d][ 'FA_A' ].append( FA_Atemp )
+            main.log.info( "{} FIN/ACK TO ACK {}:".format(d , FA_Atemp) )
+        for i in range(1, main.numCtrls + 1):
+            A_Dtemp = 0
+            D_Gtemp = 0
+            E_Etemp = 0
+
+            main.log.info("================================================")
+            # get onos metrics timestamps
+            try:
+                response = json.loads(main.CLIs[i - 1].topologyEventsMetrics())
+                DeviceTime = int( response.get("topologyDeviceEventTimestamp").get("value") )
+                main.log.info("ONOS{} device Event timestamp: {}".format(i, DeviceTime))
+                GraphTime = int( response.get("topologyGraphEventTimestamp").get("value") )
+                main.log.info("ONOS{} Graph Event timestamp: {}".format(i, GraphTime))
+            except TypeError:
+                main.log.warn("TypeError")
+                break
+            except ValueError:
+                main.log.warn("Error to decode Json object!")
+                break
+            main.log.info("================================================")
+            try:
+                A_Dtemp = float("%.2f" % (DeviceTime - tempResultDict['ACK']) )
+                D_Gtemp = GraphTime - DeviceTime
+                E_Etemp = float("%.2f" % (GraphTime - tempResultDict['FA']) )
+                main.log.info("ACK to device: {}".format(A_Dtemp))
+                main.log.info("Device ot Graph: {}".format(D_Gtemp))
+                main.log.info("End to End: {}".format(E_Etemp))
+                main.log.info("================================================")
+            except KeyError:
+                main.log.warn("Tshark Result was incorrect!")
+                main.log.warn(tempResultDict)
+                return
+            except TypeError:
+                main.log.warn("TypeError")
+                break
+            except ValueError:
+                main.log.warn("Error to decode Json object!")
+                break
+            if not warmup:
+                resultDict[switchStatus]['node' + str(i)][ 'A_D' ].append( A_Dtemp )
+                resultDict[switchStatus]['node' + str(i)][ 'D_G' ].append( D_Gtemp )
+                resultDict[switchStatus]['node' + str(i)][ 'E_E' ].append( E_Etemp )
+        main.CLIs[0].removeDevice( "of:0000000000000001" )
+