Merge "Added an additional pingall test."
diff --git a/TestON/drivers/common/cli/onosclidriver.py b/TestON/drivers/common/cli/onosclidriver.py
index afd3093..ce493ed 100644
--- a/TestON/drivers/common/cli/onosclidriver.py
+++ b/TestON/drivers/common/cli/onosclidriver.py
@@ -2062,19 +2062,18 @@
 
     def getIntentState(self, intentsId, intentsJson=None):
         """
-            Check intent state.
-            Accepts a single intent ID (string type) or a list of intent IDs.
-            Returns the state(string type) of the id if a single intent ID is
-            accepted.
-            Returns a dictionary with intent IDs as the key and its
-            corresponding states as the values
-            Parameters:
-            intentId: intent ID (string type)
+        Description:
+            Gets intent state. Accepts a single intent ID (string type) or a
+            list of intent IDs.
+        Parameters:
+            intentsId: intent ID, both string type and list type are acceptable
             intentsJson: parsed json object from the onos:intents api
-            Returns:
-            state = An intent's state- INSTALL,WITHDRAWN etc.
-            stateDict = Dictionary of intent's state. intent ID as the keys and
-            state as the values.
+        Returns:
+            Returns the state (string type) of the ID if a single intent ID is
+            accepted.
+            Returns a list of dictionaries if a list of intent IDs is accepted,
+            and each dictionary maps 'id' to the Intent ID and 'state' to
+            corresponding intent state.
         """
         try:
             state = "State is Undefined"
@@ -2428,8 +2427,8 @@
 
             return int(totalFlows)
 
-        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, rawFlows ) )
             return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
@@ -2458,8 +2457,8 @@
                 return  -1
             response = json.loads( response )
             return int( response.get("intents") )
-        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, response ) )
             return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
@@ -2720,6 +2719,9 @@
             topology = json.loads(topologyOutput)
             main.log.debug( topology )
             return topology
+        except ( TypeError, ValueError ):
+            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
+            return None
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
diff --git a/TestON/tests/CHOTestMonkey/dependencies/elements/ONOSElement.py b/TestON/tests/CHOTestMonkey/dependencies/elements/ONOSElement.py
index 699a17d..6831811 100644
--- a/TestON/tests/CHOTestMonkey/dependencies/elements/ONOSElement.py
+++ b/TestON/tests/CHOTestMonkey/dependencies/elements/ONOSElement.py
@@ -33,6 +33,7 @@
         self.default = ''
         self.type = 'INTENT'
         self.id = id
+        self.expectedState = 'INSTALLED'
 
     def isHostIntent( self ):
         return self.type == 'INTENT_HOST'
@@ -40,12 +41,26 @@
     def isPointIntent( self ):
         return self.type == 'INTENT_POINT'
 
+    def isFailed( self ):
+        return self.expectedState == 'FAILED'
+
+    def isInstalled( self ):
+        return self.expectedState == 'INSTALLED'
+
+    def setFailed( self ):
+        self.expectedState = 'FAILED'
+
+    def setInstalled( self ):
+        self.expectedState = 'INSTALLED'
+
 class HostIntent( Intent ):
     def __init__( self, id, hostA, hostB ):
         Intent.__init__( self, id )
         self.type = 'INTENT_HOST'
         self.hostA = hostA
         self.hostB = hostB
+        self.deviceA = hostA.device
+        self.deviceB = hostB.device
 
     def __str__( self ):
         return "ID: " + self.id
diff --git a/TestON/tests/CHOTestMonkey/dependencies/events/CheckEvent.py b/TestON/tests/CHOTestMonkey/dependencies/events/CheckEvent.py
index b22e65c..01aa734 100644
--- a/TestON/tests/CHOTestMonkey/dependencies/events/CheckEvent.py
+++ b/TestON/tests/CHOTestMonkey/dependencies/events/CheckEvent.py
@@ -25,21 +25,15 @@
 
     def startCheckEvent( self, args=None ):
         checkResult = EventStates().PASS
-        intentIDs = []
+        # TODO: check intents that are expected in "FAILED" state?
+        installedIntentIDs = []
         for intent in main.intents:
-            if intent.isHostIntent():
-                deviceA = intent.hostA.device
-                deviceB = intent.hostB.device
-            elif intent.isPointIntent():
-                deviceA = intent.deviceA
-                deviceB = intent.deviceB
-            # Exclude the intents that are to or from removed devices/hosts
-            if not deviceA.isRemoved() and not deviceB.isRemoved():
-                intentIDs.append( intent.id )
+            if intent.isInstalled():
+                installedIntentIDs.append( intent.id )
         for controller in main.controllers:
             if controller.isUp():
                 with controller.CLILock:
-                    intentState = controller.CLI.checkIntentState( intentsId=intentIDs )
+                    intentState = controller.CLI.checkIntentState( intentsId=installedIntentIDs )
                 if not intentState:
                     main.log.warn( "Intent Check - Not all intents are in INSTALLED state on ONOS%s" % ( controller.index ) )
                     checkResult = EventStates().FAIL
diff --git a/TestON/tests/CHOTestMonkey/dependencies/events/NetworkEvent.py b/TestON/tests/CHOTestMonkey/dependencies/events/NetworkEvent.py
index 46b37e7..7247ecf 100644
--- a/TestON/tests/CHOTestMonkey/dependencies/events/NetworkEvent.py
+++ b/TestON/tests/CHOTestMonkey/dependencies/events/NetworkEvent.py
@@ -208,6 +208,9 @@
                 link.backwardLink.setRemoved()
             for host in self.device.hosts:
                 host.setRemoved()
+            for intent in main.intents:
+                if intent.deviceA == self.device or intent.deviceB == self.device:
+                    intent.setFailed()
         return EventStates().PASS
 
 class DeviceUp( DeviceEvent ):
@@ -256,6 +259,11 @@
             with main.variableLock:
                 link.bringUp()
                 link.backwardLink.bringUp()
+                for intent in main.intents:
+                    if intent.isFailed():
+                        if intent.deviceA == self.device and intent.deviceB.isUp() or\
+                        intent.deviceB == self.device and intent.deviceA.isUp():
+                            intent.setInstalled()
         # Re-assign mastership for the device
         with main.mininetLock:
             main.Mininet1.assignSwController( sw=self.device.name, ip=main.onosIPs )