Merge "ONOS-3343 Initial scapy implementation commit"
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index 21eb959..35527d4 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -1235,30 +1235,33 @@
 
     def link( self, **linkargs ):
         """
-           Bring link( s ) between two nodes up or down"""
-        args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
-        end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
-        end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
-        option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
-        main.log.info(
-            "Bring link between '" +
-            end1 +
-            "' and '" +
-            end2 +
-            "' '" +
-            option +
-            "'" )
-        command = "link " + \
-            str( end1 ) + " " + str( end2 ) + " " + str( option )
+           Bring link( s ) between two nodes up or down
+        """
         try:
-            self.handle.sendline( command )
+            args = utilities.parse_args( [ "END1", "END2", "OPTION" ], **linkargs )
+            end1 = args[ "END1" ] if args[ "END1" ] is not None else ""
+            end2 = args[ "END2" ] if args[ "END2" ] is not None else ""
+            option = args[ "OPTION" ] if args[ "OPTION" ] is not None else ""
+
+            main.log.info( "Bring link between " + str( end1 ) + " and " + str( end2 ) + " " + str( option ) )
+            cmd = "link {} {} {}".format( end1, end2, option )
+            self.handle.sendline( cmd )
             self.handle.expect( "mininet>" )
+            response = self.handle.before
+            main.log.info( response )
+
+            return main.TRUE
+        except pexpect.TIMEOUT:
+            main.log.exception( self.name + ": Command timed out" )
+            return None
         except pexpect.EOF:
-            main.log.error( self.name + ": EOF exception found" )
-            main.log.error( self.name + ":     " + self.handle.before )
+            main.log.exception( self.name + ": connection closed." )
             main.cleanup()
             main.exit()
-        return main.TRUE
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def switch( self, **switchargs ):
         """
diff --git a/TestON/drivers/common/cli/onosclidriver.py b/TestON/drivers/common/cli/onosclidriver.py
index e15ec40..2c4e687 100644
--- a/TestON/drivers/common/cli/onosclidriver.py
+++ b/TestON/drivers/common/cli/onosclidriver.py
@@ -59,7 +59,7 @@
             self.name = self.options[ 'name' ]
 
             try:
-                if os.getenv( str( self.ip_address ) ) != None:
+                if os.getenv( str( self.ip_address ) ) is not None:
                     self.ip_address = os.getenv( str( self.ip_address ) )
                 else:
                     main.log.info( self.name +
@@ -209,7 +209,7 @@
             main.exit()
 
     def startOnosCli( self, ONOSIp, karafTimeout="",
-            commandlineTimeout=10, onosStartTimeout=60 ):
+                      commandlineTimeout=10, onosStartTimeout=60 ):
         """
         karafTimeout is an optional argument. karafTimeout value passed
         by user would be used to set the current karaf shell idle timeout.
@@ -301,7 +301,7 @@
                 lvlStr = "--level=" + level
 
             self.handle.sendline( "" )
-            i = self.handle.expect( [ "onos>","\$", pexpect.TIMEOUT ] )
+            i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
             if i == 1:
                 main.log.error( self.name + ": onos cli session closed." )
                 main.cleanup()
@@ -331,7 +331,7 @@
             main.cleanup()
             main.exit()
 
-    def sendline( self, cmdStr, showResponse=False, debug=False ):
+    def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10 ):
         """
         Send a completely user specified string to
         the onos> prompt. Use this function if you have
@@ -339,22 +339,14 @@
 
         Warning: There are no sanity checking to commands
         sent using this method.
+
         """
         try:
             logStr = "\"Sending CLI command: '" + cmdStr + "'\""
             self.log( logStr )
             self.handle.sendline( cmdStr )
-            i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
+            i = self.handle.expect( ["onos>", "\$"], timeout )
             response = self.handle.before
-            if i == 2:
-                self.handle.sendline()
-                self.handle.expect( ["\$", pexpect.TIMEOUT] )
-                response += self.handle.before
-                print response
-                try:
-                    print self.handle.after
-                except TypeError:
-                    pass
             # TODO: do something with i
             main.log.info( "Command '" + str( cmdStr ) + "' sent to "
                            + self.name + "." )
@@ -390,8 +382,13 @@
                     main.log.debug( self.name + ": " + repr( r ) )
             output = output[1].strip()
             if showResponse:
-                main.log.info( "Resonse from ONOS: {}".format( output ) )
+                main.log.info( "Response from ONOS: {}".format( output ) )
             return output
+        except pexpect.TIMEOUT:
+            main.log.error( self.name + ":ONOS timeout" )
+            if debug:
+                main.log.debug( self.handle.before )
+            return None
         except IndexError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -428,6 +425,7 @@
             cmdStr = "add-node " + str( nodeId ) + " " +\
                 str( ONOSIp ) + " " + str( tcpPort )
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             if re.search( "Error", handle ):
                 main.log.error( "Error in adding node" )
                 main.log.error( handle )
@@ -435,6 +433,9 @@
             else:
                 main.log.info( "Node " + str( ONOSIp ) + " added" )
                 return main.TRUE
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -459,12 +460,16 @@
 
             cmdStr = "remove-node " + str( nodeId )
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             if re.search( "Error", handle ):
                 main.log.error( "Error in removing node" )
                 main.log.error( handle )
                 return main.FALSE
             else:
                 return main.TRUE
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -490,7 +495,11 @@
             if jsonFormat:
                 cmdStr += " -j"
             output = self.sendline( cmdStr )
+            assert "Command not found:" not in output, output
             return output
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -514,78 +523,12 @@
         try:
             cmdStr = "topology -j"
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             main.log.info( cmdStr + " returned: " + str( handle ) )
             return handle
-        except TypeError:
-            main.log.exception( self.name + ": Object not as expected" )
+        except AssertionError:
+            main.log.exception( "" )
             return None
-        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( self.name + ": Uncaught exception!" )
-            main.cleanup()
-            main.exit()
-
-    def featureInstall( self, featureStr ):
-        """
-        Installs a specified feature by issuing command:
-            'feature:install <feature_str>'
-        NOTE: This is now deprecated, you should use the activateApp method
-              instead
-        """
-        try:
-            cmdStr = "feature:install " + str( featureStr )
-            handle = self.sendline( cmdStr )
-            if re.search( "Error", handle ):
-                main.log.error( "Error in installing feature" )
-                main.log.error( handle )
-                return main.FALSE
-            else:
-                return main.TRUE
-        except TypeError:
-            main.log.exception( self.name + ": Object not as expected" )
-            return None
-        except pexpect.EOF:
-            main.log.error( self.name + ": EOF exception found" )
-            main.log.error( self.name + ":    " + self.handle.before )
-            main.log.report( "Failed to install feature" )
-            main.log.report( "Exiting test" )
-            main.cleanup()
-            main.exit()
-        except Exception:
-            main.log.exception( self.name + ": Uncaught exception!" )
-            main.log.report( "Failed to install feature" )
-            main.log.report( "Exiting test" )
-            main.cleanup()
-            main.exit()
-
-    def featureUninstall( self, featureStr ):
-        """
-        Uninstalls a specified feature by issuing command:
-            'feature:uninstall <feature_str>'
-        NOTE: This is now deprecated, you should use the deactivateApp method
-              instead
-        """
-        try:
-            cmdStr = 'feature:list -i | grep "' + featureStr + '"'
-            handle = self.sendline( cmdStr )
-            if handle != '':
-                cmdStr = "feature:uninstall " + str( featureStr )
-                output = self.sendline( cmdStr )
-                # TODO: Check for possible error responses from karaf
-            else:
-                main.log.info( "Feature needs to be installed before " +
-                               "uninstalling it" )
-                return main.TRUE
-            if re.search( "Error", output ):
-                main.log.error( "Error in uninstalling feature" )
-                main.log.error( output )
-                return main.FALSE
-            else:
-                return main.TRUE
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -608,12 +551,16 @@
         try:
             cmdStr = "device-remove " + str( deviceId )
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             if re.search( "Error", handle ):
                 main.log.error( "Error in removing device" )
                 main.log.error( handle )
                 return main.FALSE
             else:
                 return main.TRUE
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -638,7 +585,11 @@
             if jsonFormat:
                 cmdStr += " -j"
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -661,12 +612,16 @@
         try:
             cmdStr = "onos:balance-masters"
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             if re.search( "Error", handle ):
                 main.log.error( "Error in balancing masters" )
                 main.log.error( handle )
                 return main.FALSE
             else:
                 return main.TRUE
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -680,7 +635,7 @@
             main.cleanup()
             main.exit()
 
-    def checkMasters( self,jsonFormat=True  ):
+    def checkMasters( self, jsonFormat=True  ):
         """
             Returns the output of the masters command.
             Optional argument:
@@ -691,7 +646,11 @@
             if jsonFormat:
                 cmdStr += " -j"
             output = self.sendline( cmdStr )
+            assert "Command not found:" not in output, output
             return output
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -705,7 +664,7 @@
             main.cleanup()
             main.exit()
 
-    def checkBalanceMasters( self,jsonFormat=True ):
+    def checkBalanceMasters( self, jsonFormat=True ):
         """
             Uses the master command to check that the devices' leadership
             is evenly divided
@@ -718,9 +677,15 @@
             Returns None on TypeError
         """
         try:
-            totalDevices = json.loads( self.summary() )[ "devices" ]
+            summaryOutput = self.summary()
+            totalDevices = json.loads( summaryOutput )[ "devices" ]
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
+            return None
+        try:
             totalOwnedDevices = 0
-            masters = json.loads( self.checkMasters() )
+            mastersOutput = self.checkMasters()
+            masters = json.loads( mastersOutput )
             first = masters[ 0 ][ "size" ]
             for master in masters:
                 totalOwnedDevices += master[ "size" ]
@@ -731,8 +696,8 @@
             main.log.info( "Mastership balanced between " \
                             + str( len(masters) ) + " masters" )
             return main.TRUE
-        except TypeError:
-            main.log.exception( self.name + ": Object not as expected" )
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
             return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
@@ -755,7 +720,11 @@
             if jsonFormat:
                 cmdStr += " -j"
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -780,7 +749,11 @@
             if jsonFormat:
                 cmdStr += " -j"
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -805,7 +778,11 @@
             if jsonFormat:
                 cmdStr += " -j"
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -842,8 +819,8 @@
                     if str( deviceId ) in device[ 'id' ]:
                         return device
             return None
-        except TypeError:
-            main.log.exception( self.name + ": Object not as expected" )
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
             return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
@@ -871,9 +848,8 @@
                     main.log.warn( "Device has no master: " + str( device ) )
                     return main.FALSE
             return main.TRUE
-
-        except TypeError:
-            main.log.exception( self.name + ": Object not as expected" )
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
             return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
@@ -893,6 +869,7 @@
         try:
             cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             if re.search( "Error", handle ):
                 main.log.error( "Error in getting paths" )
                 return ( handle, "Error" )
@@ -900,6 +877,9 @@
                 path = handle.split( ";" )[ 0 ]
                 cost = handle.split( ";" )[ 1 ]
                 return ( path, cost )
