Merge branch 'master' of https://github.com/opennetworkinglab/ONLabTest
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index 2d7c0a5..ce6e02d 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -264,6 +264,7 @@
            main.TRUE if pingall completes with no pings dropped
            otherwise main.FALSE"""
         try:
+            timeout = int( timeout )
             if self.handle:
                 main.log.info(
                     self.name +
diff --git a/TestON/drivers/common/cli/onosclidriver.py b/TestON/drivers/common/cli/onosclidriver.py
index d815e4c..703e15f 100644
--- a/TestON/drivers/common/cli/onosclidriver.py
+++ b/TestON/drivers/common/cli/onosclidriver.py
@@ -299,7 +299,7 @@
             main.cleanup()
             main.exit()
 
-    def sendline( self, cmdStr ):
+    def sendline( self, cmdStr, debug=False ):
         """
         Send a completely user specified string to
         the onos> prompt. Use this function if you have
@@ -316,7 +316,7 @@
             response = self.handle.before
             if i == 2:
                 self.handle.sendline()
-                self.handle.expect( "\$" )
+                self.handle.expect( ["\$", pexpect.TIMEOUT] )
                 response += self.handle.before
                 print response
                 try:
@@ -326,15 +326,39 @@
             # TODO: do something with i
             main.log.info( "Command '" + str( cmdStr ) + "' sent to "
                            + self.name + "." )
-            # Remove control strings from output
+            if debug:
+                main.log.debug( "Raw output" )
+                main.log.debug( repr( response ) )
+
+            # Remove ANSI color control strings from output
             ansiEscape = re.compile( r'\x1b[^m]*m' )
             response = ansiEscape.sub( '', response )
+            if debug:
+                main.log.debug( "ansiEscape output" )
+                main.log.debug( repr( response ) )
+
             # Remove extra return chars that get added
             response = re.sub(  r"\s\r", "", response )
+            if debug:
+                main.log.debug( "Removed extra returns from output" )
+                main.log.debug( repr( response ) )
+
+            # Strip excess whitespace
             response = response.strip()
+            if debug:
+                main.log.debug( "parsed and stripped output" )
+                main.log.debug( repr( response ) )
+
             # parse for just the output, remove the cmd from response
-            output = response.split( cmdStr, 1 )[1]
-            return output
+            output = response.split( cmdStr.strip(), 1 )
+            if debug:
+                main.log.debug( "split output" )
+                for r in output:
+                    main.log.debug( repr( r ) )
+            return output[1].strip()
+        except IndexError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -398,11 +422,13 @@
         try:
 
             cmdStr = "remove-node " + str( nodeId )
-            self.sendline( cmdStr )
-            # TODO: add error checking. Does ONOS give any errors?
-
-            return main.TRUE
-
+            handle = self.sendline( cmdStr )
+            if re.search( "Error", handle ):
+                main.log.error( "Error in removing node" )
+                main.log.error( handle )
+                return main.FALSE
+            else:
+                return main.TRUE
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -424,16 +450,11 @@
             * jsonFormat - boolean indicating if you want output in json
         """
         try:
+            cmdStr = "nodes"
             if jsonFormat:
-                cmdStr = "nodes -j"
-                output = self.sendline( cmdStr )
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                parsedOutput = ansiEscape.sub( '', output )
-                return parsedOutput
-            else:
-                cmdStr = "nodes"
-                output = self.sendline( cmdStr )
-                return output
+                cmdStr += " -j"
+            output = self.sendline( cmdStr )
+            return output
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -455,10 +476,9 @@
             topology = current ONOS topology
         """
         try:
-            # either onos:topology or 'topology' will work in CLI
             cmdStr = "topology -j"
             handle = self.sendline( cmdStr )
-            main.log.info( "topology -j returned: " + str( handle ) )
+            main.log.info( cmdStr + " returned: " + str( handle ) )
             return handle
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -475,14 +495,20 @@
 
     def featureInstall( self, featureStr ):
         """
-        Installs a specified feature
-        by issuing command: 'onos> feature:install <feature_str>'
+        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 )
-            self.sendline( cmdStr )
-            # TODO: Check for possible error responses from karaf
-            return main.TRUE
+            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
@@ -502,20 +528,28 @@
 
     def featureUninstall( self, featureStr ):
         """
-        Uninstalls a specified feature
-        by issuing command: 'onos> feature:uninstall <feature_str>'
+        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 )
-                self.sendline( cmdStr )
+                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
+                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
@@ -536,9 +570,14 @@
         TODO: refactor this function
         """
         try:
-            cmdStr = "device-remove "+str(deviceId)
-            self.sendline( cmdStr )
-            return main.TRUE
+            cmdStr = "device-remove " + str( deviceId )
+            handle = self.sendline( cmdStr )
+            if re.search( "Error", handle ):
+                main.log.error( "Error in removing device" )
+                main.log.error( handle )
+                return main.FALSE
+            else:
+                return main.TRUE
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -559,29 +598,11 @@
             * jsonFormat - boolean indicating if you want output in json
         """
         try:
+            cmdStr = "devices"
             if jsonFormat:
