Fix the Totalintent number is less than 0
    - Refactor getTotalFlowsNum driver function, now use more stable method
    - Check flows number, if flows number is not except, will finish this iteration
    - Improved some logical
    - NOTE: sometimes it's still not stable, Be careful.

Change-Id: Ied12cbb93297e26c821641f84d6dc868fb8cb292
diff --git a/TestON/drivers/common/cli/onosclidriver.py b/TestON/drivers/common/cli/onosclidriver.py
index cc5ab50..64d9fbb 100755
--- a/TestON/drivers/common/cli/onosclidriver.py
+++ b/TestON/drivers/common/cli/onosclidriver.py
@@ -441,7 +441,7 @@
         the onos> prompt. Use this function if you have
         a very specific command to send.
 
-        if noExit is True, TestON will not exit, but clean up
+        if noExit is True, TestON will not exit, and return None
 
         Warning: There are no sanity checking to commands
         sent using this method.
@@ -460,8 +460,11 @@
                         main.log.info( self.name + ": onos cli session reconnected." )
                     else:
                         main.log.error( self.name + ": reconnection failed." )
-                        main.cleanup()
-                        main.exit()
+                        if noExit:
+                            return None
+                        else:
+                            main.cleanup()
+                            main.exit()
                 else:
                     main.cleanup()
                     main.exit()
@@ -529,7 +532,6 @@
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
             if noExit:
-                main.cleanup()
                 return None
             else:
                 main.cleanup()
@@ -537,7 +539,6 @@
         except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             if noExit:
-                main.cleanup()
                 return None
             else:
                 main.cleanup()
@@ -2229,12 +2230,13 @@
             main.cleanup()
             main.exit()
 
-    def checkIntentSummary( self, timeout=60 ):
+    def checkIntentSummary( self, timeout=60, noExit=True ):
         """
         Description:
             Check the number of installed intents.
         Optional:
             timeout - the timeout for pexcept
+            noExit - If noExit, TestON will not exit if any except.
         Return:
             Returns main.TRUE only if the number of all installed intents are the same as total intents number
             , otherwise, returns main.FALSE.
@@ -2244,7 +2246,7 @@
             cmd = "intents -s -j"
 
             # Check response if something wrong
-            response = self.sendline( cmd, timeout=timeout )
+            response = self.sendline( cmd, timeout=timeout, noExit=noExit )
             if response == None:
                 return main.FALSE
             response = json.loads( response )
@@ -2263,12 +2265,18 @@
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
-            main.cleanup()
-            main.exit()
+            if noExit:
+                return main.FALSE
+            else:
+                main.cleanup()
+                main.exit()
         except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
-            main.cleanup()
-            main.exit()
+            if noExit:
+                return main.FALSE
+            else:
+                main.cleanup()
+                main.exit()
         except pexpect.TIMEOUT:
             main.log.error( self.name + ": ONOS timeout" )
             return None
@@ -2447,71 +2455,55 @@
             Get the number of ADDED flows.
         Return:
             The number of ADDED flows
+            Or return None if any exceptions
         """
 
         try:
             # get total added flows number
-            cmd = "flows -s|grep ADDED|wc -l"
-            totalFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
-
-            if totalFlows == None:
-                # if timeout, we will get total number of all flows, and subtract other states
-                states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
-                checkedStates = []
+            cmd = "flows -c added"
+            rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
+            if rawFlows:
+                rawFlows = rawFlows.split("\n")
                 totalFlows = 0
-                statesCount = [0, 0, 0, 0]
-
-                # get total flows from summary
-                response = json.loads( self.sendline( "summary -j", timeout=timeout, noExit=noExit ) )
-                totalFlows = int( response.get("flows") )
-
-                for s in states:
-                    rawFlows = self.flows( state=s, timeout = timeout )
-                    if rawFlows == None:
-                        # if timeout, return the total flows number from summary command
-                        return totalFlows
-                    checkedStates.append( json.loads( rawFlows ) )
-
-                # Calculate ADDED flows number, equal total subtracts others
-                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" )
-                    totalFlows = totalFlows - int( statesCount[i] )
-                    main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
-
-                return totalFlows
-
-            return int(totalFlows)
+                for l in rawFlows:
+                    totalFlows += int(l.split("Count=")[1])
+            else:
+                main.log.error("Response not as expected!")
+                return None
+            return totalFlows
 
         except ( TypeError, ValueError ):
-            main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
+            main.log.exception( "{}: Object not as expected!".format( self.name ) )
             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()
+            if not noExit:
+                main.cleanup()
+                main.exit()
+            return None
         except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
-            main.cleanup()
-            main.exit()
+            if not noExit:
+                main.cleanup()
+                main.exit()
+            return None
         except pexpect.TIMEOUT:
             main.log.error( self.name + ": ONOS timeout" )
             return None
 
-    def getTotalIntentsNum( self, timeout=60 ):
+    def getTotalIntentsNum( self, timeout=60, noExit = False ):
         """
         Description:
             Get the total number of intents, include every states.
+        Optional:
+            noExit - If noExit, TestON will not exit if any except.
         Return:
             The number of intents
         """
         try:
             cmd = "summary -j"
-            response = self.sendline( cmd, timeout=timeout )
+            response = self.sendline( cmd, timeout=timeout, noExit=noExit )
             if response == None:
                 return  -1
             response = json.loads( response )