+        except AssertionError:
+            main.log.exception( "" )
+            return ( handle, "Error" )
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return ( handle, "Error" )
@@ -924,6 +904,7 @@
             if jsonFormat:
                 cmdStr += " -j"
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             try:
                 # TODO: Maybe make this less hardcoded
                 # ConsistentMap Exceptions
@@ -935,6 +916,9 @@
                                 "command: " + str( handle ) )
                 return None
             return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -972,8 +956,8 @@
                     elif mac in host[ 'id' ]:
                         return host
             return None
-        except TypeError:
-            main.log.exception( self.name + ": Object not as expected" )
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
             return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
@@ -1042,6 +1026,7 @@
             cmdStr = "add-host-intent " + str( hostIdOne ) +\
                 " " + str( hostIdTwo )
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             if re.search( "Error", handle ):
                 main.log.error( "Error in adding Host intent" )
                 main.log.debug( "Response from ONOS was: " + repr( handle ) )
@@ -1057,6 +1042,9 @@
                     main.log.debug( "Response from ONOS was: " +
                                     repr( handle ) )
                     return None
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -1086,6 +1074,7 @@
             cmdStr = "add-optical-intent " + str( ingressDevice ) +\
                 " " + str( egressDevice )
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             # If error, return error message
             if re.search( "Error", handle ):
                 main.log.error( "Error in adding Optical intent" )
@@ -1100,6 +1089,9 @@
                 else:
                     main.log.error( "Error, intent ID not found" )
                     return None
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -1215,6 +1207,7 @@
                     str( portEgress )
 
             handle = self.sendline( cmd )
+            assert "Command not found:" not in handle, handle
             # If error, return error message
             if re.search( "Error", handle ):
                 main.log.error( "Error in adding point-to-point intent" )
@@ -1230,6 +1223,9 @@
                 else:
                     main.log.error( "Error, intent ID not found" )
                     return None
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -1367,6 +1363,7 @@
                     str( egressDevice ) + "/" +\
                     str( portEgress )
             handle = self.sendline( cmd )
+            assert "Command not found:" not in handle, handle
             # If error, return error message
             if re.search( "Error", handle ):
                 main.log.error( "Error in adding multipoint-to-singlepoint " +
@@ -1379,6 +1376,9 @@
                 else:
                     main.log.error( "Error, intent ID not found" )
                     return None
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -1517,6 +1517,7 @@
                                     "have the same length" )
                     return main.FALSE
             handle = self.sendline( cmd )