-                cmdStr = "devices -j"
-                handle = self.sendline( cmdStr )
-                """
-                handle variable here contains some ANSI escape color code
-                sequences at the end which are invisible in the print command
-                output. To make that escape sequence visible, use repr()
-                function. The repr( handle ) output when printed shows the
-                ANSI escape sequences. In json.loads( somestring ), this
-                somestring variable is actually repr( somestring ) and
-                json.loads would fail with the escape sequence. So we take off
-                that escape sequence using:
-
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                handle1 = ansiEscape.sub( '', handle )
-                """
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                handle1 = ansiEscape.sub( '', handle )
-                return handle1
-            else:
-                cmdStr = "devices"
-                handle = self.sendline( cmdStr )
-                return handle
+                cmdStr += " -j"
+            handle = self.sendline( cmdStr )
+            return handle
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -603,9 +624,13 @@
         """
         try:
             cmdStr = "onos:balance-masters"
-            self.sendline( cmdStr )
-            # TODO: Check for error responses from ONOS
-            return main.TRUE
+            handle = self.sendline( cmdStr )
+            if re.search( "Error", handle ):
+                main.log.error( "Error in balancing masters" )
+                main.log.error( handle )
+                return main.FALSE
+            else:
+                return main.TRUE
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -626,29 +651,11 @@
             * jsonFormat - boolean indicating if you want output in json
         """
         try:
+            cmdStr = "links"
             if jsonFormat:
-                cmdStr = "links -j"
-                handle = self.sendline( cmdStr )
-                """
-                handle variable here contains some ANSI escape color code
-                sequences at the end which are invisible in the print command
-                output. To make that escape sequence visible, use repr()
-                function. The repr( handle ) output when printed shows the ANSI
-                escape sequences. In json.loads( somestring ), this somestring
-                variable is actually repr( somestring ) and json.loads would
-                fail with the escape sequence. So we take off that escape
-                sequence using:
-
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                handle1 = ansiEscape.sub( '', handle )
-                """
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                handle1 = ansiEscape.sub( '', handle )
-                return handle1
-            else:
-                cmdStr = "links"
-                handle = self.sendline( cmdStr )
-                return handle
+                cmdStr += " -j"
+            handle = self.sendline( cmdStr )
+            return handle
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -669,30 +676,11 @@
             * jsonFormat - boolean indicating if you want output in json
         """
         try:
+            cmdStr = "ports"
             if jsonFormat:
-                cmdStr = "ports -j"
-                handle = self.sendline( cmdStr )
-                """
-                handle variable here contains some ANSI escape color code
-                sequences at the end which are invisible in the print command
-                output. To make that escape sequence visible, use repr()
-                function. The repr( handle ) output when printed shows the ANSI
-                escape sequences. In json.loads( somestring ), this somestring
-                variable is actually repr( somestring ) and json.loads would
-                fail with the escape sequence. So we take off that escape
-                sequence using the following commands:
-
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                handle1 = ansiEscape.sub( '', handle )
-                """
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                handle1 = ansiEscape.sub( '', handle )
-                return handle1
-
-            else:
-                cmdStr = "ports"
-                handle = self.sendline( cmdStr )
-                return handle
+                cmdStr += " -j"
+            handle = self.sendline( cmdStr )
+            return handle
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -713,32 +701,11 @@
             * jsonFormat - boolean indicating if you want output in json
         """
         try:
+            cmdStr = "roles"
             if jsonFormat:
-                cmdStr = "roles -j"
-                handle = self.sendline( cmdStr )
-                """
-                handle variable here contains some ANSI escape color code
-                sequences at the end which are invisible in the print command
-                output. To make that escape sequence visible, use repr()
-                function. The repr( handle ) output when printed shows the ANSI
-                escape sequences. In json.loads( somestring ), this somestring
-                variable is actually repr( somestring ) and json.loads would
-                fail with the escape sequence.
-
-                So we take off that escape sequence using the following
-                commads:
-
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                handle1 = ansiEscape.sub( '', handle )
-                """
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                handle1 = ansiEscape.sub( '', handle )
-                return handle1
-
-            else:
-                cmdStr = "roles"
-                handle = self.sendline( cmdStr )
-                return handle
+                cmdStr += " -j"
+            handle = self.sendline( cmdStr )
+            return handle
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -853,29 +820,11 @@
             * jsonFormat - boolean indicating if you want output in json
         """
         try:
+            cmdStr = "hosts"
             if jsonFormat:
-                cmdStr = "hosts -j"
-                handle = self.sendline( cmdStr )
-                """
-                handle variable here contains some ANSI escape color code
-                sequences at the end which are invisible in the print command
-                output. To make that escape sequence visible, use repr()
-                function. The repr( handle ) output when printed shows the ANSI
-                escape sequences. In json.loads( somestring ), this somestring
-                variable is actually repr( somestring ) and json.loads would
-                fail with the escape sequence. So we take off that escape
-                sequence using:
-
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                handle1 = ansiEscape.sub( '', handle )
-                """
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                handle1 = ansiEscape.sub( '', handle )
-                return handle1
-            else:
-                cmdStr = "hosts"
-                handle = self.sendline( cmdStr )
-                return handle
+                cmdStr += " -j"
+            handle = self.sendline( cmdStr )
+            return handle
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -1287,12 +1236,14 @@
                         return main.FALSE
             else:
                 if len( ingressDeviceList ) == len( portIngressList ):
-                    for ingressDevice, portIngress in zip( ingressDeviceList, portIngressList ):
+                    for ingressDevice, portIngress in zip( ingressDeviceList,
+                                                           portIngressList ):
                         cmd += " " + \
                             str( ingressDevice ) + "/" +\
                             str( portIngress ) + " "
                 else:
-                    main.log.error( "Device list and port list does not have the same length" )
+                    main.log.error( "Device list and port list does not " +
+                                    "have the same length" )
                     return main.FALSE
             if "/" in egressDevice:
                 cmd += " " + str( egressDevice )
@@ -1305,8 +1256,6 @@
                 cmd += " " +\
                     str( egressDevice ) + "/" +\
                     str( portEgress )
-
-            print "cmd= ", cmd
             handle = self.sendline( cmd )
             # If error, return error message
             if re.search( "Error", handle ):
@@ -1424,7 +1373,7 @@
 
             # Check whether the user appended the port
             # or provided it as an input
-            
+
             if "/" in ingressDevice:
                 cmd += " " + str( ingressDevice )
             else:
@@ -1448,15 +1397,15 @@
                         return main.FALSE
             else:
                 if len( egressDeviceList ) == len( portEgressList ):
-                    for egressDevice, portEgress in zip( egressDeviceList, portEgressList ):
+                    for egressDevice, portEgress in zip( egressDeviceList,
+                                                         portEgressList ):
                         cmd += " " + \
                             str( egressDevice ) + "/" +\
                             str( portEgress )
                 else:
-                    main.log.error( "Device list and port list does not have the same length" )
+                    main.log.error( "Device list and port list does not " +
+                                    "have the same length" )
                     return main.FALSE
-
-            print "cmd= ", cmd
             handle = self.sendline( cmd )
             # If error, return error message
             if re.search( "Error", handle ):
@@ -1483,6 +1432,145 @@
             main.cleanup()
             main.exit()
 
+    def addMplsIntent(
+            self,
+            ingressDevice,
+            egressDevice,
+            ingressPort="",
+            egressPort="",
+            ethType="",
+            ethSrc="",
+            ethDst="",
+            bandwidth="",
+            lambdaAlloc=False,
+            ipProto="",
+            ipSrc="",
+            ipDst="",
+            tcpSrc="",
+            tcpDst="",
+            ingressLabel="",
+            egressLabel="",
+            priority=""):
+        """
+        Required:
+            * ingressDevice: device id of ingress device
+            * egressDevice: device id of egress device
+        Optional:
+            * ethType: specify ethType
+            * ethSrc: specify ethSrc ( i.e. src mac addr )
+            * ethDst: specify ethDst ( i.e. dst mac addr )
+            * bandwidth: specify bandwidth capacity of link
+            * lambdaAlloc: if True, intent will allocate lambda
+              for the specified intent
+            * ipProto: specify ip protocol
+            * ipSrc: specify ip source address
+            * ipDst: specify ip destination address
+            * tcpSrc: specify tcp source port
+            * tcpDst: specify tcp destination port
+            * ingressLabel: Ingress MPLS label
+            * egressLabel: Egress MPLS label
+        Description:
+            Adds MPLS intent by
+            specifying device id's and optional fields
+        Returns:
+            A string of the intent id or None on error
+
+        NOTE: This function may change depending on the
+              options developers provide for MPLS
+              intent via cli
+        """
+        try:
+            # If there are no optional arguments
+            if not ethType and not ethSrc and not ethDst\
+                    and not bandwidth and not lambdaAlloc \
+                    and not ipProto and not ipSrc and not ipDst \
+                    and not tcpSrc and not tcpDst and not ingressLabel \
+                    and not egressLabel:
+                cmd = "add-mpls-intent"
+
+            else:
+                cmd = "add-mpls-intent"
+
+                if ethType:
+                    cmd += " --ethType " + str( ethType )
+                if ethSrc:
+                    cmd += " --ethSrc " + str( ethSrc )
+                if ethDst:
+                    cmd += " --ethDst " + str( ethDst )
+                if bandwidth:
+                    cmd += " --bandwidth " + str( bandwidth )
+                if lambdaAlloc:
+                    cmd += " --lambda "
+                if ipProto:
+                    cmd += " --ipProto " + str( ipProto )
+                if ipSrc:
+                    cmd += " --ipSrc " + str( ipSrc )
+                if ipDst:
+                    cmd += " --ipDst " + str( ipDst )
+                if tcpSrc:
+                    cmd += " --tcpSrc " + str( tcpSrc )
+                if tcpDst:
+                    cmd += " --tcpDst " + str( tcpDst )
+                if ingressLabel:
+                    cmd += " --ingressLabel " + str( ingressLabel )
+                if egressLabel:
+                    cmd += " --egressLabel " + str( egressLabel )
+                if priority:
+                    cmd += " --priority " + str( priority )
+
+            # Check whether the user appended the port
+            # or provided it as an input
+            if "/" in ingressDevice:
+                cmd += " " + str( ingressDevice )
+            else:
+                if not ingressPort:
+                    main.log.error( "You must specify the ingress port" )
+                    return None
+
+                cmd += " " + \
+                    str( ingressDevice ) + "/" +\
+                    str( ingressPort ) + " "
+
+            if "/" in egressDevice:
+                cmd += " " + str( egressDevice )
+            else:
+                if not egressPort:
+                    main.log.error( "You must specify the egress port" )
+                    return None
+
+                cmd += " " +\
+                    str( egressDevice ) + "/" +\
+                    str( egressPort )
+
+            handle = self.sendline( cmd )
+            # If error, return error message
+            if re.search( "Error", handle ):
+                main.log.error( "Error in adding mpls intent" )
+                return None
+            else:
+                # TODO: print out all the options in this message?
+                main.log.info( "MPLS intent installed between " +
+                               str( ingressDevice ) + " and " +
+                               str( egressDevice ) )
+                match = re.search('id=0x([\da-f]+),', handle)
+                if match:
+                    return match.group()[3:-1]
+                else:
+                    main.log.error( "Error, intent ID not found" )
+                    return None
+        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 removeIntent( self, intentId, app='org.onosproject.cli',
                       purge=False, sync=False ):
         """