@@ -2522,12 +2514,18 @@
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
-            main.cleanup()
-            main.exit()
+            if noExit:
+                return -1
+            else:
+                main.cleanup()
+                main.exit()
         except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
-            main.cleanup()
-            main.exit()
+            if noExit:
+                return -1
+            else:
+                main.cleanup()
+                main.exit()
 
     def intentsEventsMetrics( self, jsonFormat=True ):
         """
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.params b/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.params
index 8510204..4485f0f 100644
--- a/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.params
+++ b/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.params
@@ -64,10 +64,10 @@
     <NULL>
         # CASE20
         <PUSH>
-            <batch_size>1000</batch_size>
-            <min_intents>10000</min_intents>
-            <max_intents>70000</max_intents>
-            <check_interval>10000</check_interval>
+            <batch_size>500</batch_size>
+            <min_intents>2500</min_intents>
+            <max_intents>1000000</max_intents>
+            <check_interval>2500</check_interval>
         </PUSH>
 
         # if reroute is true
@@ -83,10 +83,10 @@
     <OVS>
         # CASE20
         <PUSH>
-            <batch_size>1000</batch_size>
-            <min_intents>10000</min_intents>
-            <max_intents>500000</max_intents>
-            <check_interval>10000</check_interval>
+            <batch_size>500</batch_size>
+            <min_intents>2500</min_intents>
+            <max_intents>1000000</max_intents>
+            <check_interval>2500</check_interval>
         </PUSH>
 
         # if reroute is true
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.py b/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.py
index c688207..84f65d3 100644
--- a/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.py
+++ b/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.py
@@ -7,9 +7,9 @@
 Push test Intents to onos
 CASE10: set up Null Provider
 CASE11: set up Open Flows
+Check flows number, if flows number is not as except, finished this test iteration
 Scale up when reach the Limited
 Start from 1 nodes, 8 devices. Then Scale up to 3,5,7 nodes
-Recommand batch size: 100, check interval: 100
 '''
 class SCPFscalingMaxIntents:
     def __init__( self ):
@@ -429,6 +429,7 @@
         # make sure the checkInterval divisible batchSize
         main.checkInterval = int( int( main.checkInterval / main.batchSize ) * main.batchSize )
         flowTemp=0
+        intentVerifyTemp = 0
         totalFlows=0
         for i in range(limit):
 
@@ -467,32 +468,52 @@
                 main.log.info("Verify Intents states")
                 # k is a control variable for verify retry attempts
                 k = 1
-
                 while k <= main.verifyAttempts:
-                    # while loop for check intents by using REST api
+                    # while loop for check intents by using CLI driver
                     time.sleep(5)
-                    temp = 0
-                    intentsState = main.CLIs[0].checkIntentSummary(timeout=600)
+                    intentsState = main.CLIs[0].checkIntentSummary(timeout=600, noExit=True)
                     if intentsState:
-                        verifyTotalIntents = main.CLIs[0].getTotalIntentsNum(timeout=600)
-                        if temp < verifyTotalIntents:
-                            temp = verifyTotalIntents 
+                        verifyTotalIntents = main.CLIs[0].getTotalIntentsNum(timeout=600, noExit=True)
+                        if intentVerifyTemp < verifyTotalIntents:
+                            intentVerifyTemp = verifyTotalIntents
                         else:
-                            verifytotalIntents = temp
-                        main.log.info("Total Intents: {}".format( verifyTotalIntents ) )
+                            verifyTotalIntents = intentVerifyTemp
+                        main.log.info("Total Installed Intents: {}".format( verifyTotalIntents ) )
                         break
                     k = k+1
 
-                totalFlows = main.CLIs[0].getTotalFlowsNum( timeout=600, noExit=True )
-                if flowTemp < totalFlows:
-                    flowTemp = totalFlows
-                else:
-                    totalFlows = flowTemp 
+                k = 1
+                flowVerify = True
+                while k <= main.verifyAttempts:
+                    time.sleep(5)
+                    totalFlows = main.CLIs[0].getTotalFlowsNum( timeout=600, noExit=True )
+                    expectFlows = totalIntents * 7 + main.defaultFlows
+                    if totalFlows == expectFlows:
+                        main.log.info("Total Flows Added: {}".format(totalFlows))
+                        break
+                    else:
+                        main.log.info("Some Flows are not added, retry...")
+                        main.log.info("Total Flows Added: {} Expect Flows: {}".format(totalFlows, expectFlows))
+                        flowVerify = False
 
-                if not intentsState:
+                    k += 1
+                    if flowTemp < totalFlows:
+                        flowTemp = totalFlows
+                    else:
+                        totalFlows = flowTemp
+
+                if not intentsState or not flowVerify:
                     # If some intents are not installed, grep the previous flows list, and finished this test case
-                    main.log.warn( "Some intens did not install" )
-                    verifyTotalIntents = main.CLIs[0].getTotalIntentsNum(timeout=600)
+                    main.log.warn( "Intents or flows are not installed" )
+                    verifyTotalIntents = main.CLIs[0].getTotalIntentsNum(timeout=600, noExit=True)
+                    if intentVerifyTemp < verifyTotalIntents:
+                        intentVerifyTemp = verifyTotalIntents
+                    else:
+                        verifyTotalIntents = intentVerifyTemp
+                    if flowTemp < totalFlows:
+                        flowTemp = totalFlows
+                    else:
+                        totalFlows = flowTemp
                     main.log.info("Total Intents: {}".format( verifyTotalIntents) )
                     break