+            assert "Command not found:" not in handle, handle
             # If error, return error message
             if re.search( "Error", handle ):
                 main.log.error( "Error in adding singlepoint-to-multipoint " +
@@ -1529,6 +1530,9 @@
                 else:
                     main.log.error( "Error, intent ID not found" )
                     return None
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -1653,6 +1657,7 @@
                     str( egressPort )
 
             handle = self.sendline( cmd )
+            assert "Command not found:" not in handle, handle
             # If error, return error message
             if re.search( "Error", handle ):
                 main.log.error( "Error in adding mpls intent" )
@@ -1668,6 +1673,9 @@
                 else:
                     main.log.error( "Error, intent ID not found" )
                     return None
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -1702,12 +1710,16 @@
 
             cmdStr += " " + app + " " + str( intentId )
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             if re.search( "Error", handle ):
                 main.log.error( "Error in removing intent" )
                 return main.FALSE
             else:
                 # TODO: Should this be main.TRUE
                 return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -1728,11 +1740,15 @@
         try:
             cmdStr = "purge-intents"
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             if re.search( "Error", handle ):
                 main.log.error( "Error in purging intents" )
                 return main.FALSE
             else:
                 return main.TRUE
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -1760,7 +1776,11 @@
             if jsonFormat:
                 cmdStr += " -j"
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -1784,11 +1804,14 @@
         try:
             cmdStr = "routes -s -j"
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             jsonResult = json.loads( handle )
             return jsonResult['totalRoutes4']
-
-        except TypeError:
-            main.log.exception( self.name + ": Object not as expected" )
+        except AssertionError:
+            main.log.exception( "" )
+            return None
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
             return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
@@ -1817,6 +1840,7 @@
             if jsonFormat:
                 cmdStr += " -j"
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             args = utilities.parse_args( [ "TYPE" ], **intentargs )
             if "TYPE" in args.keys():
                 intentType = args[ "TYPE" ]
@@ -1833,8 +1857,11 @@
             else:
                 main.log.error( handle )
                 return handle
-        except TypeError:
-            main.log.exception( self.name + ": Object not as expected" )
+        except AssertionError:
+            main.log.exception( "" )
+            return None
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
             return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
@@ -1865,11 +1892,12 @@
         try:
             state = "State is Undefined"
             if not intentsJson:
-                intentsJsonTemp = json.loads( self.intents() )
+                rawJson = self.intents()
             else:
-                intentsJsonTemp = json.loads( intentsJson )
+                rawJson = intentsJson
+            parsedIntentsJson = json.loads( rawJson )
             if isinstance( intentsId, types.StringType ):
-                for intent in intentsJsonTemp:
+                for intent in parsedIntentsJson:
                     if intentsId == intent[ 'id' ]:
                         state = intent[ 'state' ]
                         return state
@@ -1880,7 +1908,7 @@
                 dictList = []
                 for i in xrange( len( intentsId ) ):
                     stateDict = {}
-                    for intents in intentsJsonTemp:
+                    for intents in parsedIntentsJson:
                         if intentsId[ i ] == intents[ 'id' ]:
                             stateDict[ 'state' ] = intents[ 'state' ]
                             stateDict[ 'id' ] = intentsId[ i ]
@@ -1892,8 +1920,8 @@
             else:
                 main.log.info( "Invalid intents ID entry" )
                 return None
-        except TypeError:
-            main.log.exception( self.name + ": Object not as expected" )
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
             return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
@@ -1924,10 +1952,8 @@
             # Generating a dictionary: intent id as a key and state as value
             returnValue = main.TRUE
             intentsDict = self.getIntentState( intentsId )
-
-            #print "len of intentsDict ", str( len( intentsDict ) )
             if len( intentsId ) != len( intentsDict ):
-                main.log.info( self.name + "There is something wrong " +
+                main.log.info( self.name + ": There is something wrong " +
                                "getting intents state" )
                 return main.FALSE
 
@@ -1973,7 +1999,48 @@
             main.cleanup()
             main.exit()
 
-    def flows( self, jsonFormat=True ):
+    def checkIntentSummary( self, timeout=60 ):
+        """
+        Description:
+            Check the number of installed intents.
+        Optional:
+            timeout - the timeout for pexcept
+        Return:
+            Returns main.TRUE only if the number of all installed intents are the same as total intents number
+            , otherwise, returns main.FALSE.
+        """
+
+        try:
+            cmd = "intents -s -j"
+
+            # Check response if something wrong
+            response = self.sendline( cmd, timeout=timeout )
+            if response == None:
+                return main.False
+            response = json.loads( response )
+
+            # get total and installed number, see if they are match
+            allState = response.get( 'all' )
+            if allState.get('total') == allState.get('installed'):
+                main.log.info( 'Total Intents: {}   Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
+                return main.TRUE
+            main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
+            return main.FALSE
+
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
+            return None
+        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( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def flows( self, state="", jsonFormat=True, timeout=60 ):
         """
         Optional:
             * jsonFormat: enable output formatting in json
@@ -1983,15 +2050,23 @@
         try:
             cmdStr = "flows"
             if jsonFormat:
-                cmdStr += " -j"
-            handle = self.sendline( cmdStr )
+                cmdStr += " -j "
+            cmdStr += state
+            handle = self.sendline( cmdStr, timeout=timeout )
+            assert "Command not found:" not in handle, handle
             if re.search( "Error:", handle ):
                 main.log.error( self.name + ": flows() response: " +
                                 str( handle ) )
             return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
+        except pexpect.TIMEOUT:
+            main.log.error( self.name + ": ONOS timeout" )
+            return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
@@ -2002,48 +2077,46 @@
             main.cleanup()
             main.exit()
 
-    def checkFlowsState( self, isPENDING_ADD = True ):
+
+    def checkFlowsState( self, isPENDING=True, timeout=60 ):
         """
         Description:
-            Check the if all the current flows are in ADDED state or
-            PENDING_ADD state
+            Check the if all the current flows are in ADDED state
+            We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
+            if the count of those states is 0, which means all current flows
+            are in ADDED state, and return main.TRUE otherwise return main.FALSE
         Optional:
-            * isPENDING_ADD: whether the PENDING_ADD is also a correct status
+            * isPENDING:  whether the PENDING_ADD is also a correct status
         Return:
             returnValue - Returns main.TRUE only if all flows are in
-                          ADDED state or PENDING_ADD if the PENDING_ADD
+                          ADDED state or PENDING_ADD if the isPENDING
                           parameter is set true, return main.FALSE otherwise.
         """
         try:
-            tempFlows = json.loads( self.flows() )
-            #print tempFlows[0]
-            returnValue = main.TRUE
+            states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
+            checkedStates = []
+            statesCount = [0, 0, 0, 0]
+            for s in states:
+                rawFlows = self.flows( state=s, timeout = timeout )
+                checkedStates.append( json.loads( rawFlows ) )
+            for i in range( len( states ) ):
+                for c in checkedStates[i]:
+                    try:
+                        statesCount[i] += int( c.get( "flowCount" ) )
+                    except TypeError:
+                        main.log.exception( "Json object not as expected" )
+                main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
 
-            if isPENDING_ADD:
-                for device in tempFlows:
-                    for flow in device.get( 'flows' ):
-                        if flow.get( 'state' ) != 'ADDED' and \
-                            flow.get( 'state' ) != 'PENDING_ADD':
-
-                            main.log.info( self.name + ": flow Id: " +
-                                           str( flow.get( 'groupId' ) ) +
-                                           " | state:" +
-                                           str( flow.get( 'state' ) ) )
-                            returnValue = main.FALSE
+            # We want to count PENDING_ADD if isPENDING is true
+            if isPENDING:
+                if statesCount[1] + statesCount[2] + statesCount[3] > 0:
+                    return main.FALSE
             else:
-                for device in tempFlows:
-                    for flow in device.get( 'flows' ):
-                        if flow.get( 'state' ) != 'ADDED':
-
-                            main.log.info( self.name + ": flow Id: " +
-                                           str( flow.get( 'groupId' ) ) +
-                                           " | state:" +
-                                           str( flow.get( 'state' ) ) )
-                            returnValue = main.FALSE
-
-            return returnValue
-        except TypeError:
-            main.log.exception( self.name + ": Object not as expected" )
+                if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
+                    return main.FALSE
+            return main.TRUE
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
             return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
@@ -2055,50 +2128,105 @@
             main.cleanup()
             main.exit()
 
-    def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
-                         numMult="", appId="", report=True ):
+    def pushTestIntents( self, ingress, egress, batchSize, offset="",
+                         options="", timeout=10, background = False ):
         """
         Description:
             Push a number of intents in a batch format to
             a specific point-to-point intent definition
         Required:
-            * dpidSrc: specify source dpid
-            * dpidDst: specify destination dpid
-            * numIntents: specify number of intents to push
+            * ingress: specify source dpid
+            * egress: specify destination dpid
+            * batchSize: specify number of intents to push
         Optional:
-            * numMult: number multiplier for multiplying
-              the number of intents specified
-            * appId: specify the application id init to further
-              modularize the intents
-            * report: default True, returns latency information
+            * offset: the keyOffset is where the next batch of intents
+                      will be installed
+        Returns: If failed to push test intents, it will returen None,
+                 if successful, return true.
+                 Timeout expection will return None,
+                 TypeError will return false
+                 other expections will exit()
         """
         try:
-            cmd = "push-test-intents " +\
-                  str( dpidSrc ) + " " + str( dpidDst ) + " " +\
-                  str( numIntents )
-            if numMult:
-                cmd += " " + str( numMult )
-                # If app id is specified, then numMult
-                # must exist because of the way this command
-                if appId:
-                    cmd += " " + str( appId )
-            handle = self.sendline( cmd )
-            if report:
-                latResult = []
-                main.log.info( handle )
-                # Split result by newline
-                newline = handle.split( "\r\r\n" )
-                # Ignore the first object of list, which is empty
-                newline = newline[ 1: ]
-                # Some sloppy parsing method to get the latency
-                for result in newline:
-                    result = result.split( ": " )
-                    # Append the first result of second parse
-                    latResult.append( result[ 1 ].split( " " )[ 0 ] )
-                main.log.info( latResult )
-                return latResult
+            if background:
+                back = "&"
             else:
-                return main.TRUE
+                back = ""
+            cmd = "push-test-intents {} {} {} {} {} {}".format( options,
+                                                                ingress,
+                                                                egress,
+                                                                batchSize,
+                                                                offset,
+                                                                back )
+            response = self.sendline( cmd, timeout=timeout )
+            assert "Command not found:" not in response, response
+            main.log.info( response )
+            if response == None:
+                return None
+
+            # TODO: We should handle if there is failure in installation
+            return main.TRUE
+
+        except AssertionError:
+            main.log.exception( "" )
+            return None
+        except pexpect.TIMEOUT:
+            main.log.error( self.name + ": ONOS timeout" )
+            return None
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except 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 getTotalFlowsNum( self ):
+        """
+        Description:
+            Get the total number of flows, include every states.
+        Return:
+            The number of flows
+        """
+        try:
+            cmd = "summary -j"
+            response = self.sendline( cmd )
+            if response == None:
+                return  -1
+            response = json.loads( response )
+            return int( response.get("flows") )
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
+        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( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def getTotalIntentsNum( self ):
+        """
+        Description:
+            Get the total number of intents, include every states.
+        Return:
+            The number of intents
+        """
+        try:
+            cmd = "summary -j"
+            response = self.sendline( cmd )
+            if response == None:
+                return  -1
+            response = json.loads( response )
+            return int( response.get("intents") )
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -2123,7 +2251,11 @@
             if jsonFormat:
                 cmdStr += " -j"
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -2148,6 +2280,7 @@
             if jsonFormat:
                 cmdStr += " -j"
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             if handle:
                 return handle
             elif jsonFormat:
@@ -2155,6 +2288,9 @@
                 return '{}'
             else:
                 return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -2216,7 +2352,11 @@
             cmdStr = "flows any " + str( deviceId ) + " | " +\
                      "grep 'state=ADDED' | wc -l"
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
@@ -2292,9 +2432,8 @@
             nodesJson = json.loads( nodesStr )
             idList = [ node.get('id') for node in nodesJson ]
             return idList
-
-        except TypeError:
-            main.log.exception( self.name + ": Object not as expected" )
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
             return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
@@ -2324,8 +2463,8 @@
                     if dpid in device[ 'id' ]:
                         return device
             return None
-        except TypeError:
-            main.log.exception( self.name + ": Object not as expected" )
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
             return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
@@ -2421,6 +2560,7 @@
                     str( onosNode ) + " " +\
                     str( role )
                 handle = self.sendline( cmdStr )
+                assert "Command not found:" not in handle, handle
                 if re.search( "Error", handle ):
                     # end color output to escape any colours
                     # from the cli
@@ -2432,6 +2572,9 @@
                 main.log.error( "Invalid 'role' given to device_role(). " +
                                 "Value was '" + str(role) + "'." )
                 return main.FALSE
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -2456,7 +2599,11 @@
             if jsonFormat:
                 cmdStr += " -j"
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -2481,6 +2628,7 @@
         try:
             cmdStr = "election-test-leader"
             response = self.sendline( cmdStr )
+            assert "Command not found:" not in response, response
             # Leader
             leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
                 "app\sis\s(?P<node>.+)\."
@@ -2509,6 +2657,9 @@
                                 ": " + "unexpected response" )
                 main.log.error( repr( response ) )
                 return main.FALSE
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return main.FALSE
@@ -2532,6 +2683,7 @@
         try:
             cmdStr = "election-test-run"
             response = self.sendline( cmdStr )
+            assert "Command not found:" not in response, response
             # success
             successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
                 "Election\sapp."
@@ -2550,6 +2702,9 @@
                                 ": " + "unexpected response" )
                 main.log.error( repr( response ) )
                 return main.FALSE
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return main.FALSE
@@ -2574,6 +2729,7 @@
         try:
             cmdStr = "election-test-withdraw"
             response = self.sendline( cmdStr )
+            assert "Command not found:" not in response, response
             # success
             successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
                 "\sthe\sElection\sapp."
@@ -2591,6 +2747,9 @@
                                 self.name + ": " + "unexpected response" )
                 main.log.error( repr( response ) )
                 return main.FALSE
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return main.FALSE
@@ -2612,11 +2771,15 @@
             dpid = str( dpid )
             cmdStr = "onos:ports -e " + dpid + " | wc -l"
             output = self.sendline( cmdStr )
+            assert "Command not found:" not in output, output
             if re.search( "No such device", output ):
                 main.log.error( "Error in getting ports" )
                 return ( output, "Error" )
             else:
                 return output
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return ( output, "Error" )
@@ -2638,11 +2801,15 @@
             dpid = str( dpid )
             cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
             output = self.sendline( cmdStr )
+            assert "Command not found:" not in output, output
             if re.search( "No such device", output ):
                 main.log.error( "Error in getting ports " )
                 return ( output, "Error " )
             else:
                 return output
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return ( output, "Error " )
@@ -2663,11 +2830,15 @@
         try:
             cmdStr = "onos:intents | grep id="
             output = self.sendline( cmdStr )
+            assert "Command not found:" not in output, output
             if re.search( "Error", output ):
                 main.log.error( "Error in getting ports" )
                 return ( output, "Error" )
             else:
                 return output
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return ( output, "Error" )
@@ -2693,8 +2864,8 @@
             out = [ ( i, states.count( i ) ) for i in set( states ) ]
             main.log.info( dict( out ) )
             return dict( out )
-        except TypeError:
-            main.log.exception( self.name + ": Object not as expected" )
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
             return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
@@ -2717,7 +2888,11 @@
             if jsonFormat:
                 cmdStr += " -j"
             output = self.sendline( cmdStr )
+            assert "Command not found:" not in output, output
             return output
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -2742,7 +2917,11 @@
             if jsonFormat:
                 cmdStr += " -j"
             output = self.sendline( cmdStr )
+            assert "Command not found:" not in output, output
             return output
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -2756,7 +2935,7 @@
             main.cleanup()
             main.exit()
 
-    def specificLeaderCandidate(self,topic):
+    def specificLeaderCandidate( self, topic ):
         """
         Returns a list in format [leader,candidate1,candidate2,...] for a given
         topic parameter and an empty list if the topic doesn't exist
@@ -2765,18 +2944,22 @@
         """
         try:
             cmdStr = "onos:leaders -c -j"
-            output = self.sendline( cmdStr )
-            output = json.loads(output)
+            rawOutput = self.sendline( cmdStr )
+            assert "Command not found:" not in rawOutput, rawOutput
+            output = json.loads( rawOutput )
             results = []
             for dict in output:
                 if dict["topic"] == topic:
                     leader = dict["leader"]
-                    candidates = re.split(", ",dict["candidates"][1:-1])
-                    results.append(leader)
-                    results.extend(candidates)
+                    candidates = re.split( ", ", dict["candidates"][1:-1] )
+                    results.append( leader )
+                    results.extend( candidates )
             return results
-        except TypeError:
-            main.log.exception( self.name + ": Object not as expected" )
+        except AssertionError:
+            main.log.exception( "" )
+            return None
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
             return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
@@ -2797,7 +2980,11 @@
             if jsonFormat:
                 cmdStr += " -j"
             output = self.sendline( cmdStr )
+            assert "Command not found:" not in output, output
             return output
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -2831,7 +3018,11 @@
             if jsonFormat:
                 cmdStr += " -j"
             output = self.sendline( cmdStr )
+            assert "Command not found:" not in output, output
             return output
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -2860,12 +3051,12 @@
             if jsonFormat:
                 cmdStr += " -j"
             output = self.sendline( cmdStr )
-            assert "Error executing command" not in output
+            assert "Command not found:" not in output, output
+            assert "Error executing command" not in output, output
             return output
         # FIXME: look at specific exceptions/Errors
         except AssertionError:
-            main.log.error( "Error in processing onos:app command: " +
-                            str( output ) )
+            main.log.exception( "Error in processing onos:app command." )
             return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -2909,8 +3100,9 @@
                 main.log.error( "Unexpected state from 'onos:apps': " +
                                 str( state ) )
                 return state
-        except TypeError:
-            main.log.exception( self.name + ": Object not as expected" )
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
+            main.stop()
             return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
@@ -3167,11 +3359,11 @@
             if jsonFormat:
                 cmdStr += " -j"
             output = self.sendline( cmdStr )
-            assert "Error executing command" not in output
+            assert "Command not found:" not in output, output
+            assert "Error executing command" not in output, output
             return output
         except AssertionError:
-            main.log.error( "Error in processing onos:app-ids command: " +
-                            str( output ) )
+            main.log.exception( "Error in processing onos:app-ids command." )
             return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -3201,17 +3393,17 @@
         """
         try:
             bail = False
-            ids = self.appIDs( jsonFormat=True )
-            if ids:
-                ids = json.loads( ids )
+            rawJson = self.appIDs( jsonFormat=True )
+            if rawJson:
+                ids = json.loads( rawJson )
             else:
-                main.log.error( "app-ids returned nothing:" + repr( ids ) )
+                main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
                 bail = True
-            apps = self.apps( jsonFormat=True )
-            if apps:
-                apps = json.loads( apps )
+            rawJson = self.apps( jsonFormat=True )
+            if rawJson:
+                apps = json.loads( rawJson )
             else:
-                main.log.error( "apps returned nothing:" + repr( apps ) )
+                main.log.error( "apps returned nothing:" + repr( rawJson ) )
                 bail = True
             if bail:
                 return main.FALSE
@@ -3260,8 +3452,8 @@
                                                   separators=( ',', ': ' ) ) )
                     result = main.FALSE
             return result
-        except ( ValueError, TypeError ):
-            main.log.exception( self.name + ": Object not as expected" )
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
             return main.ERROR
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
@@ -3304,11 +3496,11 @@
             elif short:
                 baseStr += " -s"
             output = self.sendline( baseStr + cmdStr + componentStr )
-            assert "Error executing command" not in output
+            assert "Command not found:" not in output, output
+            assert "Error executing command" not in output, output
             return output
         except AssertionError:
-            main.log.error( "Error in processing 'cfg get' command: " +
-                            str( output ) )
+            main.log.exception( "Error in processing 'cfg get' command." )
             return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -3345,7 +3537,8 @@
             if value is not None:
                 cmdStr += " " + str( value )
             output = self.sendline( baseStr + cmdStr )
-            assert "Error executing command" not in output
+            assert "Command not found:" not in output, output
+            assert "Error executing command" not in output, output
             if value and check:
                 results = self.getCfg( component=str( component ),
                                        propName=str( propName ),
@@ -3354,7 +3547,7 @@
                 try:
                     jsonOutput = json.loads( results )
                     current = jsonOutput[ 'value' ]
-                except ( ValueError, TypeError ):
+                except ( TypeError, ValueError ):
                     main.log.exception( "Error parsing cfg output" )
                     main.log.error( "output:" + repr( results ) )
                     return main.FALSE
@@ -3363,11 +3556,10 @@
                 return main.FALSE
             return main.TRUE
         except AssertionError:
-            main.log.error( "Error in processing 'cfg set' command: " +
-                            str( output ) )
+            main.log.exception( "Error in processing 'cfg set' command." )
             return main.FALSE
-        except TypeError:
-            main.log.exception( self.name + ": Object not as expected" )
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
             return main.FALSE
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
@@ -3396,6 +3588,7 @@
         try:
             cmdStr = "set-test-add " + str( setName ) + " " + str( values )
             output = self.sendline( cmdStr )
+            assert "Command not found:" not in output, output
             try:
                 # TODO: Maybe make this less hardcoded
                 # ConsistentMap Exceptions
@@ -3424,8 +3617,7 @@
                 main.log.debug( self.name + " actual: " + repr( output ) )
                 return main.ERROR
         except AssertionError:
-            main.log.error( "Error in processing '" + cmdStr + "' command: " +
-                            str( output ) )
+            main.log.exception( "Error in processing '" + cmdStr + "' command. " )
             return main.ERROR
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -3478,7 +3670,8 @@
                                "seconds before retrying." )
                 time.sleep( retryTime )  # Due to change in mastership
                 output = self.sendline( cmdStr )
-            assert "Error executing command" not in output
+            assert "Command not found:" not in output, output
+            assert "Error executing command" not in output, output
             main.log.info( self.name + ": " + output )
             if clear:
                 pattern = "Set " + str( setName ) + " cleared"
@@ -3513,8 +3706,7 @@
             main.log.debug( self.name + " actual: " + repr( output ) )
             return main.ERROR
         except AssertionError:
-            main.log.error( "Error in processing '" + cmdStr + "' command: " +
-                            str( output ) )
+            main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
             return main.ERROR
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -3577,7 +3769,8 @@
                                "seconds before retrying." )
                 time.sleep( retryTime )  # Due to change in mastership
                 output = self.sendline( cmdStr )
-            assert "Error executing command" not in output
+            assert "Command not found:" not in output, output
+            assert "Error executing command" not in output, output
             main.log.info( self.name + ": " + output )
 
             if length == 0:
@@ -3620,8 +3813,7 @@
                 main.log.debug( self.name + " actual: " + repr( output ) )
                 return main.ERROR
         except AssertionError:
-            main.log.error( "Error in processing '" + cmdStr + "' command: " +
-                            str( output ) )
+            main.log.exception( "Error in processing '" + cmdStr + "' command." )
             return main.ERROR
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -3670,7 +3862,8 @@
                                "seconds before retrying." )
                 time.sleep( retryTime )  # Due to change in mastership
                 output = self.sendline( cmdStr )