@@ -1496,7 +1584,7 @@
             cli output otherwise
         """
         try:
-            cmdStr = "remove-intent "
+            cmdStr = "remove-intent"
             if purge:
                 cmdStr += " -p"
             if sync:
@@ -1533,14 +1621,10 @@
             Obtain all routes in the system
         """
         try:
+            cmdStr = "routes"
             if jsonFormat:
-                cmdStr = "routes -j"
-                handleTmp = self.sendline( cmdStr )
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                handle = ansiEscape.sub( '', handleTmp )
-            else:
-                cmdStr = "routes"
-                handle = self.sendline( cmdStr )
+                cmdStr += " -j"
+            handle = self.sendline( cmdStr )
             return handle
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -1563,14 +1647,10 @@
             Obtain intents currently installed
         """
         try:
+            cmdStr = "intents"
             if jsonFormat:
-                cmdStr = "intents -j"
-                handle = self.sendline( cmdStr )
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                handle = ansiEscape.sub( '', handle )
-            else:
-                cmdStr = "intents"
-                handle = self.sendline( cmdStr )
+                cmdStr += " -j"
+            handle = self.sendline( cmdStr )
             return handle
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -1609,27 +1689,27 @@
                 intentsJsonTemp = json.loads( intentsJson )
             if isinstance( intentsId, types.StringType ):
                 for intent in intentsJsonTemp:
-                    if intentsId == intent['id']:
-                        state = intent['state']
+                    if intentsId == intent[ 'id' ]:
+                        state = intent[ 'state' ]
                         return state
                 main.log.info( "Cannot find intent ID" + str( intentsId ) +
                                " on the list" )
                 return state
             elif isinstance( intentsId, types.ListType ):
                 dictList = []
-                for ID in intentsId:
+                for i in xrange( len( intentsId ) ):
                     stateDict = {}
                     for intents in intentsJsonTemp:
-                        if ID == intents['id']:
-                            stateDict['state'] = intents['state']
-                            stateDict['id'] = ID
+                        if intentsId[ i ] == intents[ 'id' ]:
+                            stateDict[ 'state' ] = intents[ 'state' ]
+                            stateDict[ 'id' ] = intentsId[ i ]
                             dictList.append( stateDict )
                             break
                 if len( intentsId ) != len( dictList ):
                     main.log.info( "Cannot find some of the intent ID state" )
                 return dictList
             else:
-                main.log.info("Invalid intents ID entry")
+                main.log.info( "Invalid intents ID entry" )
                 return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -1643,6 +1723,53 @@
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
+    
+    def checkIntentState( self, intentsId, expectedState = 'INSTALLED' ):
+        """
+        Description:
+            Check intents state
+        Required:
+            intentsId - List of intents ID to be checked
+        Optional:
+            expectedState - Check this expected state of each intents state
+                            in the list. Defaults to INSTALLED
+        Return:
+            Returns main.TRUE only if all intent are the same as expectedState,
+            , otherwise,returns main.FALSE.
+        """
+        try:
+            # Generating a dictionary: intent id as a key and state as value
+            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 " +
+                               "getting intents state" )
+                return main.FALSE
+            returnValue = main.TRUE
+            for intents in intentsDict:
+                if intents.get( 'state' ) != expectedState:
+                    main.log.info( self.name + " : " + intents.get( 'id' ) +
+                                   " actual state = " + intents.get( 'state' )
+                                   + " does not equal expected state = "
+                                   + expectedState )
+                    returnValue = main.FALSE
+            if returnValue == main.TRUE:
+                main.log.info( self.name + ": All " +
+                               str( len( intentsDict ) ) +
+                               " intents are in " + expectedState + " state")
+            return returnValue
+        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 flows( self, jsonFormat=True ):
         """
@@ -1652,14 +1779,10 @@
             Obtain flows currently installed
         """
         try:
+            cmdStr = "flows"
             if jsonFormat:
-                cmdStr = "flows -j"
-                handle = self.sendline( cmdStr )
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                handle = ansiEscape.sub( '', handle )
-            else:
-                cmdStr = "flows"
-                handle = self.sendline( cmdStr )
+                cmdStr += " -j"
+            handle = self.sendline( cmdStr )
             if re.search( "Error:", handle ):
                 main.log.error( self.name + ".flows() response: " +
                                 str( handle ) )
@@ -1677,6 +1800,41 @@
             main.cleanup()
             main.exit()
 
+    def checkFlowsState( self ):
+        """
+        Description:
+            Check the if all the current flows are in ADDED state or
+            PENDING_ADD state
+        Return:
+            returnValue - Returns main.TRUE only if all flows are in
+                          ADDED state or PENDING_ADD, return main.FALSE
+                          otherwise.
+        """
+        try:
+            tempFlows = json.loads( self.flows() )
+            returnValue = main.TRUE
+            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: " +
+                                       flow.get( 'flowId' ) +
+                                       " | state:" + flow.get( 'state' ) )
+                        returnValue = main.FALSE
+            return returnValue
+        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 pushTestIntents( self, dpidSrc, dpidDst, numIntents,
                          numMult="", appId="", report=True ):
         """
@@ -1705,8 +1863,6 @@
                 if appId:
                     cmd += " " + str( appId )
             handle = self.sendline( cmd )
-            ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-            handle = ansiEscape.sub( '', handle )
             if report:
                 latResult = []
                 main.log.info( handle )