-            assert "Error executing command" not in output
+            assert "Command not found:" not in output, output
+            assert "Error executing command" not in output, output
             main.log.info( self.name + ": " + output )
             match = re.search( pattern, output )
             if match:
@@ -3692,8 +3885,7 @@
                 main.log.debug( self.name + " actual: " + repr( output ) )
                 return None
         except AssertionError:
-            main.log.error( "Error in processing '" + cmdStr + "' command: " +
-                            str( output ) )
+            main.log.exception( "Error in processing '" + cmdStr + "' command." )
             return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -3723,12 +3915,12 @@
             if jsonFormat:
                 cmdStr += " -j"
             output = self.sendline( cmdStr )
-            assert "Error executing command" not in output
+            assert "Command not found:" not in output, output
+            assert "Error executing command" not in output, output
             main.log.info( self.name + ": " + output )
             return output
         except AssertionError:
-            main.log.error( "Error in processing 'counters' command: " +
-                            str( output ) )
+            main.log.exception( "Error in processing 'counters' command." )
             return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -3779,7 +3971,8 @@
                                "seconds before retrying." )
                 time.sleep( retryTime )  # Due to change in mastership
                 output = self.sendline( cmdStr )
-            assert "Error executing command" not in output
+            assert "Command not found:" not in output, output
+            assert "Error executing command" not in output, output
             main.log.info( self.name + ": " + output )
             pattern = counter + " was updated to (-?\d+)"
             match = re.search( pattern, output )
@@ -3792,8 +3985,7 @@
                 main.log.debug( self.name + " actual: " + repr( output ) )
                 return None
         except AssertionError:
-            main.log.error( "Error in processing '" + cmdStr + "'" +
-                            " command: " + str( output ) )
+            main.log.exception( "Error in processing '" + cmdStr + "' command." )
             return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -3844,7 +4036,8 @@
                                "seconds before retrying." )
                 time.sleep( retryTime )  # Due to change in mastership
                 output = self.sendline( cmdStr )
-            assert "Error executing command" not in output
+            assert "Command not found:" not in output, output
+            assert "Error executing command" not in output, output
             main.log.info( self.name + ": " + output )
             pattern = counter + " was updated to (-?\d+)"
             match = re.search( pattern, output )
@@ -3857,8 +4050,7 @@
                 main.log.debug( self.name + " actual: " + repr( output ) )
                 return None
         except AssertionError:
-            main.log.error( "Error in processing '" + cmdStr + "'" +
-                            " command: " + str( output ) )
+            main.log.exception( "Error in processing '" + cmdStr + "' command." )
             return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -3885,7 +4077,7 @@
             if jsonFormat:
                 cmdStr += " -j"
             handle = self.sendline( cmdStr )
-
+            assert "Command not found:" not in handle, handle
             if re.search( "Error:", handle ):
                 main.log.error( self.name + ": summary() response: " +
                                 str( handle ) )
@@ -3894,6 +4086,9 @@
                                 "summary command" )
                 return main.FALSE
             return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -3927,6 +4122,7 @@
                 cmdStr += "-i "
             cmdStr += keyName
             output = self.sendline( cmdStr )
+            assert "Command not found:" not in output, output
             try:
                 # TODO: Maybe make this less hardcoded
                 # ConsistentMap Exceptions
@@ -3950,6 +4146,9 @@
                     main.log.debug( self.name + " expected: " + pattern )
                     main.log.debug( self.name + " actual: " + repr( output ) )
                     return None
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -3992,6 +4191,7 @@
                 cmdStr += "-i "
             cmdStr += numKeys + " " + value
             output = self.sendline( cmdStr )
+            assert "Command not found:" not in output, output
             try:
                 # TODO: Maybe make this less hardcoded
                 # ConsistentMap Exceptions
@@ -4012,13 +4212,18 @@
                     results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
                 elif updated:
                     results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
-                                                            'oldValue': updated.groupdict()[ 'oldValue' ] }
+                                                                'oldValue': updated.groupdict()[ 'oldValue' ] }
                 else:
                     main.log.error( self.name + ": transactionlMapGet did not" +
                                     " match expected output." )
-                    main.log.debug( self.name + " expected: " + pattern )
+                    main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
+                                                                        newPattern,
+                                                                        updatedPattern ) )
                     main.log.debug( self.name + " actual: " + repr( output ) )
             return results
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -4031,6 +4236,7 @@
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
+
     def maps( self, jsonFormat=True ):
         """
         Description: Returns result of onos:maps
@@ -4042,7 +4248,11 @@
             if jsonFormat:
                 cmdStr += " -j"
             handle = self.sendline( cmdStr )
+            assert "Command not found:" not in handle, handle
             return handle
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -4065,7 +4275,11 @@
             if jsonFormat:
                 cmd += "-j "
             response = self.sendline( cmd + uri )
+            assert "Command not found:" not in response, response
             return response
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -4122,15 +4336,15 @@
                         raise TypeError
                 else:
                     cmd += " {}:{}:{}".format( proto, item, port )
-
             response = self.sendline( cmd )
-
+            assert "Command not found:" not in response, response
             if "Error" in response:
                 main.log.error( response )
                 return main.FALSE
-
             return main.TRUE
-
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return main.FALSE
@@ -4163,12 +4377,14 @@
             for d in device:
                 time.sleep( 1 )
                 response = self.sendline( "device-remove {}".format( d ) )
+                assert "Command not found:" not in response, response
                 if "Error" in response:
                     main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
                     return main.FALSE
-
             return main.TRUE
-
+        except AssertionError:
+            main.log.exception( "" )
+            return main.FALSE
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return main.FALSE
@@ -4201,12 +4417,14 @@
             for h in host:
                 time.sleep( 1 )
                 response = self.sendline( "host-remove {}".format( h ) )
+                assert "Command not found:" not in response, response
                 if "Error" in response:
                     main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
                     return main.FALSE
-
             return main.TRUE
-
+        except AssertionError:
+            main.log.exception( "" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return main.FALSE
@@ -4219,3 +4437,39 @@
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
+
+    def link( self, begin, end, state ):
+        '''
+        Description:
+            Bring link down or up in the null-provider.
+        params:
+            begin - (string) One end of a device or switch.
+            end - (string) the other end of the device or switch
+        returns:
+            main.TRUE if no exceptions were thrown and no Errors are
+            present in the resoponse. Otherwise, returns main.FALSE
+        '''
+        try:
+            cmd =  "null-link null:{} null:{} {}".format( begin, end, state )
+            response = self.sendline( cmd, showResponse=True )
+            assert "Command not found:" not in response, response
+            if "Error" in response or "Failure" in response:
+                main.log.error( response )
+                return main.FALSE
+            return main.TRUE
+        except AssertionError:
+            main.log.exception( "" )
+            return None
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            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( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
diff --git a/TestON/drivers/common/cli/onosdriver.py b/TestON/drivers/common/cli/onosdriver.py
index ed6e538..b55f98a 100644
--- a/TestON/drivers/common/cli/onosdriver.py
+++ b/TestON/drivers/common/cli/onosdriver.py
@@ -192,22 +192,29 @@
             ret = main.TRUE
             self.handle.sendline( "onos-package" )
             self.handle.expect( "onos-package" )
-            i = self.handle.expect( ["tar.gz", "\$", "Unknown options"], opTimeout )
+            i = self.handle.expect( [ "Downloading",
+                                      "tar.gz",
+                                      "\$",
+                                      "Unknown options" ],
+                                    opTimeout )
             handle = str( self.handle.before + self.handle.after )
             if i == 0:
-                self.handle.expect( "\$" )
+                # Give more time to download the file
+                self.handle.expect( "\$", opTimeout * 2 )
                 handle += str( self.handle.before )
             elif i == 1:
+                self.handle.expect( "\$" )
+                handle += str( self.handle.before )
+            elif i == 2:
                 # This seems to be harmless, but may be a problem
                 main.log.warn( "onos-package output not as expected" )
-            elif i == 2:
+            elif i == 3:
                 # Incorrect usage
                 main.log.error( "onos-package does not recognize the given options" )
                 self.handle.expect( "\$" )
                 handle += str( self.handle.before )
                 ret = main.FALSE
-            main.log.info( "onos-package command returned: " +
-                           handle )
+            main.log.info( "onos-package command returned: " + handle )
             # As long as the sendline does not time out,
             # return true. However, be careful to interpret
             # the results of the onos-package command return
@@ -828,50 +835,36 @@
         configName = 'org.onosproject.myapp'
         configParam = 'appSetting 1'
         """