@@ -1743,15 +1899,10 @@
             * jsonFormat: enable json formatting of output
         """
         try:
+            cmdStr = "intents-events-metrics"
             if jsonFormat:
-                cmdStr = "intents-events-metrics -j"
-                handle = self.sendline( cmdStr )
-                # Some color thing that we want to escape
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                handle = ansiEscape.sub( '', handle )
-            else:
-                cmdStr = "intents-events-metrics"
-                handle = self.sendline( cmdStr )
+                cmdStr += " -j"
+            handle = self.sendline( cmdStr )
             return handle
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -1773,20 +1924,17 @@
             * jsonFormat: enable json formatting of output
         """
         try:
+            cmdStr = "topology-events-metrics"
             if jsonFormat:
-                cmdStr = "topology-events-metrics -j"
-                handle = self.sendline( cmdStr )
-                # Some color thing that we want to escape
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                handle = ansiEscape.sub( '', handle )
-            else:
-                cmdStr = "topology-events-metrics"
-                handle = self.sendline( cmdStr )
+                cmdStr += " -j"
+            handle = self.sendline( cmdStr )
             if handle:
                 return handle
-            else:
+            elif jsonFormat:
                 # Return empty json
                 return '{}'
+            else:
+                return handle
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -2084,29 +2232,11 @@
             * jsonFormat - boolean indicating if you want output in json
         """
         try:
+            cmdStr = "clusters"
             if jsonFormat:
-                cmdStr = "clusters -j"
-                handle = self.sendline( cmdStr )
-                """
-                handle variable here contains some ANSI escape color code
-                sequences at the end which are invisible in the print command
-                output. To make that escape sequence visible, use repr()
-                function. The repr( handle ) output when printed shows the ANSI
-                escape sequences. In json.loads( somestring ), this somestring
-                variable is actually repr( somestring ) and json.loads would
-                fail with the escape sequence. So we take off that escape
-                sequence using:
-
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                handle1 = ansiEscape.sub( '', handle )
-                """
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                handle1 = ansiEscape.sub( '', handle )
-                return handle1
-            else:
-                cmdStr = "clusters"
-                handle = self.sendline( cmdStr )
-                return handle
+                cmdStr += " -j"
+            handle = self.sendline( cmdStr )
+            return handle
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -2337,10 +2467,10 @@
         """
         try:
             intents = self.intents( )
-            intentStates = []
+            states = []
             for intent in json.loads( intents ):
-                intentStates.append( intent.get( 'state', None ) )
-            out = [ (i, intentStates.count( i ) ) for i in set( intentStates ) ]
+                states.append( intent.get( 'state', None ) )
+            out = [ ( i, states.count( i ) ) for i in set( states ) ]
             main.log.info( dict( out ) )
             return dict( out )
         except TypeError:
@@ -2371,16 +2501,11 @@
         #     "topic": "intent-partition-3"
         #  },
         try:
+            cmdStr = "onos:leaders"
             if jsonFormat:
-                cmdStr = "onos:leaders -j"
-                output = self.sendline( cmdStr )
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                cleanedOutput = ansiEscape.sub( '', output )
-                return cleanedOutput
-            else:
-                cmdStr = "onos:leaders"
-                output = self.sendline( cmdStr )
-                return output
+                cmdStr += " -j"
+            output = self.sendline( cmdStr )
+            return output
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -2399,16 +2524,11 @@
         Returns the output of the intent Pending map.
         """
         try:
+            cmdStr = "onos:intents -p"
             if jsonFormat:
-                cmdStr = "onos:intents -p -j"
-                output = self.sendline( cmdStr )
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                cleanedOutput = ansiEscape.sub( '', output )
-                return cleanedOutput
-            else:
-                cmdStr = "onos:intents -p"
-                output = self.sendline( cmdStr )
-                return output
+                cmdStr += " -j"
+            output = self.sendline( cmdStr )
+            return output
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -2438,16 +2558,11 @@
         #     "term": 3
         # },
         try:
+            cmdStr = "onos:partitions"
             if jsonFormat:
-                cmdStr = "onos:partitions -j"
-                output = self.sendline( cmdStr )
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                cleanedOutput = ansiEscape.sub( '', output )
-                return cleanedOutput
-            else:
-                cmdStr = "onos:partitions"
-                output = self.sendline( cmdStr )
-                return output
+                cmdStr += " -j"
+            output = self.sendline( cmdStr )
+            return output
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -2472,18 +2587,12 @@
         # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
         # "features":"[onos-openflow]","state":"ACTIVE"}]
         try:
+            cmdStr = "onos:apps"
             if jsonFormat:
-                cmdStr = "onos:apps -j"
-                output = self.sendline( cmdStr )
-                assert "Error executing command" not in output
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                cleanedOutput = ansiEscape.sub( '', output )
-                return cleanedOutput
-            else:
-                cmdStr = "onos:apps"
-                output = self.sendline( cmdStr )
-                assert "Error executing command" not in output
-                return output
+                cmdStr += " -j"
+            output = self.sendline( cmdStr )
+            assert "Error executing command" not in output
+            return output
         # FIXME: look at specific exceptions/Errors
         except AssertionError:
             main.log.error( "Error in processing onos:app command: " +
@@ -2595,7 +2704,7 @@
                                 str( output ) )
             # NOTE: we may need to add more checks here
             # else: Command was successful
-            #main.log.debug( "app response: " + repr( output ) )
+            # main.log.debug( "app response: " + repr( output ) )
             return main.TRUE
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -2788,15 +2897,9 @@
             cmdStr = "app-ids"
             if jsonFormat:
                 cmdStr += " -j"
-                output = self.sendline( cmdStr )
-                assert "Error executing command" not in output
-                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
-                cleanedOutput = ansiEscape.sub( '', output )
-                return cleanedOutput
-            else:
-                output = self.sendline( cmdStr )
-                assert "Error executing command" not in output
-                return output
+            output = self.sendline( cmdStr )
+            assert "Error executing command" not in output
+            return output
         except AssertionError:
             main.log.error( "Error in processing onos:app-ids command: " +
                             str( output ) )
@@ -2888,3 +2991,108 @@
             main.cleanup()
             main.exit()
 
+    def getCfg( self, component=None, propName=None, short=False,
+                jsonFormat=True ):
+        """
+        Get configuration settings from onos cli
+        Optional arguments:
+            component - Optionally only list configurations for a specific
+                        component. If None, all components with configurations
+                        are displayed. Case Sensitive string.
+            propName - If component is specified, propName option will show
+                       only this specific configuration from that component.
+                       Case Sensitive string.
+            jsonFormat - Returns output as json. Note that this will override
+                         the short option
+            short - Short, less verbose, version of configurations.
+                    This is overridden by the json option
+        returns:
+            Output from cli as a string or None on error
+        """
+        try:
+            baseStr = "cfg"
+            cmdStr = " get"
+            componentStr = ""
+            if component:
+                componentStr += " " + component
+                if propName:
+                    componentStr += " " + propName
+            if jsonFormat:
+                baseStr += " -j"
+            elif short:
+                baseStr += " -s"
+            output = self.sendline( baseStr + cmdStr + componentStr )
+            assert "Error executing command" not in output
+            return output
+        except AssertionError:
+            main.log.error( "Error in processing 'cfg get' command: " +
+                            str( output ) )
+            return None
+        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 setCfg( self, component, propName, value=None, check=True ):
+        """
+        Set/Unset configuration settings from ONOS cli
+        Optional arguments:
+            component - The case sensitive name of the component whose
+                        property is to be set
+            propName - The case sensitive name of the property to be set/unset
+            value - The value to set the property to. If None, will unset the
+                    property and revert it to it's default value(if applicable)
+            check - Boolean, Check whether the option was successfully set this
+                    only applies when a value is given.
+        returns:
+            main.TRUE on success or main.FALSE on failure. If check is False,
+            will return main.TRUE unless there is an error
+        """
+        try:
+            baseStr = "cfg"
+            cmdStr = " set " + str( component ) + " " + str( propName )
+            if value is not None:
+                cmdStr += " " + str( value )
+            output = self.sendline( baseStr + cmdStr )
+            assert "Error executing command" not in output
+            if value and check:
+                results = self.getCfg( component=str( component ),
+                                       propName=str( propName ),
+                                       jsonFormat=True )
+                # Check if current value is what we just set
+                try:
+                    jsonOutput = json.loads( results )
+                    current = jsonOutput[ 'value' ]
+                except ( ValueError, TypeError ):
+                    main.log.exception( "Error parsing cfg output" )
+                    main.log.error( "output:" + repr( results ) )
+                    return main.FALSE
+                if current == str( value ):
+                    return main.TRUE
+                return main.FALSE
+            return main.TRUE
+        except AssertionError:
+            main.log.error( "Error in processing 'cfg set' command: " +
+                            str( output ) )
+            return main.FALSE
+        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/tests/OnosCHO/OnosCHO.py b/TestON/tests/OnosCHO/OnosCHO.py
index cd70c80..d5b9400 100644
--- a/TestON/tests/OnosCHO/OnosCHO.py
+++ b/TestON/tests/OnosCHO/OnosCHO.py
@@ -195,7 +195,7 @@
         for i in range( 1, ( main.numMNswitches + 1 ) ):  # 1 to ( num of switches +1 )
             main.Mininet1.assignSwController(
                 sw=str( i ),
-                count=int( main.numCtrls ),
+                count= 1 ,
                 ip1=main.ONOS1_ip,
                 port1=main.ONOS1_port,
                 ip2=main.ONOS2_ip,
@@ -206,7 +206,7 @@
                 port4=main.ONOS4_port,
                 ip5=main.ONOS5_ip,
                 port5=main.ONOS5_port )
-
+            time.sleep(2)
         switch_mastership = main.TRUE
         for i in range( 1, ( main.numMNswitches + 1 ) ):
             response = main.Mininet1.getSwController( "s" + str( i ) )
@@ -242,13 +242,14 @@
         """
         time.sleep(15)
         #Don't balance master for now..