-        for i in range(5):
-            try:
-                cfgStr = ( "onos "+str(ONOSIp)+" cfg set "+
-                           str(configName) + " " +
-                           str(configParam)
-                         )
+        try:
+            cfgStr = "onos {} cfg set {} {}".format( ONOSIp,
+                                                     configName,
+                                                     configParam )
+            self.handle.sendline( "" )
+            self.handle.expect( ":~" )
+            self.handle.sendline( cfgStr )
+            self.handle.expect("cfg set")
+            self.handle.expect( ":~" )
 
-                self.handle.sendline( "" )
-                self.handle.expect( ":~" )
-                self.handle.sendline( cfgStr )
-                self.handle.expect("cfg set")
-                self.handle.expect( ":~" )
+            paramValue = configParam.split(" ")[1]
+            paramName = configParam.split(" ")[0]
 
-                paramValue = configParam.split(" ")[1]
-                paramName = configParam.split(" ")[0]
+            checkStr = 'onos {} cfg get " {} {} " '.format( ONOSIp, configName, paramName )
 
-                checkStr = ( "onos " + str(ONOSIp) + """ cfg get " """ + str(configName) + " " + paramName + """ " """)
+            self.handle.sendline( checkStr )
+            self.handle.expect( ":~" )
 
-                self.handle.sendline( checkStr )
-                self.handle.expect( ":~" )
-
-                if "value=" + paramValue + "," in self.handle.before:
-                    main.log.info("cfg " + configName + " successfully set to " + configParam)
-                    return main.TRUE
-
-            except pexpect.ExceptionPexpect as e:
-                main.log.exception( self.name + ": Pexpect exception found: " )
-                main.log.error( self.name + ":    " + self.handle.before )
-                main.cleanup()
-                main.exit()
-            except Exception:
-                main.log.exception( self.name + ": Uncaught exception!" )
-                main.cleanup()
-                main.exit()
-
-            time.sleep(5)
-
-        main.log.error("CFG SET FAILURE: " + configName + " " + configParam )
-        main.ONOSbench.handle.sendline("onos $OC1 cfg get")
-        main.ONOSbench.handle.expect("\$")
-        print main.ONOSbench.handle.before
-        main.ONOSbench.logReport( ONOSIp, ["ERROR","WARN","EXCEPT"], "d")
-        return main.FALSE
-
+            if "value=" + paramValue + "," in self.handle.before:
+                main.log.info("cfg " + configName + " successfully set to " + configParam)
+                return main.TRUE
+        except pexpect.ExceptionPexpect as e:
+            main.log.exception( self.name + ": Pexpect exception found: " )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def onosCli( self, ONOSIp, cmdstr ):
         """
@@ -2049,64 +2042,73 @@
         return sorted( self.onosIps.values() )
 
     def logReport( self, nodeIp, searchTerms, outputMode="s" ):
-        '''
-            - accepts either a list or a string for "searchTerms" these
-              terms will be searched for in the log and have their
-              instances counted
+        """
+        Searches the latest ONOS log file for the given search terms and
+        prints the total occurances of each term. Returns to combined total of
+        all occurances.
 