-        main.step( "Balance devices across controllers" )
+        """main.step( "Balance devices across controllers" )
         for i in range( int( main.numCtrls ) ):
             balanceResult = main.ONOScli1.balanceMasters()
             # giving some breathing time for ONOS to complete re-balance
             time.sleep( 3 )
         topology_output = main.ONOScli1.topology()
         topology_result = main.ONOSbench.getTopology( topology_output )
+        """
         case2Result = ( switch_mastership and startStatus )
         utilities.assert_equals(
             expect=main.TRUE,
@@ -350,7 +351,7 @@
         main.case(
             "Assign and Balance all Mininet switches across controllers" )
         main.step( "Stop any previous Mininet network topology" )
-        stopStatus = main.Mininet1.stopNet(fileName = "topoSpine" )
+        #stopStatus = main.Mininet1.stopNet(fileName = "topoSpine" )
         main.step( "Start Mininet with Spine topology" )
         startStatus = main.Mininet1.startNet(topoFile = main.newTopo)
         time.sleep(20)
@@ -564,7 +565,7 @@
         main.step( "Verify Pingall" )
         ping_result = main.FALSE
         time1 = time.time()
-        ping_result = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        ping_result = main.Mininet1.pingall( timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -644,7 +645,7 @@
         main.step( "Verify Pingall" )
         ping_result = main.FALSE
         time1 = time.time()
-        ping_result = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        ping_result = main.Mininet1.pingall( timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -724,7 +725,7 @@
         main.step( "Verify Pingall" )
         ping_result = main.FALSE
         time1 = time.time()
-        ping_result = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        ping_result = main.Mininet1.pingall( timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -901,13 +902,21 @@
         intentsJson = main.ONOScli2.intents()
         getIntentStateResult = main.ONOScli1.getIntentState(intentsId = intentIdList,
                 intentsJson = intentsJson)
+        print "len of intent ID", str(len(intentIdList))
+        print "len of intent state results", str(len(getIntentStateResult))
         print getIntentStateResult
         # Takes awhile for all the onos to get the intents
-        time.sleep(30)
+        time.sleep( 15 )
+        """intentState = main.TRUE
+        for i in getIntentStateResult:
+            if getIntentStateResult.get( 'state' ) != 'INSTALLED':
+        """
+
+
         main.step( "Verify Ping across all hosts" )
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True,acceptableFailed=5)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -969,7 +978,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True,acceptableFailed=5)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1030,7 +1039,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True,acceptableFailed=5)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1112,7 +1121,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResultLinkDown = main.FALSE
         time1 = time.time()
-        pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1177,7 +1186,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResultLinkUp = main.FALSE
         time1 = time.time()
-        pingResultLinkUp = main.Mininet1.pingall( timeout=main.pingTimeout,shortCircuit=True )
+        pingResultLinkUp = main.Mininet1.pingall( timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1256,7 +1265,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResultLinkDown = main.FALSE
         time1 = time.time()
-        pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1321,7 +1330,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResultLinkUp = main.FALSE
         time1 = time.time()
-        pingResultLinkUp = main.Mininet1.pingall(timeout = main.pingTimeout, shortCircuit = True )
+        pingResultLinkUp = main.Mininet1.pingall(timeout = main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1379,7 +1388,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResultLinkDown = main.FALSE
         time1 = time.time()
-        pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True,acceptableFailed=5)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1434,7 +1443,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResultLinkUp = main.FALSE
         time1 = time.time()
-        pingResultLinkUp = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResultLinkUp = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True,acceptableFailed=5)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1492,7 +1501,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResultLinkDown = main.FALSE
         time1 = time.time()
-        pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True,acceptableFailed=5)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1547,7 +1556,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResultLinkUp = main.FALSE
         time1 = time.time()
-        pingResultLinkUp = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResultLinkUp = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True,acceptableFailed=5)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1614,7 +1623,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResultLinkDown = main.FALSE
         time1 = time.time()
-        pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True,acceptableFailed=5)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1667,7 +1676,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResultLinkUp = main.FALSE
         time1 = time.time()
-        pingResultLinkUp = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResultLinkUp = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True,acceptableFailed=5)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1727,7 +1736,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True,acceptableFailed=5)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1790,7 +1799,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True,acceptableFailed=5)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1820,12 +1829,11 @@
         main.case( "Install 4556 point intents" )
         main.step( "Add point Intents" )
         intentResult = main.TRUE
-        main.pingTimeout = 600 
+        main.pingTimeout = 600
         for i in range(len(main.hostMACs)):
             main.MACsDict[main.deviceDPIDs[i+10]] = main.hostMACs[i].split('/')[0]
         print main.MACsDict
-        deviceCombos = list( itertools.permutations( main.deviceDPIDs[10:], 2 ) ) 
-        
+        deviceCombos = list( itertools.permutations( main.deviceDPIDs[10:], 2 ) )
         intentIdList = []
         time1 = time.time()
         for i in xrange( 0, len( deviceCombos ), int(main.numCtrls) ):
@@ -1857,7 +1865,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True,acceptableFailed=5)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1912,20 +1920,38 @@
                 thread.join()
                 intentIdList.append(thread.result)
         time2 = time.time()
-        main.log.info("Time for adding point intents: %2f seconds" %(time2-time1)) 
+        main.log.info("Time for adding point intents: %2f seconds" %(time2-time1))
+        time.sleep(30)
+        print "getting all intents ID"
+        intentIdTemp = main.ONOScli1.getAllIntentsId()
+        print intentIdTemp
+        print len(intentIdList)
         print intentIdList
-        time.sleep(5)
+        checkIntentStateResult = main.TRUE
+        print "Checking intents state"
+        checkIntentStateResult = main.ONOScli1.checkIntentState( intentsId = intentIdList ) and checkIntentStateResult
+        checkIntentStateResult = main.ONOScli2.checkIntentState( intentsId = intentIdList ) and checkIntentStateResult
+        checkIntentStateResult = main.ONOScli3.checkIntentState( intentsId = intentIdList ) and checkIntentStateResult
+        checkIntentStateResult = main.ONOScli4.checkIntentState( intentsId = intentIdList ) and checkIntentStateResult
+        checkIntentStateResult = main.ONOScli5.checkIntentState( intentsId = intentIdList ) and checkIntentStateResult
+        
+        if checkIntentStateResult:
+            main.log.info( "All intents are installed correctly " )
+
+        print "Checking flows state "
+        checkFlowsState = main.ONOScli1.checkFlowsState()
+        time.sleep(50)
         main.step( "Verify Ping across all hosts" )
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True,acceptableFailed=5)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
             "Time taken for Ping All: " +
             str( timeDiff ) +
             " seconds" )