-            - nodeIp is the ip of the node whos log is to be scanned
+        Arguments:
+            * nodeIp - The ip of the ONOS node where the log is located
+            * searchTerms - A string to grep for or a list of strings to grep
+                            for in the ONOS log. Will print out the number of
+                            occurances for each term.
+        Optional Arguments:
+            * outputMode - 's' or 'd'. If 'd' will print the last 5 lines
+                           containing each search term as well as the total
+                           number of occurances of each term. Defaults to 's',
+                           which prints the simple output of just the number
+                           of occurances for each term.
+        """
+        try:
+            main.log.info( " Log Report for {} ".format( nodeIp ).center( 70, '=' ) )
+            if type( searchTerms ) is str:
+                searchTerms = [searchTerms]
+            numTerms = len( searchTerms )
+            outputMode = outputMode.lower()
 
-            - output modes:
-                "s" -   Simple. Quiet output mode that just prints
-                        the occurences of each search term
-
-                "d" -   Detailed. Prints number of occurences as well as the entire
-                        line for each of the last 5 occurences
-
-            - returns total of the number of instances of all search terms
-        '''
-        main.log.info("========================== Log Report ===========================\n")
-
-        if type(searchTerms) is str:
-            searchTerms = [searchTerms]
-
-        logLines = [ [" "] for i in range(len(searchTerms)) ]
-
-        for term in range(len(searchTerms)):
-            logLines[term][0] = searchTerms[term]
-
-        totalHits = 0
-        for term in range(len(searchTerms)):
-            cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep " + searchTerms[term]
-            self.handle.sendline(cmd)
-            self.handle.expect(":~")
-            before = (self.handle.before).splitlines()
-
-            count = [searchTerms[term],0]
-
-            for line in before:
-                if searchTerms[term] in line and "grep" not in line:
-                    count[1] += 1
-                    if before.index(line) > ( len(before) - 7 ):
-                        logLines[term].append(line)
-
-            main.log.info( str(count[0]) + ": " + str(count[1]) )
-            if term == len(searchTerms)-1:
-                print("\n")
-            totalHits += int(count[1])
-
-        if outputMode != "s" and outputMode != "S":
-            outputString = ""
-            for i in logLines:
-                outputString = i[0] + ": \n"
-                for x in range(1,len(i)):
-                    outputString += ( i[x] + "\n" )
-
-                if outputString != (i[0] + ": \n"):
-                    main.log.info(outputString)
-
-        main.log.info("================================================================\n")
-        return totalHits
+            totalHits = 0
+            logLines = []
+            for termIndex in range( numTerms ):
+                term = searchTerms[termIndex]
+                logLines.append( [term] )
+                cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep " + term
+                self.handle.sendline( cmd )
+                self.handle.expect( ":~" )
+                before = self.handle.before.splitlines()
+                count = 0
+                for line in before:
+                    if term in line and "grep" not in line:
+                        count += 1
+                        if before.index( line ) > ( len( before ) - 7 ):
+                            logLines[termIndex].append( line )
+                main.log.info( "{}: {}".format( term, count ) )
+                totalHits += count
+                if termIndex == numTerms - 1:
+                    print "\n"
+            if outputMode != "s":
+                outputString = ""
+                for term in logLines:
+                    outputString = term[0] + ": \n"
+                    for line in range( 1, len( term ) ):
+                        outputString += ( "\t" + term[line] + "\n" )
+                    if outputString != ( term[0] + ": \n" ):
+                        main.log.info( outputString )
+            main.log.info( "=" * 70 )
+            return totalHits
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except pexpect.TIMEOUT:
+            main.log.error( self.name + ": TIMEOUT exception found" )
+            main.log.error( self.name + ":     " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def copyMininetFile( self, fileName, localPath, userName, ip,
                          mnPath='~/mininet/custom/', timeout = 60 ):
diff --git a/TestON/tests/HAclusterRestart/HAclusterRestart.py b/TestON/tests/HAclusterRestart/HAclusterRestart.py
index 58b113c..7b19efc 100644
--- a/TestON/tests/HAclusterRestart/HAclusterRestart.py
+++ b/TestON/tests/HAclusterRestart/HAclusterRestart.py
@@ -216,9 +216,7 @@
             for node in main.nodes:
                 started = main.ONOSbench.isup( node.ip_address )
                 if not started:
-                    main.log.error( node.name + " didn't start!" )
-                    main.ONOSbench.onosStop( node.ip_address )
-                    main.ONOSbench.onosStart( node.ip_address )
+                    main.log.error( node.name + " hasn't started" )
                 onosIsupResult = onosIsupResult and started
             if onosIsupResult == main.TRUE:
                 break
@@ -2258,10 +2256,14 @@
                     "Error" not in devices[ controller ] and\
                     "Error" not in ports[ controller ]:
 
-                    currentDevicesResult = main.Mininet1.compareSwitches(
-                            mnSwitches,
-                            json.loads( devices[ controller ] ),
-                            json.loads( ports[ controller ] ) )
+                    try:
+                        currentDevicesResult = main.Mininet1.compareSwitches(
+                                mnSwitches,
+                                json.loads( devices[ controller ] ),
+                                json.loads( ports[ controller ] ) )
+                    except ( TypeError, ValueError ) as e:
+                        main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
+                            devices[ controller ], ports[ controller ] ) )
                 else:
                     currentDevicesResult = main.FALSE
                 utilities.assert_equals( expect=main.TRUE,
diff --git a/TestON/tests/HAkillNodes/HAkillNodes.py b/TestON/tests/HAkillNodes/HAkillNodes.py
index d31cd30..c1f979a 100644
--- a/TestON/tests/HAkillNodes/HAkillNodes.py
+++ b/TestON/tests/HAkillNodes/HAkillNodes.py
@@ -244,9 +244,7 @@
             for node in main.nodes:
                 started = main.ONOSbench.isup( node.ip_address )
                 if not started:
-                    main.log.error( node.name + " didn't start!" )
-                    main.ONOSbench.onosStop( node.ip_address )
-                    main.ONOSbench.onosStart( node.ip_address )
+                    main.log.error( node.name + " hasn't started" )
                 onosIsupResult = onosIsupResult and started
             if onosIsupResult == main.TRUE:
                 break
@@ -2255,10 +2253,14 @@
                     "Error" not in devices[ controller ] and\
                     "Error" not in ports[ controller ]:
 
-                    currentDevicesResult = main.Mininet1.compareSwitches(
-                            mnSwitches,
-                            json.loads( devices[ controller ] ),
-                            json.loads( ports[ controller ] ) )
+                    try:
+                        currentDevicesResult = main.Mininet1.compareSwitches(
+                                mnSwitches,
+                                json.loads( devices[ controller ] ),
+                                json.loads( ports[ controller ] ) )
+                    except ( TypeError, ValueError ) as e:
+                        main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
+                            devices[ controller ], ports[ controller ] ) )
                 else:
                     currentDevicesResult = main.FALSE
                 utilities.assert_equals( expect=main.TRUE,
diff --git a/TestON/tests/HAsanity/HAsanity.py b/TestON/tests/HAsanity/HAsanity.py
index ed37e33..f58073f 100644
--- a/TestON/tests/HAsanity/HAsanity.py
+++ b/TestON/tests/HAsanity/HAsanity.py
@@ -212,9 +212,7 @@
             for node in main.nodes:
                 started = main.ONOSbench.isup( node.ip_address )
                 if not started:
-                    main.log.error( node.name + " didn't start!" )
-                    main.ONOSbench.onosStop( node.ip_address )
-                    main.ONOSbench.onosStart( node.ip_address )
+                    main.log.error( node.name + " hasn't started" )
                 onosIsupResult = onosIsupResult and started
             if onosIsupResult == main.TRUE:
                 break
@@ -2151,10 +2149,14 @@
                     "Error" not in devices[ controller ] and\
                     "Error" not in ports[ controller ]:
 
-                    currentDevicesResult = main.Mininet1.compareSwitches(
-                            mnSwitches,
-                            json.loads( devices[ controller ] ),
-                            json.loads( ports[ controller ] ) )
+                    try:
+                        currentDevicesResult = main.Mininet1.compareSwitches(
+                                mnSwitches,
+                                json.loads( devices[ controller ] ),
+                                json.loads( ports[ controller ] ) )
+                    except ( TypeError, ValueError ) as e:
+                        main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
+                            devices[ controller ], ports[ controller ] ) )
                 else:
                     currentDevicesResult = main.FALSE
                 utilities.assert_equals( expect=main.TRUE,
diff --git a/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.py b/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.py
index 2f7f922..1587563 100644
--- a/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.py
+++ b/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.py
@@ -1476,10 +1476,14 @@
                     "Error" not in devices[ controller ] and\
                     "Error" not in ports[ controller ]:
 
-                    currentDevicesResult = main.Mininet1.compareSwitches(
-                            mnSwitches,
-                            json.loads( devices[ controller ] ),
-                            json.loads( ports[ controller ] ) )
+                    try:
+                        currentDevicesResult = main.Mininet1.compareSwitches(
+                                mnSwitches,
+                                json.loads( devices[ controller ] ),
+                                json.loads( ports[ controller ] ) )
+                    except ( TypeError, ValueError ) as e:
+                        main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
+                            devices[ controller ], ports[ controller ] ) )
                 else:
                     currentDevicesResult = main.FALSE
                 utilities.assert_equals( expect=main.TRUE,
diff --git a/TestON/tests/HAstopNodes/HAstopNodes.py b/TestON/tests/HAstopNodes/HAstopNodes.py
index b7f1e77..edcc4d1 100644
--- a/TestON/tests/HAstopNodes/HAstopNodes.py
+++ b/TestON/tests/HAstopNodes/HAstopNodes.py
@@ -237,9 +237,7 @@
             for node in main.nodes:
                 started = main.ONOSbench.isup( node.ip_address )
                 if not started:
-                    main.log.error( node.name + " didn't start!" )
-                    main.ONOSbench.onosStop( node.ip_address )
-                    main.ONOSbench.onosStart( node.ip_address )
+                    main.log.error( node.name + " hasn't started" )
                 onosIsupResult = onosIsupResult and started
             if onosIsupResult == main.TRUE:
                 break
@@ -2244,10 +2242,14 @@
                     "Error" not in devices[ controller ] and\
                     "Error" not in ports[ controller ]:
 
-                    currentDevicesResult = main.Mininet1.compareSwitches(
-                            mnSwitches,
-                            json.loads( devices[ controller ] ),
-                            json.loads( ports[ controller ] ) )
+                    try:
+                        currentDevicesResult = main.Mininet1.compareSwitches(
+                                mnSwitches,
+                                json.loads( devices[ controller ] ),
+                                json.loads( ports[ controller ] ) )
+                    except ( TypeError, ValueError ) as e:
+                        main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
+                            devices[ controller ], ports[ controller ] ) )
                 else:
                     currentDevicesResult = main.FALSE
                 utilities.assert_equals( expect=main.TRUE,
diff --git a/TestON/tests/SAMPstartTemplate/SAMPstartTemplate.py b/TestON/tests/SAMPstartTemplate/SAMPstartTemplate.py
index 2122570..b6184da 100644
--- a/TestON/tests/SAMPstartTemplate/SAMPstartTemplate.py
+++ b/TestON/tests/SAMPstartTemplate/SAMPstartTemplate.py
@@ -230,7 +230,7 @@
         main.log.case( "Start Mininet topology" )
 
         main.step( "Starting Mininet Topology" )
-        topoResult = main.Mininet1.startNet( topoFile=topology )
+        topoResult = main.Mininet1.startNet( topoFile=main.dependencyPath + main.topology )
         stepResult = topoResult
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
diff --git a/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.params b/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.params
index 7a08c48..2324185 100755
--- a/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.params
+++ b/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.params
@@ -1,13 +1,14 @@
 <PARAMS>
 
-    # 0-init
-    # 1-setup
+    # 1-init
+    # 2-setup
     # 10-null provider setup
     # 11-mininet setup
-    # 20-pushing intents,
-    # 21-rerouting intents
-    # 0,1,11,20,1,11,21,1,10,20,1,10,21,100
-    <testcases>0,1,11,20,1,11,21,1,10,20,1,10,21,100</testcases>
+    # 20-pushing intents, and rerouting intents if reroute is true
+    # 1,2,10,20,2,11,20,100
+    <testcases>1,2,10,20</testcases>
+
+    <reroute>False</reroute>
 
     <SCALE>
         <size>1</size>
@@ -37,24 +38,66 @@
 
     <SLEEP>
         <startup>3</startup>
-        <install>0</install>
-        <verify>0</verify>
+        <install>1</install>
+        <verify>5</verify>
         <reroute>3</reroute>
         # timeout for pexpect
         <timeout>120</timeout>
     </SLEEP>
 
+    <ATTEMPTS>
+        <verify>3</verify>
+        <push>3</push>
+    </ATTEMPTS>
+
     <DATABASE>
-        <file>MaxIntentDB</file>
+        <file>/tmp/MaxIntentDB</file>
         <nic>1gig</nic>
         <node>baremetal</node>
     </DATABASE>
 
-    <TEST>
-        <batch_size>10000</batch_size>
-        <min_intents>800000</min_intents>
-        <max_intents>1000000</max_intents>
-        <check_interval>20000</check_interval>
-    </TEST>
+    <LINK>
+        <ingress>0000000000000001/9</ingress>
+        <egress>0000000000000002/9</egress>
+    </LINK>
+
+    # CASE10
+    <NULL>
+        # CASE20
+        <PUSH>
+            <batch_size>1000</batch_size>
+            <min_intents>10000</min_intents>
+            <max_intents>1000000</max_intents>
+            <check_interval>10000</check_interval>
+        </PUSH>
+
+        # if reroute is true
+        <REROUTE>
+            <batch_size>1000</batch_size>
+            <min_intents>10000</min_intents>
+            <max_intents>1000000</max_intents>
+            <check_interval>100000</check_interval>
+        </REROUTE>
+    </NULL>
+
+    # CASE11
+    <OVS>
+        # CASE20
+        <PUSH>
+            <batch_size>1000</batch_size>
+            <min_intents>10000</min_intents>
+            <max_intents>500000</max_intents>
+            <check_interval>10000</check_interval>
+        </PUSH>
+
+        # if reroute is true
+        <REROUTE>
+            <batch_size>1000</batch_size>
+            <min_intents>10000</min_intents>
+            <max_intents>500000</max_intents>
+            <check_interval>10000</check_interval>
+        </REROUTE>
+    </OVS>
+
 
 </PARAMS>
diff --git a/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.py b/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.py
index 011b275..b4c5ac3 100644
--- a/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.py
+++ b/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.py
@@ -1,13 +1,27 @@
 
 # This is a performance scale intent that test onos to see how many intents can
 # be installed and rerouted using the null provider and mininet.
+'''
+This test will not test on reroute and OVS!!!
+If you need test on reroute or OVS, change the params file
+
+Test information:
+    - BatchSize: 1000
+    - Minimum intents: 10,000
+    - Maximum Intents: 1,000,000
+    - Check Interval: 10,000
+    - Link:
+        - ingress: 0000000000000001/9
+        - egress: 0000000000000002/9
+    - Timeout: 120 Seconds
+'''
 
 class SCPFmaxIntents:
 
     def __init__( self ):
         self.default = ''
 
-    def CASE0( self, main ):
+    def CASE1( self, main ):
         import time
         import os
         import imp
@@ -42,16 +56,20 @@
         main.maxNodes = int( main.params[ 'SCALE' ][ 'max' ] )
         main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
         main.timeout = int(main.params['SLEEP']['timeout'])
-        main.minIntents = int(main.params['TEST']['min_intents'])
-        main.maxIntents = int(main.params['TEST']['max_intents'])
-        main.checkInterval = int(main.params['TEST']['check_interval'])
         main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
         main.installSleep = int( main.params[ 'SLEEP' ][ 'install' ] )
         main.verifySleep = int( main.params[ 'SLEEP' ][ 'verify' ] )
         main.rerouteSleep = int ( main.params['SLEEP']['reroute'] )
-        main.batchSize = int(main.params['TEST']['batch_size'])
+        main.verifyAttempts = int( main.params['ATTEMPTS']['verify'] )
+        main.ingress = main.params['LINK']['ingress']
+        main.egress = main.params['LINK']['egress']
         main.dbFileName = main.params['DATABASE']['file']
         main.cellData = {} # for creating cell file
+        main.reroute = main.params['reroute']
+        if main.reroute == "True":
+            main.reroute = True
+        else:
+            main.reroute = False
         main.CLIs = []
         main.ONOSip = []
         main.maxNumBatch = 0
@@ -127,19 +145,23 @@
                                        main.apps,
                                        tempOnosIp )
 
-        main.log.info( "Applying cell to environment" )
-        cell = main.ONOSbench.setCell( "temp" )
-        verify = main.ONOSbench.verifyCell()
-        if not cell or not verify:
-            main.log.error("Failed to apply cell to environment")
-            main.cleanup()
-            main.exit()
+        main.step( "Apply cell to environment" )
+        cellResult = main.ONOSbench.setCell( "temp" )
+        verifyResult = main.ONOSbench.verifyCell()
+        stepResult = cellResult and verifyResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully applied cell to " + \
+                                        "environment",
+                                 onfail="Failed to apply cell to environment " )
 
-        main.log.info( "Creating ONOS package" )
-        if not main.ONOSbench.onosPackage():
-            main.log.error("Failed to create ONOS package")
-            main.cleanup()
-            main.exit()
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.onosPackage()
+        stepResult = packageResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully created ONOS package",
+                                 onfail="Failed to create ONOS package" )
 
         main.log.info("Creating DB file")
         with open(main.dbFileName, "w+") as dbFile:
@@ -147,9 +169,13 @@
             temp += "'" + nic + "',"
             temp += str(main.numCtrls) + ","
             temp += "'" + node + "1" + "'"
+            temp += ",0"
+            temp += ",0"
+            temp += ",0"
+            temp += ",0"
             dbFile.write(temp)
 
-    def CASE1( self, main ):
+    def CASE2( self, main ):
         """
         - Uninstall ONOS cluster
         - Verify ONOS start up
@@ -157,52 +183,48 @@
         - Connect to cli
         """
 
-        main.log.info( "Uninstalling ONOS package" )
-        main.ONOSbench.onosUninstall( nodeIp=main.ONOSip[i] )
-        for i in range( main.maxNodes ):
-            if not main.ONOSbench.onosUninstall( nodeIp=main.ONOSip[i] ):
-                main.log.error("Failed to uninstall onos on node %s" % (i+1))
-                main.cleanup()
-                main.exit()
-
-        main.log.info( "Installing ONOS package" )
+        main.step( "Installing ONOS with -f" )
+        onosInstallResult = main.TRUE
         for i in range( main.numCtrls ):
-            if not main.ONOSbench.onosInstall( node=main.ONOSip[i] ):
-                main.log.error("Failed to install onos on node %s" % (i+1))
-                main.cleanup()
-                main.exit()
+            onosInstallResult = onosInstallResult and \
+                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
+        stepResult = onosInstallResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully installed ONOS package",
+                                 onfail="Failed to install ONOS package" )
 
-        main.log.info( "Starting ONOS service" )
-        for i in range( main.numCtrls ):
-            start = main.ONOSbench.onosStart( main.ONOSip[i] )
-            isup = main.ONOSbench.isup( main.ONOSip[i] )
-            if not start or not isup:
-                main.log.error("Failed to start onos service on node %s" % (i+1))
-                main.cleanup()
-                main.exit()
+        time.sleep( main.startUpSleep )
 
-        main.log.info( "Starting ONOS cli" )
+        main.step( "Start ONOS cli" )
+        cliResult = main.TRUE
         for i in range( main.numCtrls ):
-            if not main.CLIs[i].startOnosCli( main.ONOSip[i] ):
-                main.log.error("Failed to start onos cli on node %s" % (i+1))
-                main.cleanup()
-                main.exit()
+            cliResult = cliResult and \
+                        main.CLIs[ i ].startOnosCli( main.ONOSip[ i ] )
+        stepResult = cliResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully start ONOS cli",
+                                 onfail="Failed to start ONOS cli" )
+
+        time.sleep( main.startUpSleep )
 
     def CASE10( self, main ):
         """
             Setting up null-provider
         """
         import json
-        import pexpect
 
         # Activate apps
-        main.log.info("Activating null-provider")
+        main.step("Activating null-provider")
         appStatus = main.CLIs[0].activateApp('org.onosproject.null')
-        if not appStatus:
-            main.log.error("Failed to activate null-provider")
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=appStatus,
+                                 onpass="Successfully activated null-provider",
+                                 onfail="Failed activate null-provider" )
 
         # Setup the null-provider
-        main.log.info("Configuring null-provider")
+        main.step("Configuring null-provider")
         cfgStatus = main.ONOSbench.onosCfgSet( main.ONOSip[0],
                 'org.onosproject.provider.nil.NullProviders', 'deviceCount 3' )
         cfgStatus = cfgStatus and main.ONOSbench.onosCfgSet( main.ONOSip[0],
@@ -210,20 +232,30 @@
         cfgStatus = cfgStatus and main.ONOSbench.onosCfgSet( main.ONOSip[0],
                 'org.onosproject.provider.nil.NullProviders', 'enabled true' )
 
-        if not cfgStatus:
-            main.log.error("Failed to configure null-provider")
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=cfgStatus,
+                                 onpass="Successfully configured null-provider",
+                                 onfail="Failed to configure null-provider" )
 
         # give onos some time to settle
         time.sleep(main.startUpSleep)
 
+        main.log.info("Setting default flows to zero")
         main.defaultFlows = 0
-        main.ingress =  ":0000000000000001/3"
-        main.egress = ":0000000000000003/2"
-        main.switch = "null"
-        main.linkUpCmd = "null-link null:0000000000000001/3 null:0000000000000003/1 up"
-        main.linkDownCmd = "null-link null:0000000000000001/3 null:0000000000000003/1 down"
 
-        if not appStatus or not cfgStatus:
+        main.step("Check status of null-provider setup")
+        caseResult = appStatus and cfgStatus
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=caseResult,
+                                 onpass="Setting up null-provider was successfull",
+                                 onfail="Failed to setup null-provider" )
+
+        # This tells the following cases if we are using the null-provider or ovs
+        main.switchType = "null:"
+
+        # If the null-provider setup was unsuccessfull, then there is no point to
+        # run the subsequent cases
+        if not caseResult:
             main.setupSkipped = True
 
     def CASE11( self, main ):
@@ -233,239 +265,218 @@
         import json
         import time
 
-        main.log.step("Activating openflow")
+        time.sleep(main.startUpSleep)
+
+        main.step("Activating openflow")
         appStatus = main.CLIs[0].activateApp('org.onosproject.openflow')
-        if appStatus:
-            main.log.error("Failed to activate openflow")
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=appStatus,
+                                 onpass="Successfully activated openflow",
+                                 onfail="Failed activate openflow" )
 
         time.sleep(main.startUpSleep)
 
-        main.log.info('Starting mininet topology')
+        main.step('Starting mininet topology')
         mnStatus = main.Mininet1.startNet(topoFile='~/mininet/custom/rerouteTopo.py')
-        if mnStatus:
-            main.log.error("Failed to start mininet")
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=mnStatus,
+                                 onpass="Successfully started Mininet",
+                                 onfail="Failed to activate Mininet" )
 
-        main.log.info("Assinging masters to switches")
-        swStatus =  main.Mininet1.assignSwController(sw='s1', ip=main.ONOSip[0])
-        swStatus = swStatus and  main.Mininet1.assignSwController(sw='s2', ip=main.ONOSip[0])
-        swStatus = swStatus and main.Mininet1.assignSwController(sw='s3', ip=main.ONOSip[0])
-        if not swStatus:
-            main.log.info("Failed to assign masters to switches")
+        main.step("Assinging masters to switches")
+        switches = main.Mininet1.getSwitches()
+        swStatus = main.Mininet1.assignSwController( sw=switches.keys(), ip=main.ONOSip )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=swStatus,
+                                 onpass="Successfully assigned switches to masters",
+                                 onfail="Failed assign switches to masters" )
 
         time.sleep(main.startUpSleep)
 
+        main.log.info("Getting default flows")
         jsonSum = json.loads(main.CLIs[0].summary())
-        sumStatus = (jsonSum['devices'] == 3 and jsonSum['SCC(s)'] == 1)
-
-        main.log.step("Getting default flows")
-        jsonSum = json.loads(main.CLIs[0].summary())
-
         main.defaultFlows = jsonSum["flows"]
-        main.ingress =  ":0000000000000001/3"
-        main.egress = ":0000000000000003/2"
-        main.switch = "of"
-        main.linkDownCmd = 'link s1 s3 down'
-        main.linkUpCmd = 'link s1 s3 up'
 
-        if not appStatus or not mnStatus or not swStatus or not sumStatus:
+        main.step("Check status of Mininet setup")
+        caseResult = appStatus and mnStatus and swStatus
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=caseResult,
+                                 onpass="Successfully setup Mininet",
+                                 onfail="Failed setup Mininet" )
+
+        # This tells the following cases if we are using the null-provider or ovs
+        main.switchType = "of:"
+
+        if not caseResult:
             main.setupSkipped = True
 
     def CASE20( self, main ):
-        import pexpect
         '''
             Pushing intents
         '''
 
-        # check if the setup case has been skipped
+        if main.reroute:
+            if main.switchType == "of:":
+                main.minIntents = int(main.params['OVS']['REROUTE']['min_intents'])
+                main.maxIntents = int(main.params['OVS']['REROUTE']['max_intents'])
+                main.checkInterval = int(main.params['OVS']['REROUTE']['check_interval'])
+                main.batchSize = int(main.params['OVS']['REROUTE']['batch_size'])
+            else:
+                main.minIntents = int(main.params['NULL']['REROUTE']['min_intents'])
+                main.maxIntents = int(main.params['NULL']['REROUTE']['max_intents'])
+                main.checkInterval = int(main.params['NULL']['REROUTE']['check_interval'])
+                main.batchSize = int(main.params['NULL']['REROUTE']['batch_size'])
+        else:
+            if main.switchType == "of:":
+                main.minIntents = int(main.params['OVS']['PUSH']['min_intents'])
+                main.maxIntents = int(main.params['OVS']['PUSH']['max_intents'])
+                main.checkInterval = int(main.params['OVS']['PUSH']['check_interval'])
+                main.batchSize = int(main.params['OVS']['PUSH']['batch_size'])
+            else:
+                main.minIntents = int(main.params['NULL']['PUSH']['min_intents'])
+                main.maxIntents = int(main.params['NULL']['PUSH']['max_intents'])
+                main.checkInterval = int(main.params['NULL']['PUSH']['check_interval'])
+                main.batchSize = int(main.params['NULL']['PUSH']['batch_size'])
+
+        # check if the case needs to be skipped
         if main.setupSkipped:
             main.setupSkipped = False
             main.skipCase()
 
         # the index where the next intents will be installed
         offset = 0
-        # the number of intents we expect to be in the installed state
-        expectedIntents = 0
         # keeps track of how many intents have been installed
-        maxIntents = 0
-        # the number of flows we expect to be in the added state
-        expectedFlows = main.defaultFlows
+        currIntents = 0
         # keeps track of how many flows have been installed
-        maxFlows = main.defaultFlows
+        currFlows = main.defaultFlows
         # limit for the number of intents that can be installed
         limit = main.maxIntents / main.batchSize
 
+        main.step( "Pushing intents" )
         for i in range(limit):
-            # Push intents
-            main.log.info("Pushing intents")
-            main.intentFunctions.pushIntents( main,
-                                              main.switch,
-                                              main.ingress,
-                                              main.egress,
-                                              main.batchSize,
-                                              offset,
-                                              sleep=main.installSleep,
-                                              timeout=main.timeout,
-                                              options="-i" )
+            pushResult = main.ONOScli1.pushTestIntents( main.switchType +  main.ingress,
+                                                        main.switchType +  main.egress,
+                                                        main.batchSize,
+                                                        offset = offset,
+                                                        options = "-i",
+                                                        timeout = main.timeout )
+            if pushResult == None:
+                main.log.info( "Timeout!" )
+                main.skipCase()
+            time.sleep(1)
 
+            # Update offset
             offset += main.batchSize
-            expectedIntents = offset
-            expectedFlows += main.batchSize*2
 
-            main.log.info("Grabbing number of installed intents and flows")
-            maxIntents = main.intentFunctions.getIntents( main )
-            maxFlows = main.intentFunctions.getFlows( main )
+            if offset >= main.minIntents and offset % main.checkInterval == 0:
+                intentVerify = utilities.retry( main.ONOScli1.checkIntentSummary,
+                                                main.FALSE,
+                                                [main.timeout],
+                                                sleep=main.verifySleep,
+                                                attempts=main.verifyAttempts )
 
-            if offset >= main.minIntents and offset % main.checkInterval == 0 or expectedIntents == main.maxIntents:
-                # Verifying intents
-                main.log.info("Verifying intents\nExpected intents: " + str(expectedIntents))
-                intentStatus = main.intentFunctions.verifyIntents( main,
-                                                                   expectedIntents,
-                                                                   sleep=main.verifySleep,
-                                                                   timeout=main.timeout)
-                # Verfying flows
-                main.log.info("Verifying flows\nExpected Flows: " + str(expectedFlows))
-                flowStatus = main.intentFunctions.verifyFlows( main,
-                                                               expectedFlows,
-                                                               sleep=main.verifySleep,
-                                                               timeout=main.timeout)
+                flowVerify = utilities.retry( main.ONOScli1.checkFlowsState,
+                                              main.FALSE,
+                                              [False,main.timeout],
+                                              sleep=main.verifySleep,
+                                              attempts=main.verifyAttempts )
 
-                if not flowStatus or not intentsStataus:
-                    main.log.error("Failed to verify")
+                if not intentVerify:
+                    main.log.error( "Failed to install intents" )
                     break
 
-        main.log.info("Summary: Intents=" + str(expectedIntents) + " Flows=" + str(expectedFlows))
-        main.log.info("Installed intents: " + str(maxIntents) +
-                      " Added flows: " + str(maxFlows))
+                if main.reroute:
+                    main.step( "Reroute" )
+                    # tear down a link
+                    main.log.info("Tearing down link")
+                    if main.switchType == "of:":
+                        downlink = main.Mininet1.link( END1 = "s1", END2 = "s3", OPTION = "down" )
+                    else:
+                        downlink = main.ONOScli1.link( main.ingress, main.egress, "down")
+
+                    if downlink:
+                        main.log.info( "Successfully tear down link" )
+                    else:
+                        main.log.warn( "Failed to tear down link" )
+
+                    time.sleep(main.rerouteSleep)
+
+                    # Verifying intents
+                    main.step( "Checking intents and flows" )
+                    intentVerify = utilities.retry( main.ONOScli1.checkIntentSummary,
+                                                    main.FALSE,
+                                                    [main.timeout],
+                                                    sleep=main.verifySleep,
+                                                    attempts=main.verifyAttempts )
+                    # Verfying flows
+                    flowVerify = utilities.retry( main.ONOScli1.checkFlowsState,
+                                                  main.FALSE,
+                                                  [False, main.timeout],
+                                                  sleep = main.verifySleep,
+                                                  attempts = main.verifyAttempts )
+
+                    if not intentVerify:
+                        main.log.error( "Failed to install intents" )
+                    # Bring link back up
+                    main.log.info("Bringing link back up")
+                    if main.switchType == "of:":
+                        uplink = main.Mininet1.link( END1 = "s1", END2 = "s3", OPTION = "up" )
+                    else:
+                        uplink = main.ONOScli1.link( main.ingress, main.egress, "up" )
+
+                    if uplink:
+                        main.log.info( "Successfully bring link back up" )
+                    else:
+                        main.log.warn( "Failed to bring link back up" )
+
+                    time.sleep(main.rerouteSleep)
+
+                    # Verifying intents
+                    main.step( "Checking intents and flows" )
+                    intentVerify = utilities.retry( main.ONOScli1.checkIntentSummary,
+                                                    main.FALSE,
+                                                    [main.timeout],
+                                                    sleep=main.verifySleep,
+                                                    attempts=main.verifyAttempts )
+                    # Verfying flows
+                    flowVerify = utilities.retry( main.ONOScli1.checkFlowsState,
+                                                  main.FALSE,
+                                                  [False, main.timeout],
+                                                  sleep = main.verifySleep,
+                                                  attempts = main.verifyAttempts )
+
+                    if not intentVerify:
+                        main.log.error( "Failed to install intents" )
+
+                    rerouteResult = downlink and uplink
+                    utilities.assert_equals( expect = main.TRUE,
+                                             actual = rerouteResult,
+                                             onpass = "Successfully reroute",
+                                             onfail = "Failed to reroute" )
+
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = intentVerify,
+                                 onpass = "Successfully pushed and verified intents",
+                                 onfail = "Failed to push and verify intents" )
+        currIntents = main.ONOScli1.getTotalIntentsNum()
+        currFlows = main.ONOScli1.getTotalFlowsNum()
 
         main.log.info("Writing results to DB file")
-        with open(dbFileName, "a") as dbFile:
-            temp = "," + str(maxIntents)
-            temp += "," + str(maxFlows)
-            dbFile.write(temp)
-
-        # Stopping mininet
-        if main.switch == "of":
-            main.log.info("Stopping mininet")
-            main.Mininet1.stopNet()
-
-    def CASE21( self, main ):
-        import pexpect
-        import time
-        '''
-            Reroute
-        '''
-
-        # check if the setup case has been skipped
-        if main.setupSkipped:
-            main.setupSkipped = False
-            main.skipCase()
-
-        # the index where the next intents will be installed
-        offset = 0
-        # the number of intents we expect to be in the installed state
-        expectedIntents = 0
-        # keeps track of how many intents have been installed
-        maxIntents = 0
-        # the number of flows we expect to be in the added state
-        expectedFlows = main.defaultFlows
-        # keeps track of how many flows have been installed
-        maxFlows = main.defaultFlows
-        # limit for the number of intents that can be installed
-        limit = main.maxIntents / main.batchSize
-
-        for i in range(limit):
-            # Push intents
-            main.log.info("Pushing intents")
-            main.intentFunctions.pushIntents( main,
-                                              main.switch,
-                                              main.ingress,
-                                              main.egress,
-                                              main.batchSize,
-                                              offset,
-                                              sleep=main.installSleep,
-                                              timeout=main.timeout,
-                                              options="-i" )
-
-            offset += main.batchSize
-            expectedIntents = offset
-            expectedFlows += main.batchSize*2
-
-            main.log.info("Grabbing number of installed intents and flows")
-            maxIntents = main.intentFunctions.getIntents( main )
-            maxFlows = main.intentFunctions.getFlows( main )
-
-            # Verifying intents
-            main.log.info("Verifying intents\n\tExpected intents: " + str(expectedIntents))
-            intentStatus = main.intentFunctions.verifyIntents( main,
-                                                               expectedIntents,
-                                                               sleep=main.verifySleep,
-                                                               timeout=main.timeout)
-            # Verfying flows
-            main.log.info("Verifying flows\n\tExpected Flows: " + str(expectedFlows))
-            flowStatus = main.intentFunctions.verifyFlows( main,
-                                                           expectedFlows,
-                                                           sleep=main.verifySleep,
-                                                           timeout=main.timeout)
-
-            if not flowStatus or not intentsStataus:
-                main.log.error("Failed to verify\n\tSkipping case")
-                main.log.skipCase()
-
-            # tear down a link
-            main.log.step("Tearing down link")
-            if main.switch == "of":
-                main.log.info("Sending: " + main.linkDownCmd)
-                main.Mininet1.handle.sendline(main.linkDownCmd)
-                main.Mininet1.handle.expect('mininet>')
-            else:
-                main.log.info("Sending: " + main.linkDownCmd)
-                main.CLIs[0].handle.sendline(main.linkDownCmd)
-                main.CLIs[0].handle.expect('onos>')
-
-            time.sleep(main.rerouteSleep)
-
-            # rerouting adds a 1000 flows
-            expectedFlows += 1000
-
-            main.log.info("Grabbing number of added flows")
-            maxFlows = main.intentFunctions.getFlows( main )
-
-            # Verfying flows
-            main.log.info("Verifying flows\n\tExpected Flows: " + str(expectedFlows))
-            flowStatus = main.intentFunctions.verifyFlows( main,
-                                                           expectedFlows,
-                                                           sleep=main.verifySleep,
-                                                           timeout=main.timeout)
-            if not flowStatus:
-                main.log.error("Failed to verify flows\n\tSkipping case")
-                main.skipCase()
-
-            # Bring link back up
-            main.log.step("Bringing link back up")
-            if main.switch == "of":
-                main.log.info("Sending: " + main.linkUpCmd)
-                main.Mininet1.handle.sendline(main.linkUpCmd)
-                main.Mininet1.handle.expect('mininet>')
-            else:
-                main.log.info("Sending: " + main.linkUpCmd)
-                main.CLIs[0].handle.sendline(main.linkUpCmd)
-                main.CLIs[0].handle.expect('onos>')
-
-            time.sleep(main.rerouteSleep)
-
-        main.log.info("Summary: Intents=" + str(expectedIntents) + " Flows=" + str(expectedFlows))
-        main.log.info("Installed intents: " + str(maxIntents) +
-                      " Added flows: " + str(maxFlows))
-
         with open(main.dbFileName, "a") as dbFile:
-            temp = "," + str(maxIntents)
-            temp += "," + str(maxFlows)
+            temp = "," + str(currIntents)
+            temp += "," + str(currFlows)
+            temp += ",0"
+            temp += ",0\n"
             dbFile.write(temp)
 
-        # Stopping mininet
-        if main.switch == "of":
-            main.log.info("Stopping mininet")
-            main.Mininet1.stopNet()
+        if main.switchType == "of:":
+            main.step( "Stopping mininet" )
+            stepResult = main.Mininet1.stopNet()
+            utilities.assert_equals( expect = main.TRUE,
+                                     actual = stepResult,
+                                     oppass = "Successfully stop Mininet",
+                                     opfail = "Failed stop Mininet" )
+
 
     def CASE100( self, main ):
         '''
diff --git a/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.topo b/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.topo
index be3236a..f34ed12 100755
--- a/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.topo
+++ b/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.topo
@@ -20,7 +20,7 @@
             <COMPONENTS>
             </COMPONENTS>
         </ONOScli1>
- 
+
         <Mininet1>
             <host>localhost</host>
             <user>admin</user>
diff --git a/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.py b/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.py
index fde3b1b..ae197a6 100644
--- a/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.py
+++ b/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.py
@@ -407,10 +407,14 @@
         stepResult = main.FALSE
         if main.activeNodes:
             controller = main.activeNodes[0]
-            stepResult = main.CLIs[controller].balanceMasters()
+            stepResult = utilities.retry( main.CLIs[controller].balanceMasters,
+                                          main.FALSE,
+                                          [],
+                                          sleep=3,
+                                          attempts=3 )
+
         else:
             main.log.error( "List of active nodes is empty" )
-        main.step( "Balancing Masters" )
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
                                  onpass="Balance masters was successfull",