-
+        checkFlowsState = main.ONOScli1.checkFlowsState()
         case93Result = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
@@ -1974,7 +2000,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True,acceptableFailed=5)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2031,7 +2057,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True,acceptableFailed=5)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2086,7 +2112,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True)
+        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True,acceptableFailed=5)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2101,6 +2127,68 @@
             onpass="Install 25 single to multi point Intents and Ping All test PASS",
             onfail="Install 25 single to multi point Intents and Ping All test FAIL" )
 
+    def CASE98( self ):
+        """
+        Install single-multi point intents and verify Ping all works
+        for Spine topology
+        """
+        import copy
+        main.log.report( "Install single-multi point intents and verify Ping all" )
+        main.log.report( "___________________________________________" )
+        main.case( "Install single-multi point intents and Ping all" )
+        deviceDPIDsCopy = copy.copy( main.deviceDPIDs )
+        deviceDPIDsCopy = deviceDPIDsCopy[ 10: ]
+        portEgressList = [ '1' ]*(len(deviceDPIDsCopy) - 1)
+        intentIdList = []
+        MACsDictCopy = {}
+        for i in range( len( deviceDPIDsCopy ) ):
+            MACsDictCopy[ deviceDPIDsCopy[ i ] ] = main.hostMACs[i].split( '/' )[ 0 ]
+
+        print "deviceDPIDsCopy", deviceDPIDsCopy
+        print ""
+        print "MACsDictCopy", MACsDictCopy
+        time1 = time.time()
+        for i in xrange(0,len(deviceDPIDsCopy),int(main.numCtrls)):
+            pool = []
+            for cli in main.CLIs:
+                if i >= len( deviceDPIDsCopy ):
+                    break
+                ingressDevice = deviceDPIDsCopy[i]
+                egressDeviceList = copy.copy(deviceDPIDsCopy)
+                egressDeviceList.remove(ingressDevice)
+                t = main.Thread( target=cli.addSinglepointToMultipointIntent,
+                        threadID=main.threadID,
+                        name="addSinglepointToMultipointIntent",
+                        args =[ingressDevice,egressDeviceList,'1',portEgressList,'IPV4',MACsDictCopy.get(ingressDevice),''])
+                pool.append(t)
+                #time.sleep(1)
+                t.start()
+                i = i + 1
+                main.threadID = main.threadID + 1
+            for thread in pool:
+                thread.join()
+                intentIdList.append(thread.result)
+        time2 = time.time()
+        main.log.info("Time for adding point intents: %2f seconds" %(time2-time1)) 
+        time.sleep(5)
+        main.step( "Verify Ping across all hosts" )
+        pingResult = main.FALSE
+        time1 = time.time()
+        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=True,acceptableFailed=5)
+        time2 = time.time()
+        timeDiff = round( ( time2 - time1 ), 2 )
+        main.log.report(
+            "Time taken for Ping All: " +
+            str( timeDiff ) +
+            " seconds" )
+
+        case98Result = pingResult
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=case98Result,
+            onpass="Install 25 single to multi point Intents and Ping All test PASS",
+            onfail="Install 25 single to multi point Intents and Ping All test FAIL" )
+
     def CASE10( self ):
         import time
         """
@@ -2199,7 +2287,7 @@
                                  onpass="Intent removal test successful",
                                  onfail="Intent removal test failed" )
 
-    def CASE11( self, main ):
+    def CASE12( self, main ):
         """
         Enable onos-app-ifwd, Verify Intent based Reactive forwarding through ping all and Disable it
         """
@@ -2356,3 +2444,4 @@
 
 
 
+
diff --git a/TestON/tests/ProdFunc/ProdFunc.py b/TestON/tests/ProdFunc/ProdFunc.py
index c64ec78..f779b6b 100644
--- a/TestON/tests/ProdFunc/ProdFunc.py
+++ b/TestON/tests/ProdFunc/ProdFunc.py
@@ -812,9 +812,6 @@
             actual=case12Result,
             onpass = "Expected default num of flows exist",
             onfail = "Expected default num of flows do not exist")
-    
-    
-        
 
     def CASE6( self ):
         import time
@@ -940,6 +937,9 @@
             onfail="Pingall Test after Host intents addition failed" )
 
     def CASE5( self, main ):
+        """
+            Check ONOS topology matches with mininet
+        """
         import json
         # assumes that sts is already in you PYTHONPATH
         from sts.topology.teston_topology import TestONTopology
@@ -1052,6 +1052,11 @@
             onfail="Topology checks failed" )
 
     def CASE7( self, main ):
+        """
+            Link discovery test case. Checks if ONOS can discover a link
+            down or up properly.
+        """
+
         from sts.topology.teston_topology import TestONTopology
 
         linkSleep = int( main.params[ 'timers' ][ 'LinkDiscovery' ] )
@@ -1280,8 +1285,11 @@
                                  onfail="Intent removal test failed" )
 
     def CASE9( self ):
+        """
+            Testing Point intents
+        """
         main.log.report(
-            "This testcase adds point intents and then does pingall" )
+            "This test case adds point intents and then does pingall" )
         main.log.report( "__________________________________" )
         main.log.info( "Adding point intents" )
         main.case(