Merge "Add some cases for closed-loop improvement"
diff --git a/TestON/bin/cleanup.sh b/TestON/bin/cleanup.sh
index abeb2e9..d104d3a 100755
--- a/TestON/bin/cleanup.sh
+++ b/TestON/bin/cleanup.sh
@@ -5,3 +5,6 @@
 sudo kill -9 `ps -ef | grep "ssh -X" | grep -v grep | awk '{print $2}'`
 sudo mn -c
 sudo pkill -f mn.pid
+sudo pkill bgpd
+sudo pkill zebra
+sudo kill -9 `ps -ef | grep "bird" | grep -v grep | awk '{print $2}'`
diff --git a/TestON/config/teston.cfg b/TestON/config/teston.cfg
index b255f45..aba93d1 100644
--- a/TestON/config/teston.cfg
+++ b/TestON/config/teston.cfg
@@ -5,6 +5,9 @@
         <class>xmlparser</class>
     </parser>
     <mail_to>hari@onlab.us</mail_to>
+    <mail_from></mail_from>
+    <mail_pass></mail_pass>
+    <mail_server></mail_server>
 
     <logger>
         <file>core/logger.py</file>
diff --git a/TestON/core/logger.py b/TestON/core/logger.py
index c65fa49..05693ba 100644
--- a/TestON/core/logger.py
+++ b/TestON/core/logger.py
@@ -120,6 +120,7 @@
         main.WikiFileName = main.logdir + "/" + main.TEST + "Wiki.txt"
         main.SummaryFileName = main.logdir + "/" + main.TEST + "Summary.txt"
         main.JenkinsCSV = main.logdir + "/" + main.TEST + ".csv"
+        main.TOTAL_TC_SUCCESS = 0
 
         #### Add log-level - Report
         logging.addLevelName(9, "REPORT")
diff --git a/TestON/core/teston.py b/TestON/core/teston.py
index 17893a1..4bbdc3c 100644
--- a/TestON/core/teston.py
+++ b/TestON/core/teston.py
@@ -33,16 +33,16 @@
 import xmldict
 import importlib
 import threading
-module = new.module("test")
+module = new.module( "test" )
 import openspeak
 import subprocess
-global path, drivers_path, core_path, tests_path,logs_path
+global path, drivers_path, core_path, tests_path, logs_path
 location = os.path.abspath( os.path.dirname( __file__ ) )
 path = re.sub( "(core|bin)$", "", location )
-drivers_path = path+"drivers"
-core_path = path+"core"
-tests_path = path+"tests"
-logs_path = path+"logs/"
+drivers_path = path + "drivers"
+core_path = path + "core"
+tests_path = path + "tests"
+logs_path = path + "logs/"
 config_path = path + "config/"
 sys.path.append( path )
 sys.path.append( drivers_path )
@@ -56,13 +56,14 @@
 class TestON:
     '''
     TestON will initiate the specified test.
-    The main tasks are :
+    The main tasks are:
     * Initiate the required Component handles for the test.
     * Create Log file  Handles.
     '''
-    def __init__(self,options):
+    def __init__( self, options ):
         '''
-           Initialise the component handles specified in the topology file of the specified test.
+           Initialise the component handles specified in the topology file of
+           the specified test.
         '''
         # Initialization of the variables.
         __builtin__.main = self
@@ -76,7 +77,6 @@
         self.PASS = True
         self.CASERESULT = self.ERROR
         self.STEPRESULT = self.NORESULT
-        self.stepResults = []
         self.init_result = self.TRUE
         self.testResult = "Summary"
         self.stepName = ""
@@ -97,102 +97,112 @@
         self.cleanupLock = threading.Lock()
         self.initiated = False
 
-        self.configparser()
-        verifyOptions(options)
+        self.config = self.configparser()
+        verifyOptions( options )
         load_logger()
         self.componentDictionary = {}
-        self.componentDictionary = self.topology ['COMPONENT']
-        self.driversList=[]
-        if type(self.componentDictionary) == str :
-            self.componentDictionary = dict(self.componentDictionary)
+        self.componentDictionary = self.topology['COMPONENT']
+        self.driversList = []
+        if isinstance( self.componentDictionary, str):
+            self.componentDictionary = dict( self.componentDictionary )
 
-        for component in self.componentDictionary :
-            self.driversList.append(self.componentDictionary[component]['type'])
+        for component in self.componentDictionary:
+            self.driversList.append( self.componentDictionary[component]['type'] )
 
-        self.driversList = list(set(self.driversList)) # Removing duplicates.
+        self.driversList = list( set( self.driversList ) )  # Removing duplicates.
         # Checking the test_target option set for the component or not
-        if type(self.componentDictionary) == dict:
+        if isinstance( self.componentDictionary, dict ):
             for component in self.componentDictionary.keys():
                 if 'test_target' in self.componentDictionary[component].keys():
                     self.test_target = component
 
         # Checking for the openspeak file and test script
-        self.logger.initlog(self)
+        self.logger.initlog( self )
 
         # Creating Drivers Handles
-        initString = "\n"+"*" * 30+"\n CASE INIT \n"+"*" * 30+"\n"
-        self.log.exact(initString)
+        initString = "\n" + "*" * 30 + "\n CASE INIT \n" + "*" * 30 + "\n"
+        self.log.exact( initString )
         self.driverObject = {}
-        self.random_order = 111 # Random order id to connect the components
+        self.random_order = 111  # Random order id to connect the components
         components_connect_order = {}
-        #component_list.append()
-        if type(self.componentDictionary) == dict:
+        if isinstance( self.componentDictionary, dict ):
             for component in self.componentDictionary.keys():
-                self.componentDictionary[component]['connect_order'] = self.componentDictionary[component]['connect_order'] if ('connect_order' in self.componentDictionary[component].keys()) else str(self.get_random())
-                components_connect_order[component] =  eval(self.componentDictionary[component]['connect_order'])
-            #Ordering components based on the connect order.
-            ordered_component_list =sorted(components_connect_order, key=lambda key: components_connect_order[key])
+                if 'connect_order' not in self.componentDictionary[component].keys():
+                    self.componentDictionary[component]['connect_order'] = str( self.get_random() )
+                components_connect_order[component] = eval( self.componentDictionary[component]['connect_order'] )
+            # Ordering components based on the connect order.
+            ordered_component_list = sorted( components_connect_order,
+                                             key=lambda key: components_connect_order[key] )
             print ordered_component_list
             for component in ordered_component_list:
-                self.componentInit(component)
+                self.componentInit( component )
 
-    def configparser(self):
+    def configparser( self ):
         '''
         It will parse the config file (teston.cfg) and return as dictionary
         '''
-        matchFileName = re.match(r'(.*)\.cfg', self.configFile, re.M | re.I)
+        matchFileName = re.match( r'(.*)\.cfg', self.configFile, re.M | re.I )
         if matchFileName:
-            xml = open(self.configFile).read()
-            try :
-                self.configDict = xmldict.xml_to_dict(xml)
+            xml = open( self.configFile ).read()
+            try:
+                self.configDict = xmldict.xml_to_dict( xml )
                 return self.configDict
             except IOError:
                 print "There is no such file to parse " + self.configFile
         else:
             print "There is no such file to parse " + self.configFile
 
-    def componentInit(self,component):
+    def componentInit( self, component ):
         '''
         This method will initialize specified component
         '''
         global driver_options
         self.initiated = False
-        self.log.info("Creating component Handle: "+component)
+        self.log.info( "Creating component Handle: " + component )
         driver_options = {}
         if 'COMPONENTS' in self.componentDictionary[component].keys():
-            driver_options =dict(self.componentDictionary[component]['COMPONENTS'])
+            driver_options = dict( self.componentDictionary[component]['COMPONENTS'] )
 
-        driver_options['name']=component
+        driver_options['name'] = component
         driverName = self.componentDictionary[component]['type']
-        driver_options ['type'] = driverName
+        driver_options['type'] = driverName
 
-        classPath = self.getDriverPath(driverName.lower())
-        driverModule = importlib.import_module(classPath)
-        driverClass = getattr(driverModule, driverName)
+        classPath = self.getDriverPath( driverName.lower() )
+        driverModule = importlib.import_module( classPath )
+        driverClass = getattr( driverModule, driverName )
         driverObject = driverClass()
 
-        if ( "OCN" in self.componentDictionary[component]['host'] and main.onoscell ):
+        if "OCN" in self.componentDictionary[component]['host'] and\
+           main.onoscell:
             self.componentDictionary[component]['host'] = main.mnIP
 
-        connect_result = driverObject.connect(user_name = self.componentDictionary[component]['user'] if ('user' in self.componentDictionary[component].keys()) else getpass.getuser(),
-                                              ip_address= self.componentDictionary[component]['host'] if ('host' in self.componentDictionary[component].keys()) else 'localhost',
-                                              pwd = self.componentDictionary[component]['password'] if ('password' in self.componentDictionary[component].keys()) else 'changeme',
-                                              port = self.componentDictionary[component]['port'] if ('port' in self.componentDictionary[component].keys()) else None,
-                                              options = driver_options)
+        user_name = self.componentDictionary[component].get( 'user',
+                                                             getpass.getuser() )
+        ip_address = self.componentDictionary[component].get( 'host',
+                                                              'localhost' )
+        pwd = self.componentDictionary[component].get( 'password',
+                                                       'changeme' )
+        port = self.componentDictionary[component].get( 'port' )
+        connect_result = driverObject.connect( user_name=user_name,
+                                               ip_address=ip_address,
+                                               pwd=pwd,
+                                               port=port,
+                                               options=driver_options)
 
         if not connect_result:
-            self.log.error("Exiting from the test execution because the connecting to the "+component+" component failed.")
+            self.log.error( "Exiting from the test execution because connecting to the " +
+                            component + " component failed." )
             self.exit()
 
-        vars(self)[component] = driverObject
+        vars( self )[component] = driverObject
         self.initiated = True
 
-    def run(self):
+    def run( self ):
         '''
-           The Execution of the test script's cases listed in the Test params file will be done here.
-           And Update each test case result.
-           This method will return TRUE if it executed all the test cases successfully,
-           else will retun FALSE
+           The Execution of the test script's cases listed in the Test params
+           file will be done here then update each test case result.
+           This method will return main.TRUE if it executed all the test cases
+           successfully, else will retun main.FALSE
         '''
         self.testCaseResult = {}
         self.TOTAL_TC = 0
@@ -202,117 +212,167 @@
         self.TOTAL_TC_FAIL = 0
         self.TOTAL_TC_PASS = 0
         self.TEST_ITERATION = 0
+
+        # NOTE: number of main.step statements in the
+        #       outer most level of the test case. used to
+        #       execute code in smaller steps
         self.stepCount = 0
         self.CASERESULT = self.NORESULT
 
         import testparser
-        testFile = self.tests_path + "/"+self.TEST + "/"+self.TEST + ".py"
-        test = testparser.TestParser(testFile)
+        testFile = self.tests_path + "/" + self.TEST + "/" + self.TEST + ".py"
+        test = testparser.TestParser( testFile )
         self.testscript = test.testscript
         self.code = test.getStepCode()
-        repeat= int(self.params['repeat']) if ('repeat' in self.params) else 1
-        self.TOTAL_TC_PLANNED = len(self.testcases_list)*repeat
+        repeat = int( self.params.get( 'repeat', 1 ) )
+        self.TOTAL_TC_PLANNED = len( self.testcases_list ) * repeat
 
         result = self.TRUE
-        while(repeat):
+        while repeat:
             for self.CurrentTestCaseNumber in self.testcases_list:
-                result = self.runCase(self.CurrentTestCaseNumber)
-            repeat-=1
+                result = self.runCase( self.CurrentTestCaseNumber )
+            repeat -= 1
         return result
 
     def runCase( self, testCaseNumber ):
         self.CurrentTestCaseNumber = testCaseNumber
         self.CurrentTestCase = ""
-        self.stepResults = []
+
+        # List of step results in a case. ANDed together to get the result
+        self.stepResultsList = []
         self.stepName = ""
         self.caseExplanation = ""
         result = self.TRUE
+
+        # NOTE: number of main.step statements in the
+        #       outer most level of the test case. used to
+        #       execute code in smaller steps
         self.stepCount = 0
+
+        # NOTE: This is the current number of main.step()'s executed
+        #       in a case. Used for logging.
+        self.stepNumber = 0
         self.EXPERIMENTAL_MODE = self.FALSE
         self.addCaseHeader()
         self.testCaseNumber = str( testCaseNumber )
         self.CASERESULT = self.NORESULT
         stopped = False
-        try :
-            self.stepList = self.code[self.testCaseNumber].keys()
+        try:
+            self.code[self.testCaseNumber]
         except KeyError:
             self.log.error( "There is no Test-Case " + self.testCaseNumber )
             return self.FALSE
         self.stepCount = 0
-        while self.stepCount < len(self.code[self.testCaseNumber].keys()):
-            result = self.runStep(self.stepList,self.code,self.testCaseNumber)
+        while self.stepCount < len( self.code[self.testCaseNumber].keys() ):
+            result = self.runStep( self.code, self.testCaseNumber )
             if result == self.FALSE:
                 break
             elif result == self.TRUE:
                 continue
+        # stepResults format: ( stepNo[], stepName[], stepResult[], onFail[] )
+        stepResults = self.stepResultsList
         if not stopped:
             if self.CASERESULT == self.TRUE or self.CASERESULT == self.FALSE:
-                # Result was already explitily set somewhere else like skipCase()
+                # Result was already explitily set somewhere else like
+                # in skipCase()
                 pass
-            elif all( self.TRUE == i for i in self.stepResults ):
+            elif all( self.TRUE == i for i in stepResults ):
                 # ALL PASSED
                 self.CASERESULT = self.TRUE
-            elif self.FALSE in self.stepResults:
+            elif self.FALSE in stepResults:
                 # AT LEAST ONE FAILED
                 self.CASERESULT = self.FALSE
-            elif self.TRUE in self.stepResults:
+            elif self.TRUE in stepResults:
                 # AT LEAST ONE PASSED
                 self.CASERESULT = self.TRUE
             else:
                 self.CASERESULT = self.NORESULT
-            self.testCaseResult[str(self.CurrentTestCaseNumber)] = self.CASERESULT
-            self.logger.updateCaseResults(self)
+            self.testCaseResult[str( self.CurrentTestCaseNumber )] = self.CASERESULT
+            self.logger.updateCaseResults( self )
             self.log.wiki( "<p>" + self.caseExplanation + "</p>" )
             self.log.summary( self.caseExplanation )
             self.log.wiki( "<ul>" )
+            subcaseMessage = False
             for line in self.stepCache.splitlines():
-                if re.search( " - PASS$", line ):
-                    self.log.wiki( "<li>" + line + "  <ac:emoticon ac:name=\"tick\" /></li>\n" )
-                elif re.search( " - FAIL$", line ):
-                    self.log.wiki( "<li>" + line + "  <ac:emoticon ac:name=\"cross\" /></li>\n" )
-                elif re.search( " - No Result$", line ):
-                    self.log.wiki( "<li>" + line + "  <ac:emoticon ac:name=\"warning\" /></li>\n" )
-                else:  # Should only be on fail message
-                    self.log.wiki( "<ul><li>" + line + "</li></ul>\n" )
+                if re.search( "[0-9]\.[0-9]", line ):  # Step
+                    if subcaseMessage:  # End of Failure Message Printout
+                        self.log.wiki( "</ul>\n" )
+                        subcaseMessage = False
+                    if re.search( " - PASS$", line ):
+                        self.log.wiki( "<li>" + line + "  <ac:emoticon ac:name=\"tick\" /></li>\n" )
+                    elif re.search( " - FAIL$", line ):
+                        self.log.wiki( "<li>" + line + "  <ac:emoticon ac:name=\"cross\" /></li>\n" )
+                    elif re.search( " - No Result$", line ):
+                        self.log.wiki( "<li>" + line + "  <ac:emoticon ac:name=\"warning\" /></li>\n" )
+                else:  # Substep
+                    if not subcaseMessage:  # Open Failure Message Printout
+                        self.log.wiki( "<ul><li>" + line + "</li>\n" )
+                        subcaseMessage = True
+                    else:  # Add to Failure Message Printout
+                        self.log.wiki( "<li>" + line + "</li>\n" )
+            if subcaseMessage:  # End of Failure Message Printout for last item
+                self.log.wiki( "</ul>\n" )
             self.log.wiki( "</ul>" )
             self.log.summary( self.stepCache )
             self.stepCache = ""
         return result
 
-    def runStep(self,stepList,code,testCaseNumber):
+    def runStep( self, code, testCaseNumber ):
         if not cli.pause:
-            try :
-                step = stepList[self.stepCount]
-                self.STEPRESULT = self.NORESULT
-                self.onFailMsg = "No on fail message given"
+            try:
+                step = self.stepCount
+                # stepResults format: ( stepNo, stepName, stepResult, onFail )
+                # NOTE: This is needed to catch results of main.step()'s
+                #       called inside functions or loops
+                self.stepResults = ( [], [], [], [] )
                 exec code[testCaseNumber][step] in module.__dict__
                 self.stepCount = self.stepCount + 1
-                if step > 0:
-                    self.stepCache += "\t"+str(testCaseNumber)+"."+str(step)+" "+self.stepName+" - "
-                    if self.STEPRESULT == self.TRUE:
+
+                # Iterate through each of the steps and print them
+                for index in range( len( self.stepResults[0] ) ):
+                    # stepResults = ( stepNo, stepName, stepResult, onFail )
+                    stepNo = self.stepResults[0][ index ]
+                    stepName = self.stepResults[1][ index ]
+                    stepResult = self.stepResults[2][ index ]
+                    onFail = self.stepResults[3][ index ]
+                    self.stepCache += "\t" + str( testCaseNumber ) + "."
+                    self.stepCache += str( stepNo ) + " "
+                    self.stepCache += stepName + " - "
+                    if stepResult == self.TRUE:
                         self.stepCache += "PASS\n"
-                    elif self.STEPRESULT == self.FALSE:
+                    elif stepResult == self.FALSE:
                         self.stepCache += "FAIL\n"
-                        # TODO: Print the on-fail statement here
-                        self.stepCache += "\t\t" + self.onFailMsg + "\n"
+                        self.stepCache += "\t\t" + onFail + "\n"
                     else:
                         self.stepCache += "No Result\n"
-                    self.stepResults.append(self.STEPRESULT)
+                    self.stepResultsList.append( stepResult )
             except StopIteration:  # Raised in self.skipCase()
                 self.log.warn( "Skipping the rest of CASE" +
                                str( testCaseNumber ) )
-                self.stepResults.append(self.STEPRESULT)
+                self.stepResultsList.append( self.STEPRESULT )
                 self.stepCache += "\t\t" + self.onFailMsg + "\n"
                 self.stepCount = self.stepCount + 1
                 return self.FALSE
-            except StandardError:
-                self.log.exception( "\nException in the following section of" +
-                                    " code: " + str( testCaseNumber ) + "." +
-                                    str( step ) + ": " + self.stepName )
-                #print code[testCaseNumber][step]
+            except StandardError as e:
+                try:
+                    stepNo = self.stepResults[0][ self.stepNumber - 1 ]
+                except IndexError:
+                    stepNo = "<IndexError>"
+                    main.log.warn( "Error trying to get step number. " +
+                                   "It is likely between step " +
+                                   str( self.stepNumber ) + " and step" +
+                                   str( self.stepNumber + 1 ) )
+                try:
+                    stepName = self.stepResults[1][ self.stepNumber - 1 ]
+                except IndexError:
+                    stepName = "<IndexError>"
+                self.log.error( "\nException in the following section of" +
+                                " code: " + str( testCaseNumber ) + "." +
+                                str( stepNo ) + ": " + stepName )
+                self.log.error( e )
                 self.stepCount = self.stepCount + 1
-                self.logger.updateCaseResults(self)
-                #WIKI results
+                self.logger.updateCaseResults( self )
+                # WIKI results
                 self.log.wiki( "<ul>" )
                 for line in self.stepCache.splitlines():
                     if re.search( " - PASS$", line ):
@@ -324,7 +384,7 @@
                     else:  # Should only be on fail message
                         self.log.wiki( "<ul><li>" + line + "</li></ul>\n" )
                 self.log.wiki( "</ul>" )
-                #summary results
+                # summary results
                 self.log.summary( self.stepCache )
                 self.stepCache = ""
                 self.cleanup()
@@ -332,10 +392,9 @@
             return self.TRUE
         if cli.stop:
             cli.stop = False
-            stopped = True
             self.TOTAL_TC_NORESULT = self.TOTAL_TC_NORESULT + 1
-            self.testCaseResult[str(self.CurrentTestCaseNumber)] = "Stopped"
-            self.logger.updateCaseResults(self)
+            self.testCaseResult[str( self.CurrentTestCaseNumber )] = "Stopped"
+            self.logger.updateCaseResults( self )
             result = self.cleanup()
             return self.FALSE
 
@@ -360,24 +419,30 @@
             self.onFailMsg += str( msg )
         raise StopIteration
 
-    def addCaseHeader(self):
-        caseHeader = "\n"+"*" * 30+"\n Result summary for Testcase"+str(self.CurrentTestCaseNumber)+"\n"+"*" * 30+"\n"
-        self.log.exact(caseHeader)
-        caseHeader = "\n"+"*" * 40 +"\nStart of Test Case"+str(self.CurrentTestCaseNumber)+" : "
+    def addCaseHeader( self ):
+        caseHeader = "\n" + "*" * 30 + "\n Result summary for Testcase" +\
+                     str( self.CurrentTestCaseNumber ) + "\n" + "*" * 30 + "\n"
+        self.log.exact( caseHeader )
+        caseHeader = "\n" + "*" * 40 + "\nStart of Test Case" +\
+                     str( self.CurrentTestCaseNumber ) + " : "
         for driver in self.componentDictionary.keys():
-            vars(self)[driver+'log'].info(caseHeader)
+            vars( self )[driver + 'log'].info( caseHeader )
 
-    def addCaseFooter(self):
-        if self.stepCount-1 > 0 :
-            previousStep = " "+str(self.CurrentTestCaseNumber)+"."+str(self.stepCount-1)+": "+ str(self.stepName) + ""
-            stepHeader = "\n"+"*" * 40+"\nEnd of Step "+previousStep+"\n"+"*" * 40+"\n"
+    def addCaseFooter( self ):
+        stepNo = self.stepResults[0][-2]
+        if stepNo > 0:
+            previousStep = " " + str( self.CurrentTestCaseNumber ) + "." +\
+                           str( stepNo ) + ": " + str( self.stepName )
+            stepHeader = "\n" + "*" * 40 + "\nEnd of Step " + previousStep +\
+                         "\n" + "*" * 40 + "\n"
 
-        caseFooter = "\n"+"*" * 40+"\nEnd of Test case "+str(self.CurrentTestCaseNumber)+"\n"+"*" * 40+"\n"
+        caseFooter = "\n" + "*" * 40 + "\nEnd of Test case " +\
+                     str( self.CurrentTestCaseNumber ) + "\n" + "*" * 40 + "\n"
 
         for driver in self.driversList:
-            vars(self)[driver].write(stepHeader+"\n"+caseFooter)
+            vars( self )[driver].write( stepHeader + "\n" + caseFooter )
 
-    def cleanup(self):
+    def cleanup( self ):
         '''
         Print a summary of the current test's results then attempt to release
         all the component handles and the close opened file handles.
@@ -395,12 +460,12 @@
                 if self.cleanupFlag is False:  # First thread to run this
                     self.cleanupFlag = True
                     if self.initiated:
-                        self.logger.testSummary(self)
+                        self.logger.testSummary( self )
                     for component in self.componentDictionary.keys():
-                        try :
-                            tempObject  = vars(self)[component]
-                            print "Disconnecting from " + str(tempObject.name) + ": " + \
-                                  str(tempObject)
+                        try:
+                            tempObject = vars( self )[component]
+                            print "Disconnecting from " + str( tempObject.name ) +\
+                                  ": " + str( tempObject.__class__)
                             tempObject.disconnect()
                         except KeyboardInterrupt:
                             pass
@@ -415,7 +480,7 @@
                     # Closing all the driver's session files
                     for driver in self.componentDictionary.keys():
                         try:
-                            vars(self)[driver].close_log_handles()
+                            vars( self )[driver].close_log_handles()
                         except KeyboardInterrupt:
                             pass
                         except KeyError:
@@ -440,210 +505,226 @@
             lock.release()
         return result
 
-    def pause(self):
+    def pause( self ):
         '''
-        This function will pause the test's execution, and will continue after user provide 'resume' command.
+        This function will pause the test's execution, and will continue after
+        user provide 'resume' command.
         '''
         __builtin__.testthread.pause()
 
-    def onfail(self,*components):
+    def onfail( self, *components ):
         '''
         When test step failed, calling all the components onfail.
         '''
         if not components:
-            try :
+            try:
                 for component in self.componentDictionary.keys():
-                    tempObject  = vars(self)[component]
+                    tempObject = vars( self )[component]
                     result = tempObject.onfail()
             except StandardError as e:
-                print str(e)
+                print str( e )
                 result = self.FALSE
         else:
-            try :
+            try:
                 for component in components:
-                    tempObject  = vars(self)[component]
+                    tempObject = vars( self )[component]
                     result = tempObject.onfail()
             except StandardError as e:
-                print str(e)
+                print str( e )
                 result = self.FALSE
 
-    def getDriverPath(self,driverName):
+    def getDriverPath( self, driverName ):
         '''
-           Based on the component 'type' specified in the params , this method will find the absolute path ,
-           by recursively searching the name of the component.
+           Based on the component 'type' specified in the params , this method
+           will find the absolute path, by recursively searching the name of
+           the component.
+
+           NOTE: This function requires the linux 'find' command.
         '''
         import commands
 
-        cmd = "find "+drivers_path+" -name "+driverName+".py"
-        result = commands.getoutput(cmd)
+        cmd = "find " + drivers_path + " -name " + driverName + ".py"
+        result = commands.getoutput( cmd )
 
-        result_array = str(result).split('\n')
+        result_array = str( result ).split( '\n' )
         result_count = 0
 
         for drivers_list in result_array:
-            result_count = result_count+1
-        if result_count > 1 :
-            print "found "+driverName+" "+ str(result_count) + "  times"+str(result_array)
+            result_count = result_count + 1
+        if result_count > 1:
+            print "Found " + driverName + " " + str( result_count ) + " times:"
+            print str( result_array )
             self.exit()
 
-        result = re.sub("(.*)drivers","",result)
-        result = re.sub("\/\/","/",result)
-        result = re.sub("\.py","",result)
-        result = re.sub("\.pyc","",result)
-        result = re.sub("\/",".",result)
-        result = "drivers"+result
+        result = re.sub( "(.*)drivers", "", result )
+        result = re.sub( "\/\/", "/", result )
+        result = re.sub( "\.py", "", result )
+        result = re.sub( "\.pyc", "", result )
+        result = re.sub( "\/", ".", result )
+        result = "drivers" + result
         return result
 
-    def step(self,stepDesc):
+    def step( self, stepDesc ):
         '''
            The step information of the test-case will append to the logs.
         '''
-        previousStep = " "+str(self.CurrentTestCaseNumber)+"."+str(self.stepCount-1)+": "+ str(self.stepName) + ""
+        previousStep = " " + str( self.CurrentTestCaseNumber ) + "." +\
+                       str( self.stepNumber ) + ": " + str( self.stepName )
         self.stepName = stepDesc
+        self.stepNumber += 1
+        self.stepResults[0].append( self.stepNumber )
+        self.stepResults[1].append( stepDesc )
+        self.stepResults[2].append( self.NORESULT )
+        self.stepResults[3].append( "No on fail message given" )
 
-        stepName = " "+str(self.CurrentTestCaseNumber)+"."+str(self.stepCount)+": "+ str(stepDesc) + ""
-        try :
-            if self.stepCount == 0:
-                stepName = " INIT : Initializing the test case :"+self.CurrentTestCase
-        except AttributeError:
-                stepName = " INIT : Initializing the test case :"+str(self.CurrentTestCaseNumber)
-
+        stepName = " " + str( self.CurrentTestCaseNumber ) + "." +\
+                   str( self.stepNumber ) + ": " + str( stepDesc )
         self.log.step(stepName)
         stepHeader = ""
-        if self.stepCount > 1 :
-            stepHeader = "\n"+"-"*45+"\nEnd of Step "+previousStep+"\n"+"-"*45+"\n"
-
-        stepHeader += "\n"+"-"*45+"\nStart of Step"+stepName+"\n"+"-"*45+"\n"
+        line = "\n" + "-" * 45 + "\n"
+        if self.stepNumber > 1:
+            stepHeader = line + "End of Step " + previousStep + line
+        stepHeader += line + "Start of Step" + stepName + line
         for driver in self.componentDictionary.keys():
-            vars(self)[driver+'log'].info(stepHeader)
+            vars( self )[driver + 'log'].info( stepHeader )
 
-    def case(self,testCaseName):
+    def case( self, testCaseName ):
         '''
            Test's each test-case information will append to the logs.
         '''
         self.CurrentTestCase = testCaseName
-        testCaseName = " " + str(testCaseName) + ""
-        self.log.case(testCaseName)
-        caseHeader = testCaseName+"\n"+"*" * 40+"\n"
+        testCaseName = " " + str( testCaseName )
+        self.log.case( testCaseName )
+        caseHeader = testCaseName + "\n" + "*" * 40 + "\n"
         for driver in self.componentDictionary.keys():
-            vars(self)[driver+'log'].info(caseHeader)
+            vars( self )[driver + 'log'].info( caseHeader )
 
-    def testDesc(self,description):
+    def testDesc( self, description ):
         '''
            Test description will append to the logs.
         '''
-        description = "Test Description : " + str (description) + ""
-        self.log.info(description)
+        description = "Test Description : " + str( description )
+        self.log.info( description )
 
-    def _getTest(self):
+    def _getTest( self ):
         '''
-           This method will parse the test script to find required test information.
+        This method will parse the test script to find required test
+        information.
         '''
-        testFile = self.tests_path + "/"+self.TEST + "/"+self.TEST + ".py"
-        testFileHandler = open(testFile, 'r')
+        testFile = self.tests_path + "/" + self.TEST + "/" + self.TEST + ".py"
+        testFileHandler = open( testFile, 'r' )
         testFileList = testFileHandler.readlines()
         testFileHandler.close()
-        #self.TOTAL_TC_PLANNED = 0
         counter = 0
-        for index in range(len(testFileList)):
-            lineMatch = re.match('\s+def CASE(\d+)(.*):',testFileList[index],0)
+        for index in range( len( testFileList ) ):
+            lineMatch = re.match( '\s+def CASE(\d+)(.*):',
+                                  testFileList[index],
+                                  0 )
             if lineMatch:
-                counter  = counter + 1
-                self.TC_PLANNED = len(self.testcases_list)
+                counter = counter + 1
+                self.TC_PLANNED = len( self.testcases_list )
 
-    def response_parser(self,response, return_format):
+    def response_parser( self, response, return_format ):
         ''' It will load the default response parser '''
         response_dict = {}
-        response_dict = self.response_to_dict(response, return_format)
-        return_format_string = self.dict_to_return_format(response,return_format,response_dict)
+        response_dict = self.response_to_dict( response, return_format )
+        return_format_string = self.dict_to_return_format( response,
+                                                           return_format,
+                                                           response_dict )
         return return_format_string
 
-    def response_to_dict(self,response,return_format):
+    def response_to_dict( self, response, return_format ):
         response_dict = {}
-        json_match = re.search('^\s*{', response)
-        xml_match = re.search('^\s*\<', response)
-        ini_match = re.search('^\s*\[', response)
-        if json_match :
-            self.log.info(" Response is in 'JSON' format and Converting to '"+return_format+"' format")
+        json_match = re.search( '^\s*{', response )
+        xml_match = re.search( '^\s*\<', response )
+        ini_match = re.search( '^\s*\[', response )
+        if json_match:
+            self.log.info( "Response is in 'JSON' format, converting to '" +
+                           return_format + "' format" )
             # Formatting the json string
-            response = re.sub(r"{\s*'?(\w)", r'{"\1', response)
-            response = re.sub(r",\s*'?(\w)", r',"\1', response)
-            response = re.sub(r"(\w)'?\s*:", r'\1":', response)
-            response = re.sub(r":\s*'(\w)'\s*([,}])", r':"\1"\2', response)
-            try :
+            response = re.sub( r"{\s*'?(\w)", r'{"\1', response )
+            response = re.sub( r",\s*'?(\w)", r',"\1', response )
+            response = re.sub( r"(\w)'?\s*:", r'\1":', response )
+            response = re.sub( r":\s*'(\w)'\s*([,}])", r':"\1"\2', response )
+            try:
                 import json
-                response_dict = json.loads(response)
+                response_dict = json.loads( response )
             except StandardError:
                 self.log.exception( "Json Parser is unable to parse the string" )
             return response_dict
-        elif ini_match :
-            self.log.info(" Response is in 'INI' format and Converting to '"+return_format+"' format")
+        elif ini_match:
+            self.log.info( "Response is in 'INI' format, converting to '" +
+                           return_format + "' format" )
             from configobj import ConfigObj
-            response_file = open("respnse_file.temp",'w')
-            response_file.write(response)
+            response_file = open( "respnse_file.temp", 'w' )
+            response_file.write( response )
             response_file.close()
-            response_dict = ConfigObj("respnse_file.temp")
+            response_dict = ConfigObj( "respnse_file.temp" )
             return response_dict
-        elif xml_match :
-            self.log.info(" Response is in 'XML' format and Converting to '"+return_format+"' format")
-            try :
-                response_dict = xmldict.xml_to_dict("<response> "+str(response)+" </response>")
+        elif xml_match:
+            self.log.info( "Response is in 'XML' format, converting to '" +
+                           return_format + "' format" )
+            try:
+                response_dict = xmldict.xml_to_dict( "<response> " +
+                                                     str( response ) +
+                                                     " </response>" )
             except StandardError:
                 self.log.exception()
             return response_dict
 
-    def dict_to_return_format(self,response,return_format,response_dict):
-        if return_format =='table' :
+    def dict_to_return_format( self, response, return_format, response_dict ):
+        if return_format == 'table':
             ''' Will return in table format'''
             to_do = "Call the table output formatter"
             global response_table
             response_table = '\n'
-            response_table = response_table +'\t'.join(response_dict)+"\n"
+            response_table = response_table + '\t'.join( response_dict ) + "\n"
 
-            def get_table(value_to_convert):
-                ''' This will parse the dictionary recusrsively and print as table format'''
+            def get_table( value_to_convert ):
+                ''' This will parse the dictionary recusrsively and print as
+                    table format'''
                 table_data = ""
-                if type(value_to_convert) == dict :
-                    table_data = table_data +'\t'.join(value_to_convert)+"\n"
-                    for temp_val in value_to_convert.values() :
-                        table_data = table_data + get_table(temp_val)
-                else :
-                    table_data = table_data + str(value_to_convert) +"\t"
+                if isinstance( value_to_convert, dict ):
+                    table_data = table_data + '\t'.join( value_to_convert ) +\
+                                 "\n"
+                    for temp_val in value_to_convert.values():
+                        table_data = table_data + get_table( temp_val )
+                else:
+                    table_data = table_data + str( value_to_convert ) + "\t"
                 return table_data
 
-            for value in response_dict.values() :
-                response_table =  response_table + get_table(value)
-            # response_table = response_table + '\t'.join(response_dict.values())
+            for value in response_dict.values():
+                response_table = response_table + get_table( value )
             return response_table
 
-        elif return_format =='config':
+        elif return_format == 'config':
             ''' Will return in config format'''
             to_do = 'Call dict to config coverter'
-            response_string = str(response_dict)
+            response_string = str( response_dict )
             print response_string
-            response_config = re.sub(",", "\n\t", response_string)
-            response_config = re.sub("u\'", "\'", response_config)
-            response_config = re.sub("{", "", response_config)
-            response_config = re.sub("}", "\n", response_config)
-            response_config = re.sub(":", " =", response_config)
-            return "[response]\n\t "+response_config
+            response_config = re.sub( ",", "\n\t", response_string )
+            response_config = re.sub( "u\'", "\'", response_config )
+            response_config = re.sub( "{", "", response_config )
+            response_config = re.sub( "}", "\n", response_config )
+            response_config = re.sub( ":", " =", response_config )
+            return "[response]\n\t " + response_config
         elif return_format == 'xml':
             ''' Will return in xml format'''
-            response_xml = xmldict.dict_to_xml(response_dict)
-            response_xml = re.sub(">\s*<", ">\n<", response_xml)
-            return "\n"+response_xml
+            response_xml = xmldict.dict_to_xml( response_dict )
+            response_xml = re.sub( ">\s*<", ">\n<", response_xml )
+            return "\n" + response_xml
         elif return_format == 'json':
             ''' Will return in json format'''
             to_do = 'Call dict to xml coverter'
             import json
-            response_json = json.dumps(response_dict)
+            response_json = json.dumps( response_dict )
             return response_json
 
-    def get_random(self):
+    def get_random( self ):
         self.random_order = self.random_order + 1
         return self.random_order
 
-    def exit(self):
+    def exit( self ):
         __builtin__.testthread = None
         for thread in threading.enumerate():
             if thread.isAlive():
@@ -653,248 +734,316 @@
                     # NOTE: We should catch any exceptions while trying to
                     # close the thread so that we can try to close the other
                     # threads as well
-                    print( str( thread.getName() ) + ' could not be terminated' )
+                    print str( thread.getName() ) +\
+                          ' could not be terminated'
         sys.exit()
 
-def verifyOptions(options):
-    '''
-    This will verify the command line options and set to default values, if any option not given in command line.
-    '''
-    import pprint
-    pp = pprint.PrettyPrinter(indent=4)
+    def stop( self, email=False ):
+        """
+        Stop the test until Ctrl-D is entered.
+        Ctrl-C will kill the test
 
-    # pp.pprint(options)
-    verifyTest(options)
-    verifyExample(options)
-    verifyTestScript(options)
+        Optional arguments:
+        email can either be a bool, or you can specify the email address
+        to send the email to
+        """
+        try:
+            if email:
+                if '@' in email:
+                    main.mail = email
+                utilities.send_warning_email()
+            self.log.error( "Test execution suspended. Press Ctrl-D to "
+                            "resume or Ctrl-C to exit the test" )
+            # NOTE: Ctrl-D needs to be entered on a new line
+            while True:
+                # TODO: we could give the user an interactive prompt where
+                #       they could call functions
+                raw_input()
+        except EOFError:
+            return
+        # Pass all other exceptions up to caller
+
+
+def verifyOptions( options ):
+    '''
+    This will verify the command line options and set to default values,
+    if any option not given in command line.
+    '''
+    verifyTest( options )
+    verifyExample( options )
+    verifyTestScript( options )
     verifyParams()
-    verifyLogdir(options)
-    verifyMail(options)
-    verifyTestCases(options)
-    verifyOnosCell(options)
+    verifyLogdir( options )
+    verifyMail( options )
+    verifyTestCases( options )
+    verifyOnosCell( options )
 
-def verifyTest(options):
+def verifyTest( options ):
     try:
         if options.testname:
             main.TEST = options.testname
-            main.classPath = "tests."+main.TEST+"."+main.TEST
+            main.classPath = "tests." + main.TEST + "." + main.TEST
             main.tests_path = tests_path
         elif options.example:
             main.TEST = options.example
-            main.tests_path = path+"/examples/"
-            main.classPath = "examples."+main.TEST+"."+main.TEST
+            main.tests_path = path + "/examples/"
+            main.classPath = "examples." + main.TEST + "." + main.TEST
     except AttributeError:
         print "Test or Example not specified please specify the --test <test name > or --example <example name>"
         main.exit()
 
-def verifyExample(options):
+def verifyExample( options ):
     if options.example:
-        main.testDir = path+'/examples/'
-        main.tests_path = path+"/examples/"
-        main.classPath = "examples."+main.TEST+"."+main.TEST
+        main.testDir = path + '/examples/'
+        main.tests_path = path + "/examples/"
+        main.classPath = "examples." + main.TEST + "." + main.TEST
 
-def verifyLogdir(options):
+def verifyLogdir( options ):
     # Verifying Log directory option
     if options.logdir:
         main.logdir = options.logdir
-    else :
+    else:
         main.logdir = main.FALSE
 
-def verifyMail(options):
-    # Checking the mailing list
-    if options.mail:
+def verifyMail( options ):
+    # Mail-To: field
+    if options.mail:  # Test run specific
         main.mail = options.mail
-    elif main.params.has_key('mail'):
-        main.mail = main.params['mail']
-    else :
-        main.mail = 'paxweb@paxterrasolutions.com'
+    elif main.params.get('mail'):  # Test suite specific
+        main.mail = main.params.get( 'mail' )
+    else:  # TestON specific
+        main.mail = main.config['config'].get( 'mail_to' )
+    # Mail-From: field
+    main.sender = main.config['config'].get( 'mail_from' )
+    # Mail smtp server
+    main.smtp = main.config['config'].get( 'mail_server' )
+    # Mail-From account password
+    main.senderPwd = main.config['config'].get( 'mail_pass' )
 
-def verifyTestCases(options):
+
+def verifyTestCases( options ):
     # Getting Test cases list
     if options.testcases:
         testcases_list = options.testcases
         # sys.exit()
-        testcases_list = re.sub("(\[|\])", "", options.testcases)
-        main.testcases_list = eval(testcases_list+",")
-    else :
+        testcases_list = re.sub( "(\[|\])", "", options.testcases )
+        main.testcases_list = eval( testcases_list + "," )
+    else:
         if 'testcases' in main.params.keys():
-            temp = eval(main.params['testcases']+",")
-            list1=[]
-            if type(temp[0])==list:
+            temp = eval( main.params['testcases'] + "," )
+            list1 = []
+            if isinstance( temp[0], list ):
                 for test in temp:
                     for testcase in test:
-                        if type(testcase)==int:
-                            testcase=[testcase]
-                        list1.extend(testcase)
-            else :
-                temp=list(temp)
+                        if isinstance( testcase, int ):
+                            testcase = [testcase]
+                        list1.extend( testcase )
+            else:
+                temp = list( temp )
                 for testcase in temp:
-                    if type(testcase)==int:
-                        testcase=[testcase]
-                    list1.extend(testcase)
-            main.testcases_list=list1
-        else :
-            print "testcases not specifed in params, please provide in params file or 'testcases' commandline argument"
+                    if isinstance( testcase, int ):
+                        testcase = [testcase]
+                    list1.extend( testcase )
+            main.testcases_list = list1
+        else:
+            print "Testcases not specifed in params, please provide in " +\
+                  "params file or 'testcases' commandline argument"
             sys.exit()
 
-def verifyOnosCell(options):
+def verifyOnosCell( options ):
     # Verifying onoscell option
     if options.onoscell:
         main.onoscell = options.onoscell
         main.onosIPs = []
         main.mnIP = ""
-        cellCMD = ". ~/.profile; cell "+main.onoscell
-        output=subprocess.check_output( ["bash", '-c', cellCMD] )
+        cellCMD = ". ~/.profile; cell " + main.onoscell
+        output = subprocess.check_output( ["bash", '-c', cellCMD] )
         splitOutput = output.splitlines()
-        for i in range( len(splitOutput) ):
-            if( re.match( "OCN", splitOutput[i] ) ):
-                mnNode=splitOutput[i].split("=")
+        for i in range( len( splitOutput ) ):
+            if re.match( "OCN", splitOutput[i] ):
+                mnNode = splitOutput[i].split( "=" )
                 main.mnIP = mnNode[1]
-            # cell already sorts OC variables in bash, so no need to sort in TestON
-            if( re.match( "OC[1-9]", splitOutput[i] ) ):
-                onosNodes = splitOutput[i].split("=")
+            # cell already sorts OC variables in bash, so no need to
+            # sort in TestON
+            if re.match( "OC[1-9]", splitOutput[i] ):
+                onosNodes = splitOutput[i].split( "=" )
                 main.onosIPs.append( onosNodes[1] )
-    else :
+    else:
         main.onoscell = main.FALSE
 
-def verifyTestScript(options):
+def verifyTestScript( options ):
     '''
     Verifyies test script.
     '''
     main.openspeak = openspeak.OpenSpeak()
-    openspeakfile = main.testDir+"/" + main.TEST + "/" + main.TEST + ".ospk"
-    testfile = main.testDir+"/" + main.TEST + "/" + main.TEST + ".py"
-    if os.path.exists(openspeakfile):
+    openspeakfile = main.testDir + "/" + main.TEST + "/" + main.TEST + ".ospk"
+    testfile = main.testDir + "/" + main.TEST + "/" + main.TEST + ".py"
+    if os.path.exists( openspeakfile ):
         # Openspeak file found, compiling to python
-        main.openspeak.compiler(openspeakfile=openspeakfile,writetofile=1)
-    elif os.path.exists(testfile):
+        main.openspeak.compiler( openspeakfile=openspeakfile, writetofile=1 )
+    elif os.path.exists( testfile ):
         # No openspeak found, using python file instead
         pass
     else:
-        print "\nThere is no \""+main.TEST+"\" test script.\nPlease provide a " +\
+        print "\nThere is no \"" + main.TEST + "\" test script.\nPlease provide a " +\
               "Python or OpenSpeak test script in the tests folder: " +\
-              main.testDir+"/" + main.TEST + "/"
+              main.testDir + "/" + main.TEST + "/"
         __builtin__.testthread = None
         main.exit()
-    try :
-        testModule = __import__(main.classPath, globals(), locals(), [main.TEST], -1)
+    try:
+        testModule = __import__( main.classPath,
+                                 globals(),
+                                 locals(),
+                                 [main.TEST],
+                                 -1 )
     except ImportError:
-        print "There was an import error, it might mean that there is no test named "+main.TEST
+        print "There was an import error, it might mean that there is " +\
+              "no test named " + main.TEST
         main.exit()
 
-    testClass = getattr(testModule, main.TEST)
+    testClass = getattr( testModule, main.TEST )
     main.testObject = testClass()
     load_parser()
-    main.params = main.parser.parseParams(main.classPath)
-    main.topology = main.parser.parseTopology(main.classPath)
+    main.params = main.parser.parseParams( main.classPath )
+    main.topology = main.parser.parseTopology( main.classPath )
 
 def verifyParams():
-    try :
+    try:
         main.params = main.params['PARAMS']
     except KeyError:
-        print "Error with the params file: Either the file not specified or the format is not correct"
+        print "Error with the params file: Either the file not specified " +\
+              "or the format is not correct"
         main.exit()
-    try :
+    try:
         main.topology = main.topology['TOPOLOGY']
     except KeyError:
-        print "Error with the Topology file: Either the file not specified or the format is not correct"
+        print "Error with the Topology file: Either the file not specified " +\
+              "or the format is not correct"
         main.exit()
 
-def load_parser() :
+def load_parser():
     '''
     It facilitates the loading customised parser for topology and params file.
     It loads parser mentioned in tab named parser of teston.cfg file.
-    It also loads default xmlparser if no parser have specified in teston.cfg file.
+    It also loads default xmlparser if no parser have specified in teston.cfg
+    file.
 
     '''
     confighash = main.configDict
-    if 'file' in confighash['config']['parser'] and 'class' in confighash['config']['parser']:
+    if 'file' in confighash['config']['parser'] and\
+       'class' in confighash['config']['parser']:
         path = confighash['config']['parser']['file']
-        if path != None or confighash['config']['parser']['class']!= None:
+        if path is not None or\
+           confighash['config']['parser']['class'] is not None:
             try:
                 module = re.sub( r".py\s*$", "", path )
                 moduleList = module.split("/")
-                newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]])
+                newModule = ".".join( moduleList[-2:] )
                 parsingClass = confighash['config']['parser']['class']
-                parsingModule = __import__(newModule, globals(), locals(), [parsingClass], -1)
-                parsingClass = getattr(parsingModule, parsingClass)
+                parsingModule = __import__( newModule,
+                                            globals(),
+                                            locals(),
+                                            [parsingClass],
+                                            -1 )
+                parsingClass = getattr( parsingModule, parsingClass )
                 main.parser = parsingClass()
-                #hashobj = main.parser.parseParams(main.classPath)
-                if hasattr(main.parser,"parseParams") and hasattr(main.parser,"parseTopology") and hasattr(main.parser,"parse"):
+                if hasattr( main.parser, "parseParams" ) and\
+                   hasattr( main.parser, "parseTopology" ) and\
+                   hasattr( main.parser, "parse" ):
                     pass
                 else:
                     print "Invalid parser format"
                     main.exit()
             except ImportError:
-                print "Could not find the file " + path + " using default parser."
+                print "Could not find the file " + path +\
+                      " using default parser."
                 load_defaultParser()
-        elif confighash['config']['parser']['file'] == None or confighash['config']['parser']['class'] == None:
+        elif confighash['config']['parser']['file'] is None or\
+             confighash['config']['parser']['class'] is None:
             load_defaultParser()
     else:
         load_defaultParser()
 
 def load_defaultParser():
     '''
-    It will load the default parser which is xml parser to parse the params and topology file.
+    It will load the default parser which is xml parser to parse the params and
+    topology file.
     '''
     moduleList = main.parserPath.split("/")
-    newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]])
-    try :
+    newModule = ".".join( moduleList[-2:] )
+    try:
         parsingClass = main.parsingClass
-        parsingModule = __import__(newModule, globals(), locals(), [parsingClass], -1)
-        parsingClass = getattr(parsingModule, parsingClass)
+        parsingModule = __import__( newModule,
+                                    globals(),
+                                    locals(),
+                                    [parsingClass],
+                                    -1 )
+        parsingClass = getattr( parsingModule, parsingClass )
         main.parser = parsingClass()
-        if hasattr(main.parser,"parseParams") and hasattr(main.parser,"parseTopology") and hasattr(main.parser,"parse") :
+        if hasattr( main.parser, "parseParams" ) and\
+           hasattr( main.parser, "parseTopology" ) and\
+           hasattr( main.parser, "parse" ):
             pass
         else:
             main.exit()
-
     except ImportError:
         print sys.exc_info()[1]
 
-def load_logger() :
+def load_logger():
     '''
     It facilitates the loading customised parser for topology and params file.
     It loads parser mentioned in tab named parser of teston.cfg file.
-    It also loads default xmlparser if no parser have specified in teston.cfg file.
-
+    It also loads default xmlparser if no parser have specified in teston.cfg
+    file.
     '''
     confighash = main.configDict
-    if 'file' in confighash['config']['logger'] and 'class' in confighash['config']['logger']:
+    if 'file' in confighash['config']['logger'] and\
+       'class' in confighash['config']['logger']:
         path = confighash['config']['logger']['file']
-        if path != None or confighash['config']['logger']['class']!= None :
+        if path is not None or\
+           confighash['config']['logger']['class'] is not None:
             try:
                 module = re.sub( r".py\s*$", "", path )
-                moduleList = module.split("/")
-                newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]])
+                moduleList = module.split( "/" )
+                newModule = ".".join( moduleList[-2:] )
                 loggerClass = confighash['config']['logger']['class']
-                loggerModule = __import__(newModule, globals(), locals(), [loggerClass], -1)
-                loggerClass = getattr(loggerModule, loggerClass)
+                loggerModule = __import__( newModule,
+                                           globals(),
+                                           locals(),
+                                           [loggerClass],
+                                           -1 )
+                loggerClass = getattr( loggerModule, loggerClass )
                 main.logger = loggerClass()
-                #hashobj = main.parser.parseParams(main.classPath)
             except ImportError:
-                print "Could not find the file " + path + " using default logger."
+                print "Could not find the file " + path +\
+                      " using default logger."
                 load_defaultlogger()
-        elif confighash['config']['parser']['file'] == None or confighash['config']['parser']['class'] == None :
+        elif confighash['config']['parser']['file'] is None or\
+             confighash['config']['parser']['class'] is None:
             load_defaultlogger()
     else:
         load_defaultlogger()
 
 def load_defaultlogger():
     '''
-    It will load the default parser which is xml parser to parse the params and topology file.
+    It will load the default parser which is xml parser to parse the params and
+    topology file.
     '''
     moduleList = main.loggerPath.split("/")
-    newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]])
-    try :
+    newModule = ".".join( moduleList[-2:] )
+    try:
         loggerClass = main.loggerClass
-        loggerModule = __import__(newModule, globals(), locals(), [loggerClass], -1)
-        loggerClass = getattr(loggerModule, loggerClass)
+        loggerModule = __import__( newModule,
+                                   globals(),
+                                   locals(),
+                                   [loggerClass],
+                                   -1 )
+        loggerClass = getattr( loggerModule, loggerClass )
         main.logger = loggerClass()
 
     except ImportError:
         print sys.exc_info()[1]
         main.exit()
 
-def _echo(self):
+def _echo( self ):
     print "THIS IS ECHO"
diff --git a/TestON/core/utilities.py b/TestON/core/utilities.py
index 8cd81e5..cdf6c1a 100644
--- a/TestON/core/utilities.py
+++ b/TestON/core/utilities.py
@@ -185,6 +185,14 @@
                 print e
 
         main.last_result = result
+        if main.stepResults[2]:
+            main.stepResults[2][-1] = result
+            try:
+                main.stepResults[3][-1] = arguments[ 'ONFAIL' ]
+            except AttributeError:
+                pass
+        else:
+            main.log.warn( "Assertion called before a test step" )
         return result
 
     def parse_args(self,args, **kwargs):
@@ -207,37 +215,67 @@
         msg = email.mime.Multipart.MIMEMultipart()
         try :
             if main.test_target:
-                sub = "Result summary of \""+main.TEST+"\" run on component \""+main.test_target+"\" Version \""+vars(main)[main.test_target].get_version()+"\": "+str(main.TOTAL_TC_SUCCESS)+"% Passed"
+                sub = "Result summary of \"" + main.TEST + "\" run on component \"" +\
+                      main.test_target + "\" Version \"" +\
+                      vars( main )[main.test_target].get_version() + "\": " +\
+                      str( main.TOTAL_TC_SUCCESS ) + "% Passed"
             else :
-                sub = "Result summary of \""+main.TEST+"\": "+str(main.TOTAL_TC_SUCCESS)+"% Passed"
+                sub = "Result summary of \"" + main.TEST + "\": " +\
+                      str( main.TOTAL_TC_SUCCESS ) + "% Passed"
         except ( KeyError, AttributeError ):
-            sub = "Result summary of \""+main.TEST+"\": "+str(main.TOTAL_TC_SUCCESS)+"% Passed"
+            sub = "Result summary of \"" + main.TEST + "\": " +\
+                  str( main.TOTAL_TC_SUCCESS ) + "% Passed"
 
         msg['Subject'] = sub
-        msg['From'] = 'paxweb@paxterrasolutions.com'
+        msg['From'] = main.sender
         msg['To'] = main.mail
-        #msg['Cc'] = 'paxweb@paxterrasolutions.com'
 
         # The main body is just another attachment
-        body = email.mime.Text.MIMEText(main.logHeader+"\n"+main.testResult)
-        msg.attach(body)
+        body = email.mime.Text.MIMEText( main.logHeader + "\n" +
+                                         main.testResult)
+        msg.attach( body )
 
-        # Attachment
-        for filename in os.listdir(main.logdir):
-            filepath = main.logdir+"/"+filename
-            fp=open(filepath,'rb')
-            att = email.mime.application.MIMEApplication(fp.read(),_subtype="")
+        # Attachments
+        for filename in os.listdir( main.logdir ):
+            filepath = main.logdir + "/" + filename
+            fp = open( filepath, 'rb' )
+            att = email.mime.application.MIMEApplication( fp.read(),
+                                                          _subtype="" )
             fp.close()
-            att.add_header('Content-Disposition','attachment',filename=filename)
-            msg.attach(att)
-
-        smtp = smtplib.SMTP('198.57.211.46')
-        smtp.starttls()
-        smtp.login('paxweb@paxterrasolutions.com','pax@peace')
-        smtp.sendmail(msg['From'],[msg['To']], msg.as_string())
-        smtp.quit()
+            att.add_header( 'Content-Disposition',
+                            'attachment',
+                            filename=filename )
+            msg.attach( att )
+        try:
+            smtp = smtplib.SMTP( main.smtp )
+            smtp.starttls()
+            smtp.login( main.sender, main.senderPwd )
+            smtp.sendmail( msg['From'], [msg['To']], msg.as_string() )
+            smtp.quit()
+        except Exception:
+            main.log.exception( "Error sending email" )
         return main.TRUE
 
+    def send_warning_email( self, subject=None ):
+        try:
+            if not subject:
+                subject = main.TEST + " PAUSED!"
+            # Create a text/plain message
+            msg = email.mime.Multipart.MIMEMultipart()
+
+            msg['Subject'] = subject
+            msg['From'] = main.sender
+            msg['To'] = main.mail
+
+            smtp = smtplib.SMTP( main.smtp )
+            smtp.starttls()
+            smtp.login( main.sender, main.senderPwd )
+            smtp.sendmail( msg['From'], [msg['To']], msg.as_string() )
+            smtp.quit()
+        except Exception:
+            main.log.exception( "" )
+            return main.FALSE
+        return main.TRUE
 
     def parse(self,fileName):
         '''
diff --git a/TestON/drivers/common/api/controller/onosrestdriver.py b/TestON/drivers/common/api/controller/onosrestdriver.py
index 66cd8b4..3ff43c7 100644
--- a/TestON/drivers/common/api/controller/onosrestdriver.py
+++ b/TestON/drivers/common/api/controller/onosrestdriver.py
@@ -20,6 +20,7 @@
 import os
 import requests
 import types
+import sys
 
 from drivers.common.api.controllerdriver import Controller
 
@@ -32,6 +33,7 @@
         super( Controller, self ).__init__()
         self.ip_address = "localhost"
         self.port = "8080"
+        self.wrapped = sys.modules[ __name__ ]
 
     def connect( self, **connectargs ):
         try:
@@ -55,6 +57,24 @@
         self.handle = super( OnosRestDriver, self ).connect()
         return self.handle
 
+    def pprint( self, jsonObject ):
+        """
+        Pretty Prints a json object
+
+        arguments:
+            jsonObject - a parsed json object
+        returns:
+            A formatted string for printing or None on error
+        """
+        try:
+            if isinstance( jsonObject, str ):
+                jsonObject = json.loads( jsonObject )
+            return json.dumps( jsonObject, sort_keys=True,
+                               indent=4, separators=(',', ': '))
+        except ( TypeError, ValueError ):
+            main.log.exception( "Error parsing jsonObject" )
+            return None
+
     def send( self, ip, port, url, base="/onos/v1", method="GET",
               query=None, data=None, debug=False ):
         """
@@ -93,10 +113,10 @@
         except requests.exceptions:
             main.log.exception( "Error sending request." )
             return None
-        except Exception as e:
-            main.log.exception( e )
-            return None
-        # FIXME: add other exceptions
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def intents( self, ip="DEFAULT", port="DEFAULT" ):
         """
@@ -121,15 +141,20 @@
                 if 200 <= response[ 0 ] <= 299:
                     output = response[ 1 ]
                     a = json.loads( output ).get( 'intents' )
+                    assert a is not None, "Error parsing json object"
                     b = json.dumps( a )
                     return b
                 else:
                     main.log.error( "Error with REST request, response was: " +
                                     str( response ) )
                     return main.FALSE
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, AssertionError, 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 intent( self, intentId, appId="org.onosproject.cli",
                 ip="DEFAULT", port="DEFAULT" ):
@@ -169,9 +194,13 @@
                     main.log.error( "Error with REST request, response was: " +
                                     str( response ) )
                     return main.FALSE
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, TypeError ):
+            main.log.exception( self.name + ": Object not as expected" )
             return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def getIntentsId( self, ip="DEFAULT", port="DEFAULT" ):
         """
@@ -187,18 +216,19 @@
             intentsDict = json.loads( self.intents( ip=ip, port=port ) )
             for intent in intentsDict:
                 intentsIdList.append( intent.get( 'id' ) )
-
             if not intentsIdList:
                 main.log.debug( "Cannot find any intents" )
                 return main.FALSE
             else:
                 main.log.info( "Found intents: " + str( intentsIdList ) )
                 return main.TRUE
-
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, TypeError ):
+            main.log.exception( self.name + ": Object not as expected" )
             return None
-
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def apps( self, ip="DEFAULT", port="DEFAULT" ):
         """
@@ -222,15 +252,20 @@
                 if 200 <= response[ 0 ] <= 299:
                     output = response[ 1 ]
                     a = json.loads( output ).get( 'applications' )
+                    assert a is not None, "Error parsing json object"
                     b = json.dumps( a )
                     return b
                 else:
                     main.log.error( "Error with REST request, response was: " +
                                     str( response ) )
                     return main.FALSE
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, AssertionError, 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 activateApp( self, appName, ip="DEFAULT", port="DEFAULT", check=True ):
         """
@@ -280,9 +315,13 @@
                     main.log.error( "Error with REST request, response was: " +
                                     str( response ) )
                     return main.FALSE
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, TypeError ):
+            main.log.exception( self.name + ": Object not as expected" )
             return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def deactivateApp( self, appName, ip="DEFAULT", port="DEFAULT",
                        check=True ):
@@ -332,9 +371,13 @@
                     main.log.error( "Error with REST request, response was: " +
                                     str( response ) )
                     return main.FALSE
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, TypeError ):
+            main.log.exception( self.name + ": Object not as expected" )
             return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def getApp( self, appName, project="org.onosproject.", ip="DEFAULT",
                 port="DEFAULT" ):
@@ -367,9 +410,13 @@
                     main.log.error( "Error with REST request, response was: " +
                                     str( response ) )
                     return main.FALSE
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, TypeError ):
+            main.log.exception( self.name + ": Object not as expected" )
             return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def addHostIntent( self, hostIdOne, hostIdTwo, appId='org.onosproject.cli',
                        ip="DEFAULT", port="DEFAULT" ):
@@ -419,9 +466,13 @@
                                     str( response ) )
                     return main.FALSE
 
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, TypeError ):
+            main.log.exception( self.name + ": Object not as expected" )
             return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def addPointIntent( self,
                         ingressDevice,
@@ -567,10 +618,13 @@
                                     str( response ) )
                     return main.FALSE
 
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, TypeError ):
+            main.log.exception( self.name + ": Object not as expected" )
             return None
-
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def removeIntent( self, intentId, appId='org.onosproject.cli',
                        ip="DEFAULT", port="DEFAULT" ):
@@ -600,9 +654,13 @@
                     main.log.error( "Error with REST request, response was: " +
                                     str( response ) )
                     return main.FALSE
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, TypeError ):
+            main.log.exception( self.name + ": Object not as expected" )
             return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def getIntentsId( self, ip="DEFAULT", port="DEFAULT" ):
         """
@@ -611,14 +669,16 @@
         try:
             intentIdList = []
             intentsJson = json.loads( self.intents() )
-            print intentsJson
             for intent in intentsJson:
                 intentIdList.append( intent.get( 'id' ) )
-            print intentIdList
             return intentIdList
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, TypeError ):
+            main.log.exception( self.name + ": Object not as expected" )
             return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def removeAllIntents( self, intentIdList ='ALL',appId='org.onosproject.cli',
                           ip="DEFAULT", port="DEFAULT", delay=5 ):
@@ -660,10 +720,13 @@
                     return main.FALSE
             else:
                 main.log.debug( self.name + ": There is no intents ID list" )
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, TypeError ):
+            main.log.exception( self.name + ": Object not as expected" )
             return None
-
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def hosts( self, ip="DEFAULT", port="DEFAULT" ):
         """
@@ -688,15 +751,20 @@
                 if 200 <= response[ 0 ] <= 299:
                     output = response[ 1 ]
                     a = json.loads( output ).get( 'hosts' )
+                    assert a is not None, "Error parsing json object"
                     b = json.dumps( a )
                     return b
                 else:
                     main.log.error( "Error with REST request, response was: " +
                                     str( response ) )
                     return main.FALSE
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, AssertionError, 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 getHost( self, mac, vlan="-1", ip="DEFAULT", port="DEFAULT" ):
         """
@@ -738,9 +806,13 @@
                     main.log.error( "Error with REST request, response was: " +
                                     str( response ) )
                     return main.FALSE
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, TypeError ):
+            main.log.exception( self.name + ": Object not as expected" )
             return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def topology( self, ip="DEFAULT", port="DEFAULT" ):
         """
@@ -770,9 +842,51 @@
                     main.log.error( "Error with REST request, response was: " +
                                     str( response ) )
                     return main.FALSE
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, TypeError ):
+            main.log.exception( self.name + ": Object not as expected" )
             return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def devices( self, ip="DEFAULT", port="DEFAULT" ):
+        """
+        Description:
+            Get the devices discovered by ONOS is json string format
+        Returns:
+            a json string of the devices currently discovered by ONOS OR
+            main.FALSE if there is an error in the request OR
+            Returns None for exception
+        """
+        try:
+            output = None
+            if ip == "DEFAULT":
+                main.log.warn( "No ip given, reverting to ip from topo file" )
+                ip = self.ip_address
+            if port == "DEFAULT":
+                main.log.warn( "No port given, reverting to port " +
+                               "from topo file" )
+                port = self.port
+            response = self.send( ip, port, url="/devices" )
+            if response:
+                if 200 <= response[ 0 ] <= 299:
+                    output = response[ 1 ]
+                    a = json.loads( output ).get( 'devices' )
+                    assert a is not None, "Error parsing json object"
+                    b = json.dumps( a )
+                    return b
+                else:
+                    main.log.error( "Error with REST request, response was: " +
+                                    str( response ) )
+                    return main.FALSE
+        except ( AttributeError, AssertionError, 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 getIntentState( self, intentsId, intentsJson=None,
                         ip="DEFAULT", port="DEFAULT" ):
@@ -823,12 +937,13 @@
                 main.log.info( "Invalid intents ID entry" )
                 return None
 
-        except TypeError:
-            main.log.exception( self.name + ": Object Type not as expected" )
+        except ( AttributeError, TypeError ):
+            main.log.exception( self.name + ": Object not as expected" )
             return None
-        except Exception as e:
-            main.log.exception( e )
-            return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def checkIntentState( self, intentsId="ALL", expectedState='INSTALLED',
                           ip="DEFAULT", port="DEFAULT"):
@@ -889,12 +1004,13 @@
                                " intents are in " + str( expectedState ) +
                                " state" )
             return returnValue
-        except TypeError:
+        except ( AttributeError, TypeError ):
             main.log.exception( self.name + ": Object not as expected" )
-            return main.FALSE
-        except Exception as e:
-            main.log.exception( e )
             return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def flows( self, ip="DEFAULT", port="DEFAULT" ):
         """
@@ -902,7 +1018,9 @@
             Get flows currently added to the system
         NOTE:
             The flows -j cli command has completely different format than
-            the REST output; Returns None for exception
+            the REST output
+
+        Returns None for exception
         """
         try:
             output = None
@@ -918,23 +1036,28 @@
                 if 200 <= response[ 0 ] <= 299:
                     output = response[ 1 ]
                     a = json.loads( output ).get( 'flows' )
+                    assert a is not None, "Error parsing json object"
                     b = json.dumps( a )
                     return b
                 else:
                     main.log.error( "Error with REST request, response was: " +
                                     str( response ) )
                     return main.FALSE
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, AssertionError, 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 getFlows( self, device, flowId=0, ip="DEFAULT", port="DEFAULT" ):
+    def getFlows( self, deviceId, flowId=None, ip="DEFAULT", port="DEFAULT" ):
         """
         Description:
             Gets all the flows of the device or get a specific flow in the
             device by giving its flow ID
         Required:
-            str device - device/switch Id
+            str deviceId - device/switch Id
         Optional:
             int/hex flowId - ID of the flow
         """
@@ -947,7 +1070,7 @@
                 main.log.warn( "No port given, reverting to port " +
                                "from topo file" )
                 port = self.port
-            url = "/flows/" + device
+            url = "/flows/" + deviceId
             if flowId:
                 url += "/" + str( int( flowId ) )
             print url
@@ -956,16 +1079,20 @@
                 if 200 <= response[ 0 ] <= 299:
                     output = response[ 1 ]
                     a = json.loads( output ).get( 'flows' )
+                    assert a is not None, "Error parsing json object"
                     b = json.dumps( a )
                     return b
                 else:
                     main.log.error( "Error with REST request, response was: " +
                                     str( response ) )
                     return main.FALSE
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, AssertionError, 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 addFlow( self,
                  deviceId,
@@ -1009,17 +1136,14 @@
             of the ONOS node
         """
         try:
-
             flowJson = { "priority":100,
                            "isPermanent":"true",
                            "timeout":0,
                            "deviceId":deviceId,
                            "treatment":{"instructions":[]},
                            "selector": {"criteria":[]}}
-
             if appId:
                 flowJson[ "appId" ] = appId
-
             if egressPort:
                 flowJson[ 'treatment' ][ 'instructions' ].append(
                                                        { "type":"OUTPUT",
@@ -1064,11 +1188,10 @@
                 flowJson[ 'selector' ][ 'criteria' ].append(
                                                        { "type":"IP_PROTO",
                                                          "protocol": ipProto } )
-
-            # TODO: Bandwidth and Lambda will be implemented if needed
-
-            main.log.debug( flowJson )
-
+            if bandwidth or lambdaAlloc:
+                # TODO: Bandwidth and Lambda will be implemented if needed
+                raise NotImplementedError
+            main.log.debug( "Adding flow: " + self.pprint( flowJson ) )
             output = None
             if ip == "DEFAULT":
                 main.log.warn( "No ip given, reverting to ip from topo file" )
@@ -1092,10 +1215,15 @@
                     main.log.error( "Error with REST request, response was: " +
                                     str( response ) )
                     return main.FALSE
-
-        except Exception as e:
-            main.log.exception( e )
+        except NotImplementedError as e:
+            raise e  # Inform the caller
+        except ( AttributeError, TypeError ):
+            main.log.exception( self.name + ": Object not as expected" )
             return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def removeFlow( self, deviceId, flowId,
                        ip="DEFAULT", port="DEFAULT" ):
@@ -1131,9 +1259,13 @@
                     main.log.error( "Error with REST request, response was: " +
                                     str( response ) )
                     return main.FALSE
-        except Exception as e:
-            main.log.exception( e )
+        except ( AttributeError, TypeError ):
+            main.log.exception( self.name + ": Object not as expected" )
             return None
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def checkFlowsState( self , ip="DEFAULT", port="DEFAULT" ):
         """
@@ -1155,11 +1287,8 @@
                                    str( flow.get( 'state' ) ) )
                     returnValue = main.FALSE
             return returnValue
-        except TypeError:
+        except ( AttributeError, TypeError ):
             main.log.exception( self.name + ": Object not as expected" )
-            return main.FALSE
-        except Exception as e:
-            main.log.exception( e )
             return None
         except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
diff --git a/TestON/drivers/common/api/dockerapidriver.py b/TestON/drivers/common/api/dockerapidriver.py
new file mode 100644
index 0000000..2630f6b
--- /dev/null
+++ b/TestON/drivers/common/api/dockerapidriver.py
@@ -0,0 +1,242 @@
+#!/usr/bin/env python
+
+import json
+import os
+import re
+import subprocess
+from docker import Client
+from drivers.common.apidriver import API
+
+class DockerApiDriver( API ):
+
+    def __init__( self ):
+        """
+        Initialize client
+        """
+        self.name = None
+        self.home = None
+        self.handle = None
+        super( API, self ).__init__()
+
+    def connect( self, **connectargs ):
+        """
+        Create Client handle to connnect to Docker server
+        """
+        try:
+            for key in connectargs:
+                vars( self )[ key ] = connectargs[ key ]
+            self.name = self.options[ 'name' ]
+            for key in self.options:
+                if key == "home":
+                    self.home = self.options[ 'home' ]
+                    break
+            if self.home is None or self.home == "":
+                self.home = "/var/tmp"
+
+            self.handle = super( DockerApiDriver, self ).connect()
+            self.dockerClient = Client(base_url='unix://var/run/docker.sock')
+            return self.handle
+        except Exception as e:
+            main.log.exception( e )
+
+    def dockerPull( self, image="onosproject/onos", tag="latest" ):
+        """
+        Pulls Docker image from repository
+        """
+        try:
+            main.log.info( self.name +
+                           ": Pulling Docker image " + image + ":"+tag )
+            for line in self.dockerClient.pull( repository=image, \
+                    tag=tag, stream=True ):
+                response = json.dumps( json.loads( line ), indent=4 )
+            if( re.search( "Downloaded", response ) ):
+                return main.TRUE
+            else:
+                main.log.error( "Failed to download image: " + image +":"+ tag )
+                main.log.error( "Error respone: " )
+                main.log.error( response )
+                return main.FALSE
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def dockerRun( self, image="onosproject/onos", node="onos1" ):
+        """
+            Run specified Docker container
+        """
+        try:
+            main.log.info( self.name +
+                           ": Creating Docker conatiner for node " + node )
+            reponse = self.dockerClient.create_container( image=image, \
+                    tty=True, hostname=node, detach=True )
+            if( reponse['Warnings'] == 'None' ):
+                main.log.info( "Created container for node: " + node )
+                return main.TRUE
+            else:
+                main.log.info( "Noticed warnings during create" )
+                return main.FALSE
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def dockerStart( self, node="onos1" ):
+        """
+            Start Docker container
+        """
+        try:
+            main.log.info( self.name +
+                           ": Starting Docker conatiner for node " + node )
+            reponse = self.dockerClient.start( node )
+            if( reponse == 'None' ):
+                main.log.info( "Started container for node: " + node )
+                return main.TRUE
+            else:
+                main.log.info( "Noticed warnings during start" )
+                return main.FALSE
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def dockerStop( self, node="onos1" ):
+        """
+            Stop docker container
+        """
+        try:
+            main.log.info( self.name +
+                           ": Stopping Docker conatiner for node " + node )
+            reponse = self.dockerClient.stop( node )
+            if( reponse == 'None' ):
+                main.log.info( "Stopped container for node: " + node )
+                return main.TRUE
+            else:
+                main.log.info( "Noticed warnings during stop" )
+                return main.FALSE
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def dockerRestart( self, node="onos1" ):
+        """
+            Restart Docker container
+        """
+        try:
+            main.log.info( self.name +
+                           ": Restarting Docker conatiner for node " + node )
+            reponse = self.dockerClient.restart( node )
+            if( reponse == 'None' ):
+                main.log.info( "Restarted container for node: " + node )
+                return main.TRUE
+            else:
+                main.log.info( "Noticed warnings during Restart" )
+                return main.FALSE
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def dockerStatus( self, node="onos1" ):
+        """
+            Check Docker conatiner status
+        """
+        try:
+            main.log.info( self.name +
+                           ": Checking Docker Status for node " + node )
+            reponse = self.dockerClient.inspect_container( node )
+            if( reponse == 'True' ):
+                main.log.info( "Container " + node + " is running" )
+                return main.TRUE
+            else:
+                main.log.info( "Container " + node + " is not running" )
+                return main.FALSE
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def dockerRemove( self, node="onos1" ):
+        """
+            Remove Docker conatiner
+        """
+        try:
+            main.log.info( self.name +
+                           ": Removing Docker container for node " + node )
+            reponse = self.dockerClient.remove_container( node )
+            if( reponse == 'None' ):
+                main.log.info( "Removed container for node: " + node )
+                return main.TRUE
+            else:
+                main.log.info( "Noticed warnings during Remove " + node )
+                return main.FALSE
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def dockerImageRemove( self, image="onosproject/onos" ):
+        """
+            Remove Docker image
+        """
+        try:
+            main.log.info( self.name +
+                           ": Removing Docker container for node " + node )
+            reponse = self.dockerClient.remove_image( image )
+            if( reponse == 'None' ):
+                main.log.info( "Removed Docker image: " + image )
+                return main.TRUE
+            else:
+                main.log.info( "Noticed warnings during Remove " + image )
+                return main.FALSE
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def fetchLatestClusterFile( self, branch="master" ):
+        """
+            Fetch onos-form-cluster file from a particular branch
+        """
+        try:
+            command = "wget -N https://raw.githubusercontent.com/opennetworkinglab/\
+                    onos/" + branch + "/tools/package/bin/onos-form-cluster"
+            subprocess.call( command ) # output checks are missing for now
+            command = "chmod u+x " + "onos-form-cluster"
+            subprocess.call( command )
+            return main.TRUE
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def onosFormCluster( self, onosIPs, user="onos", passwd="rocks" ):
+        """
+            From ONOS cluster for IP addresses in onosIPs list
+        """
+        try:
+            onosIPs = " ".join(onosIPs)
+            command = "./onos-form-cluster -u " + user + " -p " + passwd + \
+                    " `" + onosIPs + "`"
+            subprocess.call( command ) # output checks are missing for now
+            return main.TRUE # FALSE condition will be verified from output
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def dockerIP( self, node='onos1' ):
+        """
+            Fetch IP address assigned to specified node/container
+        """
+        try:
+            output = self.dockerClient.inspect_container(node)
+            nodeIP = output['NetworkSettings']['IPAddress']
+            #main.log.info( " Docker IP " + str(nodeIP) )
+            return str(nodeIP)
+
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index d726f2e..e7718c0 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -405,7 +405,7 @@
         main.log.info( self.name + ": \n---\n" + response )
         return main.FALSE
 
-    def pingallHosts( self, hostList ):
+    def pingallHosts( self, hostList, wait=1 ):
         """
             Ping all specified IPv4 hosts
 
@@ -417,8 +417,8 @@
 
             Returns main.FALSE if one or more of hosts specified
             cannot reach each other"""
-
-        cmd = " ping -c 1 -i 1 -W 8 "
+        wait = int( wait )
+        cmd = " ping -c 1 -i 1 -W " + str( wait ) + " "
 
         try:
             main.log.info( "Testing reachability between specified hosts" )
@@ -438,7 +438,7 @@
                     # Current host pings all other hosts specified
                     pingCmd = str( host ) + cmd + str( temp )
                     self.handle.sendline( pingCmd )
-                    self.handle.expect( "mininet>" )
+                    self.handle.expect( "mininet>", timeout=wait + 1 )
                     response = self.handle.before
                     if re.search( ',\s0\%\spacket\sloss', response ):
                         pingResponse += str(" h" + str( temp[1:] ))
@@ -463,19 +463,20 @@
             main.cleanup()
             main.exit()
 
-    def pingIpv6Hosts(self, hostList, prefix='1000::'):
+    def pingIpv6Hosts( self, hostList, prefix='1000::', wait=1 ):
         """
-           IPv6 ping all hosts in hostList. If no prefix passed this will use
-           default prefix of 1000::
+        IPv6 ping all hosts in hostList. If no prefix passed this will use
+        default prefix of 1000::
 
-           Returns main.TRUE if all hosts specified can reach each other
+        Returns main.TRUE if all hosts specified can reach each other
 
-           Returns main.FALSE if one or more of hosts specified cannot reach each other
+        Returns main.FALSE if one or more of hosts specified cannot reach each other
         """
         try:
             main.log.info( "Testing reachability between specified IPv6 hosts" )
             isReachable = main.TRUE
-            cmd = " ping6 -c 1 -i 1 -W 8 "
+            wait = int( wait )
+            cmd = " ping6 -c 1 -i 1 -W " + str( wait ) + " "
             pingResponse = "IPv6 Pingall output:\n"
             failedPings = 0
             for host in hostList:
@@ -490,7 +491,7 @@
                     # Current host pings all other hosts specified
                     pingCmd = str( host ) + cmd + prefix + str( temp[1:] )
                     self.handle.sendline( pingCmd )
-                    self.handle.expect( "mininet>" )
+                    self.handle.expect( "mininet>", timeout=wait + 1 )
                     response = self.handle.before
                     if re.search( ',\s0\%\spacket\sloss', response ):
                         pingResponse += str(" h" + str( temp[1:] ))
@@ -518,15 +519,19 @@
 
     def pingHost( self, **pingParams ):
         """
-           Ping from one mininet host to another
-           Currently the only supported Params: SRC and TARGET"""
-        args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
+        Ping from one mininet host to another
+        Currently the only supported Params: SRC, TARGET, and WAIT
+        """
+        args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
+        wait = args['WAIT']
+        wait = int( wait if wait else 1 )
         command = args[ "SRC" ] + " ping " + \
-            args[ "TARGET" ] + " -c 1 -i 1 -W 8"
+            args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
         try:
             main.log.info( "Sending: " + command )
             self.handle.sendline( command )
-            i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
+            i = self.handle.expect( [ command, pexpect.TIMEOUT ],
+                                    timeout=wait + 1 )
             if i == 1:
                 main.log.error(
                     self.name +
@@ -561,17 +566,20 @@
     def ping6pair( self, **pingParams ):
         """
            IPv6 Ping between a pair of mininet hosts
-           Currently the only supported Params are: SRC , TARGET
+           Currently the only supported Params are: SRC, TARGET, and WAIT
            FLOWLABEL and -I (src interface) will be added later after running some tests.
            Example: main.Mininet1.ping6pair( src="h1", target="1000::2" )
         """
-        args = utilities.parse_args( [ "SRC", "TARGET" ], **pingParams )
-        command = args[ "SRC" ] + " ping6 " + \
-            args[ "TARGET" ] + " -c 1 -i 1 -W 8"
+        args = utilities.parse_args( [ "SRC", "TARGET", 'WAIT' ], **pingParams )
+        wait = args['WAIT']
+        wait = int( wait if wait else 1 )
+        command = args[ "SRC" ] + " ping " + \
+            args[ "TARGET" ] + " -c 1 -i 1 -W " + str( wait ) + " "
         try:
             main.log.info( "Sending: " + command )
             self.handle.sendline( command )
-            i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
+            i = self.handle.expect( [ command, pexpect.TIMEOUT ],
+                                    timeout=wait + 1 )
             if i == 1:
                 main.log.error(
                     self.name +
@@ -1039,7 +1047,7 @@
         main.log.info( self.name + ": List network links" )
         try:
             response = self.execute( cmd='links', prompt='mininet>',
-                                     timeout=10 )
+                                     timeout=20 )
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":     " + self.handle.before )
@@ -1104,12 +1112,15 @@
             else:
                 main.log.error( self.name + ": iperf test failed" )
                 return main.FALSE
-
         except pexpect.TIMEOUT:
-            main.log.error( self.name + ": TIMEOUT exception found")
-            main.log.error( self.name + ": Exception: Cannot connect to iperf on port 5001" )
+            main.log.error( self.name + ": TIMEOUT exception found" )
+            main.log.error( self.name + " response: " +
+                            repr ( self.handle.before ) )
+            # NOTE: Send ctrl-c to make sure iperf is done
+            self.handle.sendline( "\x03" )
+            self.handle.expect( "Interrupt" )
+            self.handle.expect( "mininet>" )
             return main.FALSE
-
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":     " + self.handle.before )
diff --git a/TestON/drivers/common/cli/onosdriver.py b/TestON/drivers/common/cli/onosdriver.py
index c261872..2fae817 100644
--- a/TestON/drivers/common/cli/onosdriver.py
+++ b/TestON/drivers/common/cli/onosdriver.py
@@ -192,6 +192,7 @@
             self.handle.sendline( "onos-package" )
             self.handle.expect( "onos-package" )
             self.handle.expect( "tar.gz", opTimeout )
+            self.handle.expect( "\$" )
             handle = str( self.handle.before )
             main.log.info( "onos-package command returned: " +
                            handle )
@@ -221,6 +222,7 @@
                 "BUILD FAILED" ],
                 timeout=120 )
             handle = str( self.handle.before )
+            self.handle.expect( "\$" )
 
             main.log.info( "onos-build command returned: " +
                            handle )
@@ -752,12 +754,11 @@
                 # Expect the cellname in the ONOSCELL variable.
                 # Note that this variable name is subject to change
                 #   and that this driver will have to change accordingly
-                self.handle.expect(str(cellname))
+                self.handle.expect( str( cellname ) )
                 handleBefore = self.handle.before
                 handleAfter = self.handle.after
                 # Get the rest of the handle
-                self.handle.sendline("")
-                self.handle.expect("\$")
+                self.handle.expect( "\$" )
                 handleMore = self.handle.before
 
                 cell_result = handleBefore + handleAfter + handleMore
@@ -768,7 +769,6 @@
                     main.cleanup()
                     main.exit()
                 return main.TRUE
-
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
@@ -793,19 +793,11 @@
             self.handle.expect( "\$" )
             handleBefore = self.handle.before
             handleAfter = self.handle.after
-            # Get the rest of the handle
-            self.handle.sendline( "" )
-            self.handle.expect( "\$" )
-            handleMore = self.handle.before
-
             main.log.info( "Verify cell returned: " + handleBefore +
-                           handleAfter + handleMore )
-
+                           handleAfter )
             return main.TRUE
         except pexpect.ExceptionPexpect as e:
-            main.log.error( self.name + ": Pexpect exception found of type " +
-                            str( type( e ) ) )
-            main.log.error ( e.get_trace() )
+            main.log.exception( self.name + ": Pexpect exception found: " )
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
@@ -851,9 +843,7 @@
                     return main.TRUE
 
             except pexpect.ExceptionPexpect as e:
-                main.log.error( self.name + ": Pexpect exception found of type " +
-                                str( type( e ) ) )
-                main.log.error ( e.get_trace() )
+                main.log.exception( self.name + ": Pexpect exception found: " )
                 main.log.error( self.name + ":    " + self.handle.before )
                 main.cleanup()
                 main.exit()
@@ -904,23 +894,12 @@
             self.handle.expect( "\$" )
 
             handleBefore = self.handle.before
-            print "handle_before = ", self.handle.before
-            # handleAfter = str( self.handle.after )
-
-            # self.handle.sendline( "" )
-            # self.handle.expect( "\$" )
-            # handleMore = str( self.handle.before )
-
             main.log.info( "Command sent successfully" )
-
             # Obtain return handle that consists of result from
             # the onos command. The string may need to be
             # configured further.
-            # returnString = handleBefore + handleAfter
             returnString = handleBefore
-            print "return_string = ", returnString
             return returnString
-
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
@@ -954,26 +933,28 @@
                                       "onos\sstart/running,\sprocess",
                                       "ONOS\sis\salready\sinstalled",
                                       pexpect.TIMEOUT ], timeout=60 )
-
             if i == 0:
                 main.log.warn( "Network is unreachable" )
+                self.handle.expect( "\$" )
                 return main.FALSE
             elif i == 1:
                 main.log.info(
                     "ONOS was installed on " +
                     node +
                     " and started" )
+                self.handle.expect( "\$" )
                 return main.TRUE
             elif i == 2:
                 main.log.info( "ONOS is already installed on " + node )
+                self.handle.expect( "\$" )
                 return main.TRUE
             elif i == 3:
                 main.log.info(
                     "Installation of ONOS on " +
                     node +
                     " timed out" )
+                self.handle.expect( "\$" )
                 return main.FALSE
-
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
@@ -999,7 +980,7 @@
                 "start/running",
                 "Unknown\sinstance",
                 pexpect.TIMEOUT ], timeout=120 )
-
+            self.handle.expect( "\$" )
             if i == 0:
                 main.log.info( "Service is already running" )
                 return main.TRUE
@@ -1035,7 +1016,7 @@
                 "Could not resolve hostname",
                 "Unknown\sinstance",
                 pexpect.TIMEOUT ], timeout=60 )
-
+            self.handle.expect( "\$" )
             if i == 0:
                 main.log.info( "ONOS service stopped" )
                 return main.TRUE
@@ -1049,7 +1030,6 @@
             else:
                 main.log.error( "ONOS service failed to stop" )
                 return main.FALSE
-
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
@@ -1070,13 +1050,10 @@
             self.handle.sendline( "" )
             self.handle.expect( "\$", timeout=60 )
             self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
-            self.handle.expect( "\$" )
-
+            self.handle.expect( "\$", timeout=60 )
             main.log.info( "ONOS " + nodeIp + " was uninstalled" )
-
             # onos-uninstall command does not return any text
             return main.TRUE
-
         except pexpect.TIMEOUT:
             main.log.exception( self.name + ": Timeout in onosUninstall" )
             return main.FALSE
@@ -1186,10 +1163,7 @@
                                         timeout=120 )
                 if i == 1:
                     return main.FALSE
-            #self.handle.sendline( "" )
-            #self.handle.expect( "\$" )
             return main.TRUE
-
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
@@ -1237,7 +1211,7 @@
             main.cleanup()
             main.exit()
 
-    def isup(self, node = "", timeout = 120):
+    def isup( self, node="", timeout=120 ):
         """
         Run's onos-wait-for-start which only returns once ONOS is at run
         level 100(ready for use)
@@ -1245,8 +1219,8 @@
         Returns: main.TRUE if ONOS is running and main.FALSE on timeout
         """
         try:
-            self.handle.sendline("onos-wait-for-start " + node )
-            self.handle.expect("onos-wait-for-start")
+            self.handle.sendline( "onos-wait-for-start " + node )
+            self.handle.expect( "onos-wait-for-start" )
             # NOTE: this timeout is arbitrary"
             i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
             if i == 0:
diff --git a/TestON/drivers/common/clidriver.py b/TestON/drivers/common/clidriver.py
index 0202a15..7d6ef0b 100644
--- a/TestON/drivers/common/clidriver.py
+++ b/TestON/drivers/common/clidriver.py
@@ -145,12 +145,11 @@
         """
         result = super( CLI, self ).execute( self )
         defaultPrompt = '.*[$>\#]'
-        args = utilities.parse_args( [
-                     "CMD",
-                                     "TIMEOUT",
-                                     "PROMPT",
-                                     "MORE" ],
-                             **execparams )
+        args = utilities.parse_args( [ "CMD",
+                                       "TIMEOUT",
+                                       "PROMPT",
+                                       "MORE" ],
+                                     **execparams )
 
         expectPrompt = args[ "PROMPT" ] if args[ "PROMPT" ] else defaultPrompt
         self.LASTRSP = ""
@@ -164,20 +163,18 @@
             args[ "MORE" ] = " "
         self.handle.sendline( cmd )
         self.lastCommand = cmd
-        index = self.handle.expect( [
-                    expectPrompt,
-                                    "--More--",
-                                    'Command not found.',
-                                    pexpect.TIMEOUT,
-                                    "^:$" ],
-                            timeout=timeoutVar )
+        index = self.handle.expect( [ expectPrompt,
+                                      "--More--",
+                                      'Command not found.',
+                                      pexpect.TIMEOUT,
+                                      "^:$" ],
+                                    timeout=timeoutVar )
         if index == 0:
             self.LASTRSP = self.LASTRSP + \
                 self.handle.before + self.handle.after
-            main.log.info(
-                "Executed :" + str(
-                    cmd ) + " \t\t Expected Prompt '" + str(
-                        expectPrompt) + "' Found" )
+            main.log.info( "Executed :" + str(cmd ) +
+                           " \t\t Expected Prompt '" + str( expectPrompt) +
+                           "' Found" )
         elif index == 1:
             self.LASTRSP = self.LASTRSP + self.handle.before
             self.handle.send( args[ "MORE" ] )
@@ -196,26 +193,25 @@
             main.log.error( "Command not found" )
             self.LASTRSP = self.LASTRSP + self.handle.before
         elif index == 3:
-            main.log.error( "Expected Prompt not found , Time Out!!" )
+            main.log.error( "Expected Prompt not found, Time Out!!" )
             main.log.error( expectPrompt )
-            return "Expected Prompt not found , Time Out!!"
-
+            self.LASTRSP = self.LASTRSP + self.handle.before
+            return self.LASTRSP
         elif index == 4:
             self.LASTRSP = self.LASTRSP + self.handle.before
             # self.handle.send( args[ "MORE" ] )
             self.handle.sendcontrol( "D" )
             main.log.info(
-                "Found More screen to go , Sending a key to proceed" )
+                "Found More screen to go, Sending a key to proceed" )
             indexMore = self.handle.expect(
                 [ "^:$", expectPrompt ], timeout=timeoutVar )
             while indexMore == 0:
                 main.log.info(
-                    "Found another More screen to go , Sending a key to proceed" )
+                    "Found another More screen to go, Sending a key to proceed" )
                 self.handle.sendcontrol( "D" )
                 indexMore = self.handle.expect(
                     [ "^:$", expectPrompt ], timeout=timeoutVar )
                 self.LASTRSP = self.LASTRSP + self.handle.before
-
         main.last_response = self.remove_contol_chars( self.LASTRSP )
         return self.LASTRSP
 
@@ -297,7 +293,6 @@
                                 pexpect.EOF,
                                 pexpect.TIMEOUT ],
                                 120 )
-
             if i == 0:  # ask for ssh key confirmation
                 main.log.info( "ssh key confirmation received, sending yes" )
                 self.handle.sendline( 'yes' )
@@ -327,10 +322,7 @@
                     "@" +
                     ipAddress )
                 returnVal = main.FALSE
-
-        self.handle.sendline( "" )
-        self.handle.expect( "$" )
-
+        self.handle.expect( "\$" )
         return returnVal
 
     def scp( self, remoteHost, filePath, dstPath, direction="from" ):
diff --git a/TestON/tests/CHOtest/CHOtest.params b/TestON/tests/CHOtest/CHOtest.params
index d4199ad..5f8c205 100644
--- a/TestON/tests/CHOtest/CHOtest.params
+++ b/TestON/tests/CHOtest/CHOtest.params
@@ -90,7 +90,15 @@
         <LinkDiscovery>15</LinkDiscovery>
         <SwitchDiscovery>10</SwitchDiscovery>
         <IntentPurgeDelay>15</IntentPurgeDelay>
-        <CheckIntentDelay>40</CheckIntentDelay>
+        <CheckIntentDelay>8</CheckIntentDelay>
+        <pingSleep>3</pingSleep>
     </timers>
 
+    <TEST>
+        <pauseTest>off</pauseTest>
+        <email>off</email>
+        <intentChecks>8</intentChecks>
+        <numPings>5</numPings>
+    </TEST>
+
 </PARAMS>
diff --git a/TestON/tests/CHOtest/CHOtest.py b/TestON/tests/CHOtest/CHOtest.py
index fbe51cd..a1a1610 100644
--- a/TestON/tests/CHOtest/CHOtest.py
+++ b/TestON/tests/CHOtest/CHOtest.py
@@ -33,9 +33,17 @@
         git_branch = main.params[ 'GIT' ][ 'branch' ]
         karafTimeout = main.params['CTRL']['karafCliTimeout']
         main.checkIntentsDelay = int( main.params['timers']['CheckIntentDelay'] )
+        main.failSwitch = main.params['TEST']['pauseTest']
+        main.emailOnStop = main.params['TEST']['email']
+        main.intentCheck = int( main.params['TEST']['intentChecks'] )
+        main.numPings = int( main.params['TEST']['numPings'] )
+        main.pingSleep = int( main.params['timers']['pingSleep'] )
         main.newTopo = ""
         main.CLIs = []
 
+        main.failSwitch = True if main.failSwitch == "on" else False
+        main.emailOnStop = True if main.emailOnStop == "on" else False
+
         for i in range( 1, int(main.numCtrls) + 1 ):
             main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
 
@@ -283,11 +291,11 @@
         # giving some breathing time for ONOS to complete re-balance
         time.sleep( 5 )
 
-        case21Result = switch_mastership
+        caseResult = switch_mastership
         time.sleep(30)
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case21Result,
+            actual=caseResult,
             onpass="Starting new Chordal topology test PASS",
             onfail="Starting new Chordal topology test FAIL" )
 
@@ -350,11 +358,11 @@
             # giving some breathing time for ONOS to complete re-balance
             time.sleep( 3 )
 
-        case22Result = switch_mastership
+        caseResult = switch_mastership
         time.sleep(60)
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case22Result,
+            actual=caseResult,
             onpass="Starting new Spine topology test PASS",
             onfail="Starting new Spine topology test FAIL" )
 
@@ -507,13 +515,15 @@
 
         time.sleep( 10 )
 
-        main.step( "Verify Pingall" )
-        pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall( timeout=main.pingTimeout )
-        if not pingResult:
-            main.log.warn("First pingall failed. Trying again...")
-            pingResult = main.Mininet1.pingall( timeout=main.pingTimeout)
+        main.step( "Verify Ping across all hosts" )
+        for i in range(main.numPings):
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
+
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -526,8 +536,8 @@
         else:
             main.log.report( "IPv4 Pingall Test in Reactive mode failed" )
 
-        case40Result =  appCheck and pingResult
-        utilities.assert_equals( expect=main.TRUE, actual=case40Result,
+        caseResult =  appCheck and pingResult
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Reactive Mode IPv4 Pingall test PASS",
                                  onfail="Reactive Mode IPv4 Pingall test FAIL" )
 
@@ -566,13 +576,15 @@
 
         time.sleep( 10 )
 
-        main.step( "Verify Pingall" )
-        pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall( timeout=main.pingTimeout )
-        if not pingResult:
-            main.log.warn("First pingall failed. Trying again...")
-            pingResult = main.Mininet1.pingall( timeout=main.pingTimeout )
+        main.step( "Verify Ping across all hosts" )
+        for i in range(main.numPings):
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
+
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -585,8 +597,8 @@
         else:
             main.log.report( "IPv4 Pingall Test in Reactive mode failed" )
 
-        case41Result =  appCheck and pingResult
-        utilities.assert_equals( expect=main.TRUE, actual=case41Result,
+        caseResult =  appCheck and pingResult
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Reactive Mode IPv4 Pingall test PASS",
                                  onfail="Reactive Mode IPv4 Pingall test FAIL" )
 
@@ -625,13 +637,15 @@
 
         time.sleep( 10 )
 
-        main.step( "Verify Pingall" )
-        pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall( timeout=main.pingTimeout )
-        if not pingResult:
-            main.log.warn("First pingall failed. Trying again...")
-            pingResult = main.Mininet1.pingall( timeout=main.pingTimeout )
+        main.step( "Verify Ping across all hosts" )
+        for i in range(main.numPings):
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
+
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -644,8 +658,8 @@
         else:
             main.log.report( "IPv4 Pingall Test in Reactive mode failed" )
 
-        case42Result =  appCheck and pingResult
-        utilities.assert_equals( expect=main.TRUE, actual=case42Result,
+        caseResult =  appCheck and pingResult
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Reactive Mode IPv4 Pingall test PASS",
                                  onfail="Reactive Mode IPv4 Pingall test FAIL" )
 
@@ -713,8 +727,8 @@
 
         # Waiting for reative flows to be cleared.
         time.sleep( 30 )
-        case140Result =  appCheck and cfgResult and pingResult
-        utilities.assert_equals( expect=main.TRUE, actual=case140Result,
+        caseResult =  appCheck and cfgResult and pingResult
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Reactive Mode IPv6 Pingall test PASS",
                                  onfail="Reactive Mode IPv6 Pingall test FAIL" )
 
@@ -782,8 +796,8 @@
 
         # Waiting for reative flows to be cleared.
         time.sleep( 30 )
-        case140Result =  appCheck and cfgResult and pingResult
-        utilities.assert_equals( expect=main.TRUE, actual=case140Result,
+        caseResult =  appCheck and cfgResult and pingResult
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Reactive Mode IPv6 Pingall test PASS",
                                  onfail="Reactive Mode IPv6 Pingall test FAIL" )
 
@@ -810,10 +824,10 @@
         main.step( "Verify IPv6 Pingall" )
         pingResult = main.FALSE
         time1 = time.time()
-        ping_result = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout)
-        if not ping_result:
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout)
+        if not pingResult:
             main.log.warn("First pingall failed. Trying again...")
-            ping_result = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -851,8 +865,8 @@
 
         # Waiting for reative flows to be cleared.
         time.sleep( 30 )
-        case142Result =  appCheck and cfgResult and pingResult
-        utilities.assert_equals( expect=main.TRUE, actual=case142Result,
+        caseResult =  appCheck and cfgResult and pingResult
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Reactive Mode IPv6 Pingall test PASS",
                                  onfail="Reactive Mode IPv6 Pingall test FAIL" )
 
@@ -989,40 +1003,45 @@
         time2 = time.time()
         main.log.info("Time for adding host intents: %2f seconds" %(time2-time1))
 
+        # Saving intent ids to check intents in later cases
+        main.intentIds = list(intentIdList)
+
         main.step("Verify intents are installed")
 
-        # Giving onos 3 chances to install intents
-        for i in range(3):
-            intentsJson = main.ONOScli1.intents()
-            getIntentStateResult = main.ONOScli1.getIntentState(intentsId = intentIdList,
-                                                                intentsJson = intentsJson)
-            main.log.info("Waiting for onos to get intents...")
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Waiting for onos to install intents...")
             time.sleep( main.checkIntentsDelay )
 
             intentState = main.TRUE
-            failedIntents = 0
-            for intent in getIntentStateResult:
-                state = intent.items()[0][1]
-                if state != 'INSTALLED':
-                    main.log.info("Intent State: " + state)
-                    failedIntents += 1
-                    intentState = main.FALSE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = intentIdList ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
             if intentState:
                 break
-            main.log.error("Total # of intents not in an INSTALLED state: " + str(failedIntents))
+        else:
+            #Dumping intent summary
+            main.log.info( "**** Intent Summary ****\n" + str(main.ONOScli1.intents( jsonFormat=False, summary=True)) )
+
 
         utilities.assert_equals( expect=main.TRUE, actual=intentState,
                                  onpass="INTENTS INSTALLED",
                                  onfail="SOME INTENTS NOT INSTALLED" )
 
         main.step( "Verify Ping across all hosts" )
-        pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
-        if not pingResult:
-            main.log.warn("First pingall failed. Retrying...")
+        for i in range(main.numPings):
             time1 = time.time()
             pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(3)
+            else: break
+
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1033,13 +1052,22 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case60Result = ( intentState and pingResult )
+        caseResult = ( intentState and pingResult )
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case60Result,
+            actual=caseResult,
             onpass="Install 300 Host Intents and Ping All test PASS",
             onfail="Install 300 Host Intents and Ping All test FAIL" )
 
+        if not intentState:
+            main.log.debug( "Intents failed to install completely" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
+
     def CASE61( self ):
         """
         Install 600 host intents and verify ping all for Chordal Topology
@@ -1075,41 +1103,44 @@
         time2 = time.time()
         main.log.info("Time for adding host intents: %2f seconds" %(time2-time1))
 
+        # Saving intent ids to check intents in later cases
+        main.intentIds = list(intentIdList)
+
         main.step("Verify intents are installed")
 
-        # Giving onos 3 chances to install intents
-        for i in range(3):
-            intentsJson = main.ONOScli1.intents()
-            getIntentStateResult = main.ONOScli1.getIntentState(intentsId = intentIdList,
-                                                                intentsJson = intentsJson)
-            main.log.info("Waiting for onos to get intents...")
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Waiting for onos to install intents...")
             time.sleep( main.checkIntentsDelay )
 
             intentState = main.TRUE
-            failedIntents = 0
-            for intent in getIntentStateResult:
-                state = intent.items()[0][1]
-                if state != 'INSTALLED':
-                    main.log.info("Intent State: " + state)
-                    failedIntents += 1
-                    intentState = main.FALSE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = intentIdList ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
             if intentState:
                 break
-            main.log.error("Total # of intents not in an INSTALLED state: " + str(failedIntents))
-
+        else:
+            #Dumping intent summary
+            main.log.info( "**** Intents Summary ****\n" + str(main.ONOScli1.intents(jsonFormat=False, summary=True)) )
 
         utilities.assert_equals( expect=main.TRUE, actual=intentState,
                                  onpass="INTENTS INSTALLED",
                                  onfail="SOME INTENTS NOT INSTALLED" )
 
         main.step( "Verify Ping across all hosts" )
-        pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
-        if not pingResult:
-            main.log.warn("First pingall failed. Retrying...")
+        for i in range(main.numPings):
             time1 = time.time()
             pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
+
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1120,14 +1151,23 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case14Result = ( intentState and pingResult )
+        caseResult = ( intentState and pingResult )
 
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case14Result,
+            actual=caseResult,
             onpass="Install 300 Host Intents and Ping All test PASS",
             onfail="Install 300 Host Intents and Ping All test FAIL" )
 
+        if not intentState:
+            main.log.debug( "Intents failed to install completely" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
+
     def CASE62( self ):
         """
         Install 2278 host intents and verify ping all for Spine Topology
@@ -1162,40 +1202,44 @@
         time2 = time.time()
         main.log.info("Time for adding host intents: %2f seconds" %(time2-time1))
 
+        # Saving intent ids to check intents in later cases
+        main.intentIds = list(intentIdList)
+
         main.step("Verify intents are installed")
 
-        # Giving onos 5 chances to install intents
-        for i in range(5):
-            intentsJson = main.ONOScli1.intents()
-            getIntentStateResult = main.ONOScli1.getIntentState(intentsId = intentIdList,
-                                                                intentsJson = intentsJson)
-            main.log.info("Waiting for onos to get intents...")
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Waiting for onos to install intents...")
             time.sleep( main.checkIntentsDelay )
 
             intentState = main.TRUE
-            failedIntents = 0
-            for intent in getIntentStateResult:
-                state = intent.items()[0][1]
-                if state != 'INSTALLED':
-                    main.log.info("Intent State: " + state)
-                    failedIntents += 1
-                    intentState = main.FALSE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = intentIdList ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
             if intentState:
                 break
-            main.log.error("Total # of intents not in an INSTALLED state: " + str(failedIntents))
+        else:
+            #Dumping intent summary
+            main.log.info( "**** Intents Summary ****\n" + str(main.ONOScli1.intents(jsonFormat=False, summary=True)) )
 
         utilities.assert_equals( expect=main.TRUE, actual=intentState,
                                  onpass="INTENTS INSTALLED",
                                  onfail="SOME INTENTS NOT INSTALLED" )
 
         main.step( "Verify Ping across all hosts" )
-        pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
-        if not pingResult:
-            main.log.warn("First pingall failed. Retrying...")
+        for i in range(main.numPings):
             time1 = time.time()
             pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
+
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1206,14 +1250,23 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case15Result = ( intentState and pingResult )
+        caseResult = ( intentState and pingResult )
 
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case15Result,
+            actual=caseResult,
             onpass="Install 2278 Host Intents and Ping All test PASS",
             onfail="Install 2278 Host Intents and Ping All test FAIL" )
 
+        if not intentState:
+            main.log.debug( "Intents failed to install completely" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
+
     def CASE160( self ):
         """
         Verify IPv6 ping across 300 host intents (Att Topology)
@@ -1224,14 +1277,13 @@
         import time
         main.case( "IPv6 ping all 300 host intents" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 1)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("First pingall failed. Retrying...")
             time1 = time.time()
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1242,10 +1294,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case160Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case160Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 300 host intents test PASS",
             onfail="IPv6 Ping across 300 host intents test FAIL" )
 
@@ -1259,15 +1311,13 @@
         import time
         main.case( "IPv6 ping all 600 host intents" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 1)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("First pingall failed. Retrying...")
             time1 = time.time()
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
-
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1278,10 +1328,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case161Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case161Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 600 host intents test PASS",
             onfail="IPv6 Ping across 600 host intents test FAIL" )
 
@@ -1295,15 +1345,13 @@
         import time
         main.case( "IPv6 ping all 600 host intents" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 11)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("First pingall failed. Retrying...")
             time1 = time.time()
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
-
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -1314,10 +1362,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case162Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case162Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 600 host intents test PASS",
             onfail="IPv6 Ping across 600 host intents test FAIL" )
 
@@ -1383,14 +1431,40 @@
             str( link_sleep ) +
             " seconds" )
 
+        main.step("Verify intents are installed")
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Giving onos some time...")
+            time.sleep( main.checkIntentsDelay )
+
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = main.intentIds ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "**** Intent Summary ****\n" + str(main.ONOScli1.intents( jsonFormat=False, summary=True)) )
+
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
         main.step( "Verify Ping across all hosts" )
-        pingResultLinkDown = main.FALSE
-        time1 = time.time()
-        pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout )
-        if not pingResultLinkDown:
-            main.log.warn("First pingall failed. Retrying...")
+        for i in range(main.numPings):
             time1 = time.time()
-            pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout )
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
 
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
@@ -1398,15 +1472,27 @@
             "Time taken for Ping All: " +
             str( timeDiff ) +
             " seconds" )
-        utilities.assert_equals( expect=main.TRUE, actual=pingResultLinkDown,
+        utilities.assert_equals( expect=main.TRUE, actual=pingResult,
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        caseResult70 = linkDown and pingResultLinkDown
-        utilities.assert_equals( expect=main.TRUE, actual=caseResult70,
+        caseResult = linkDown and pingResult and intentState
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Random Link cut Test PASS",
                                  onfail="Random Link cut Test FAIL" )
 
+        # Printing what exactly failed
+        if not linkDown:
+            main.log.debug( "Link down was not discovered correctly" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not intentState:
+            main.log.debug( "Intents are not all installed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
+
     def CASE80( self, main ):
         """
         Bring the core links up that are down and verify ping all ( Host Intents-Att Topo )
@@ -1455,14 +1541,40 @@
             str( link_sleep ) +
             " seconds" )
 
+        main.step("Verify intents are installed")
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Giving onos some time...")
+            time.sleep( main.checkIntentsDelay )
+
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = main.intentIds ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "**** Intent Summary ****\n" + str(main.ONOScli1.intents( jsonFormat=False, summary=True)) )
+
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
         main.step( "Verify Ping across all hosts" )
-        pingResultLinkUp = main.FALSE
-        time1 = time.time()
-        pingResultLinkUp = main.Mininet1.pingall( timeout=main.pingTimeout )
-        if not pingResultLinkUp:
-            main.log.warn("First pingall failed. Retrying...")
+        for i in range(main.numPings):
             time1 = time.time()
-            pingResultLinkUp = main.Mininet1.pingall(timeout=main.pingTimeout )
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
 
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
@@ -1470,14 +1582,25 @@
             "Time taken for Ping All: " +
             str( timeDiff ) +
             " seconds" )
-        utilities.assert_equals( expect=main.TRUE, actual=pingResultLinkUp,
+        utilities.assert_equals( expect=main.TRUE, actual=pingResult,
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        caseResult80 = linkUp and pingResultLinkUp
-        utilities.assert_equals( expect=main.TRUE, actual=caseResult80,
+        caseResult = linkUp and pingResult
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Link Up Test PASS",
                                  onfail="Link Up Test FAIL" )
+        # Printing what exactly failed
+        if not linkUp:
+            main.log.debug( "Link down was not discovered correctly" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not intentState:
+            main.log.debug( "Intents are not all installed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
 
     def CASE71( self, main ):
         """
@@ -1541,14 +1664,40 @@
             str( link_sleep ) +
             " seconds" )
 
+        main.step("Verify intents are installed")
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Giving onos some time...")
+            time.sleep( main.checkIntentsDelay )
+
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = main.intentIds ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "**** Intent Summary ****\n" + str(main.ONOScli1.intents( jsonFormat=False, summary=True)) )
+
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
         main.step( "Verify Ping across all hosts" )
-        pingResultLinkDown = main.FALSE
-        time1 = time.time()
-        pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout)
-        if not pingResultLinkDown:
-            main.log.warn("First pingall failed. Retrying...")
+        for i in range(main.numPings):
             time1 = time.time()
-            pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout )
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
 
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
@@ -1556,15 +1705,27 @@
             "Time taken for Ping All: " +
             str( timeDiff ) +
             " seconds" )
-        utilities.assert_equals( expect=main.TRUE, actual=pingResultLinkDown,
+        utilities.assert_equals( expect=main.TRUE, actual=pingResult,
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        caseResult71 = linkDown and pingResultLinkDown
-        utilities.assert_equals( expect=main.TRUE, actual=caseResult71,
+        caseResult = linkDown and pingResult and intentState
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Random Link cut Test PASS",
                                  onfail="Random Link cut Test FAIL" )
 
+        # Printing what exactly failed
+        if not linkDown:
+            main.log.debug( "Link down was not discovered correctly" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not intentState:
+            main.log.debug( "Intents are not all installed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
+
     def CASE81( self, main ):
         """
         Bring the core links up that are down and verify ping all ( Point Intents-Att Topo )
@@ -1613,14 +1774,40 @@
             str( link_sleep ) +
             " seconds" )
 
+        main.step("Verify intents are installed")
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Giving onos some time...")
+            time.sleep( main.checkIntentsDelay )
+
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = main.intentIds ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "**** Intent Summary ****\n" + str(main.ONOScli1.intents( jsonFormat=False, summary=True)) )
+
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
         main.step( "Verify Ping across all hosts" )
-        pingResultLinkUp = main.FALSE
-        time1 = time.time()
-        pingResultLinkUp = main.Mininet1.pingall(timeout = main.pingTimeout )
-        if not pingResultLinkUp:
-            main.log.warn("First pingall failed. Retrying...")
+        for i in range(main.numPings):
             time1 = time.time()
-            pingResultLinkUp = main.Mininet1.pingall(timeout=main.pingTimeout )
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
 
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
@@ -1628,14 +1815,25 @@
             "Time taken for Ping All: " +
             str( timeDiff ) +
             " seconds" )
-        utilities.assert_equals( expect=main.TRUE, actual=pingResultLinkUp,
+        utilities.assert_equals( expect=main.TRUE, actual=pingResult,
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        caseResult81 = linkUp and pingResultLinkUp
-        utilities.assert_equals( expect=main.TRUE, actual=caseResult81,
+        caseResult = linkUp and pingResult
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Link Up Test PASS",
                                  onfail="Link Up Test FAIL" )
+        # Printing what exactly failed
+        if not linkUp:
+            main.log.debug( "Link down was not discovered correctly" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not intentState:
+            main.log.debug( "Intents are not all installed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
 
     def CASE72( self, main ):
         """
@@ -1676,15 +1874,40 @@
             str( link_sleep ) +
             " seconds" )
 
-        main.step( "Verify Ping across all hosts" )
-        pingResultLinkDown = main.FALSE
-        time1 = time.time()
-        pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
-        if not pingResultLinkDown:
-            main.log.warn("First pingall failed. Retrying...")
-            time1 = time.time()
-            pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
+        main.step("Verify intents are installed")
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Giving onos some time...")
+            time.sleep( main.checkIntentsDelay )
 
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = main.intentIds ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "**** Intent Summary ****\n" + str(main.ONOScli1.intents( jsonFormat=False, summary=True)) )
+
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
+        main.step( "Verify Ping across all hosts" )
+        for i in range(main.numPings):
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
 
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
@@ -1692,15 +1915,27 @@
             "Time taken for Ping All: " +
             str( timeDiff ) +
             " seconds" )
-        utilities.assert_equals( expect=main.TRUE, actual=pingResultLinkDown,
+        utilities.assert_equals( expect=main.TRUE, actual=pingResult,
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        caseResult71 = pingResultLinkDown
-        utilities.assert_equals( expect=main.TRUE, actual=caseResult71,
+        caseResult = linkDown and pingResult and intentState
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Random Link cut Test PASS",
                                  onfail="Random Link cut Test FAIL" )
 
+        # Printing what exactly failed
+        if not linkDown:
+            main.log.debug( "Link down was not discovered correctly" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not intentState:
+            main.log.debug( "Intents are not all installed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
+
     def CASE82( self, main ):
         """
         Bring the core links up that are down and verify ping all ( Host Intents Chordal Topo )
@@ -1736,15 +1971,40 @@
             str( link_sleep ) +
             " seconds" )
 
-        main.step( "Verify Ping across all hosts" )
-        pingResultLinkUp = main.FALSE
-        time1 = time.time()
-        pingResultLinkUp = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
-        if not pingResultLinkUp:
-            main.log.warn("First pingall failed. Retrying...")
-            time1 = time.time()
-            pingResultLinkUp = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
+        main.step("Verify intents are installed")
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Giving onos some time...")
+            time.sleep( main.checkIntentsDelay )
 
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = main.intentIds ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "**** Intent Summary ****\n" + str(main.ONOScli1.intents( jsonFormat=False, summary=True)) )
+
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
+        main.step( "Verify Ping across all hosts" )
+        for i in range(main.numPings):
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
 
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
@@ -1752,14 +2012,25 @@
             "Time taken for Ping All: " +
             str( timeDiff ) +
             " seconds" )
-        utilities.assert_equals( expect=main.TRUE, actual=pingResultLinkUp,
+        utilities.assert_equals( expect=main.TRUE, actual=pingResult,
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        caseResult82 = linkUp and pingResultLinkUp
-        utilities.assert_equals( expect=main.TRUE, actual=caseResult82,
+        caseResult = linkUp and pingResult
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Link Up Test PASS",
                                  onfail="Link Up Test FAIL" )
+        # Printing what exactly failed
+        if not linkUp:
+            main.log.debug( "Link down was not discovered correctly" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not intentState:
+            main.log.debug( "Intents are not all installed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
 
     def CASE73( self, main ):
         """
@@ -1800,14 +2071,40 @@
             str( link_sleep ) +
             " seconds" )
 
+        main.step("Verify intents are installed")
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Giving onos some time...")
+            time.sleep( main.checkIntentsDelay )
+
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = main.intentIds ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "**** Intent Summary ****\n" + str(main.ONOScli1.intents( jsonFormat=False, summary=True)) )
+
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
         main.step( "Verify Ping across all hosts" )
-        pingResultLinkDown = main.FALSE
-        time1 = time.time()
-        pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
-        if not pingResultLinkDown:
-            main.log.warn("First pingall failed. Retrying...")
+        for i in range(main.numPings):
             time1 = time.time()
-            pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
 
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
@@ -1815,15 +2112,27 @@
             "Time taken for Ping All: " +
             str( timeDiff ) +
             " seconds" )
-        utilities.assert_equals( expect=main.TRUE, actual=pingResultLinkDown,
+        utilities.assert_equals( expect=main.TRUE, actual=pingResult,
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        caseResult73 = pingResultLinkDown
-        utilities.assert_equals( expect=main.TRUE, actual=caseResult73,
+        caseResult = linkDown and pingResult and intentState
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Random Link cut Test PASS",
                                  onfail="Random Link cut Test FAIL" )
 
+        # Printing what exactly failed
+        if not linkDown:
+            main.log.debug( "Link down was not discovered correctly" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not intentState:
+            main.log.debug( "Intents are not all installed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
+
     def CASE83( self, main ):
         """
         Bring the core links up that are down and verify ping all ( Point Intents Chordal Topo )
@@ -1859,14 +2168,40 @@
             str( link_sleep ) +
             " seconds" )
 
+        main.step("Verify intents are installed")
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Giving onos some time...")
+            time.sleep( main.checkIntentsDelay )
+
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = main.intentIds ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "**** Intent Summary ****\n" + str(main.ONOScli1.intents( jsonFormat=False, summary=True)) )
+
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
         main.step( "Verify Ping across all hosts" )
-        pingResultLinkUp = main.FALSE
-        time1 = time.time()
-        pingResultLinkUp = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
-        if not pingResultLinkUp:
-            main.log.warn("First pingall failed. Retrying...")
+        for i in range(main.numPings):
             time1 = time.time()
-            pingResultLinkUp = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
 
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
@@ -1874,14 +2209,25 @@
             "Time taken for Ping All: " +
             str( timeDiff ) +
             " seconds" )
-        utilities.assert_equals( expect=main.TRUE, actual=pingResultLinkUp,
+        utilities.assert_equals( expect=main.TRUE, actual=pingResult,
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        caseResult83 = linkUp and pingResultLinkUp
-        utilities.assert_equals( expect=main.TRUE, actual=caseResult83,
+        caseResult = linkUp and pingResult
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Link Up Test PASS",
                                  onfail="Link Up Test FAIL" )
+        # Printing what exactly failed
+        if not linkUp:
+            main.log.debug( "Link down was not discovered correctly" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not intentState:
+            main.log.debug( "Intents are not all installed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
 
     def CASE74( self, main ):
         """
@@ -1933,14 +2279,40 @@
             str( link_sleep ) +
             " seconds" )
 
+        main.step("Verify intents are installed")
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Giving onos some time...")
+            time.sleep( main.checkIntentsDelay )
+
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = main.intentIds ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "**** Intent Summary ****\n" + str(main.ONOScli1.intents( jsonFormat=False, summary=True)) )
+
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
         main.step( "Verify Ping across all hosts" )
-        pingResultLinkDown = main.FALSE
-        time1 = time.time()
-        pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
-        if not pingResultLinkDown:
-            main.log.warn("First pingall failed. Retrying...")
+        for i in range(main.numPings):
             time1 = time.time()
-            pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
 
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
@@ -1948,15 +2320,27 @@
             "Time taken for Ping All: " +
             str( timeDiff ) +
             " seconds" )
-        utilities.assert_equals( expect=main.TRUE, actual=pingResultLinkDown,
+        utilities.assert_equals( expect=main.TRUE, actual=pingResult,
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        caseResult74 = linkDown and pingResultLinkDown
-        utilities.assert_equals( expect=main.TRUE, actual=caseResult74,
+        caseResult = linkDown and pingResult and intentState
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Random Link cut Test PASS",
                                  onfail="Random Link cut Test FAIL" )
 
+        # Printing what exactly failed
+        if not linkDown:
+            main.log.debug( "Link down was not discovered correctly" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not intentState:
+            main.log.debug( "Intents are not all installed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
+
     def CASE84( self, main ):
         """
         Bring the core links up that are down and verify ping all ( Host Intents-Spine Topo )
@@ -1993,14 +2377,40 @@
             str( link_sleep ) +
             " seconds" )
 
+        main.step("Verify intents are installed")
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Giving onos some time...")
+            time.sleep( main.checkIntentsDelay )
+
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = main.intentIds ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "**** Intent Summary ****\n" + str(main.ONOScli1.intents( jsonFormat=False, summary=True)) )
+
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
         main.step( "Verify Ping across all hosts" )
-        pingResultLinkUp = main.FALSE
-        time1 = time.time()
-        pingResultLinkUp = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
-        if not pingResultLinkUp:
-            main.log.warn("First pingall failed. Retrying...")
+        for i in range(main.numPings):
             time1 = time.time()
-            pingResultLinkUp = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
 
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
@@ -2008,14 +2418,25 @@
             "Time taken for Ping All: " +
             str( timeDiff ) +
             " seconds" )
-        utilities.assert_equals( expect=main.TRUE, actual=pingResultLinkUp,
+        utilities.assert_equals( expect=main.TRUE, actual=pingResult,
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        caseResult84 = linkUp and pingResultLinkUp
-        utilities.assert_equals( expect=main.TRUE, actual=caseResult84,
+        caseResult = linkUp and pingResult
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Link Up Test PASS",
                                  onfail="Link Up Test FAIL" )
+        # Printing what exactly failed
+        if not linkUp:
+            main.log.debug( "Link down was not discovered correctly" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not intentState:
+            main.log.debug( "Intents are not all installed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
 
     def CASE75( self, main ):
         """
@@ -2067,14 +2488,40 @@
             str( link_sleep ) +
             " seconds" )
 
+        main.step("Verify intents are installed")
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Giving onos some time...")
+            time.sleep( main.checkIntentsDelay )
+
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = main.intentIds ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "**** Intent Summary ****\n" + str(main.ONOScli1.intents( jsonFormat=False, summary=True)) )
+
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
         main.step( "Verify Ping across all hosts" )
-        pingResultLinkDown = main.FALSE
-        time1 = time.time()
-        pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
-        if not pingResultLinkDown:
-            main.log.warn("First pingall failed. Retrying...")
+        for i in range(main.numPings):
             time1 = time.time()
-            pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
 
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
@@ -2082,15 +2529,27 @@
             "Time taken for Ping All: " +
             str( timeDiff ) +
             " seconds" )
-        utilities.assert_equals( expect=main.TRUE, actual=pingResultLinkDown,
+        utilities.assert_equals( expect=main.TRUE, actual=pingResult,
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        caseResult75 = linkDown and pingResultLinkDown
-        utilities.assert_equals( expect=main.TRUE, actual=caseResult75,
+        caseResult = linkDown and pingResult and intentState
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Random Link cut Test PASS",
                                  onfail="Random Link cut Test FAIL" )
 
+        # Printing what exactly failed
+        if not linkDown:
+            main.log.debug( "Link down was not discovered correctly" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not intentState:
+            main.log.debug( "Intents are not all installed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
+
     def CASE85( self, main ):
         """
         Bring the core links up that are down and verify ping all ( Point Intents-Spine Topo )
@@ -2127,14 +2586,40 @@
             str( link_sleep ) +
             " seconds" )
 
+        main.step("Verify intents are installed")
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Giving onos some time...")
+            time.sleep( main.checkIntentsDelay )
+
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = main.intentIds ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "**** Intent Summary ****\n" + str(main.ONOScli1.intents( jsonFormat=False, summary=True)) )
+
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
         main.step( "Verify Ping across all hosts" )
-        pingResultLinkUp = main.FALSE
-        time1 = time.time()
-        pingResultLinkUp = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
-        if not pingResultLinkUp:
-            main.log.warn("First pingall failed. Retrying...")
+        for i in range(main.numPings):
             time1 = time.time()
-            pingResultLinkUp = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
 
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
@@ -2142,14 +2627,25 @@
             "Time taken for Ping All: " +
             str( timeDiff ) +
             " seconds" )
-        utilities.assert_equals( expect=main.TRUE, actual=pingResultLinkUp,
+        utilities.assert_equals( expect=main.TRUE, actual=pingResult,
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        caseResult85 = linkUp and pingResultLinkUp
-        utilities.assert_equals( expect=main.TRUE, actual=caseResult85,
+        caseResult = linkUp and pingResult
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Link Up Test PASS",
                                  onfail="Link Up Test FAIL" )
+        # Printing what exactly failed
+        if not linkUp:
+            main.log.debug( "Link down was not discovered correctly" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not intentState:
+            main.log.debug( "Intents are not all installed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
 
     def CASE170( self ):
         """
@@ -2161,13 +2657,12 @@
         import time
         main.case( "IPv6 ping all with some core links down( Host Intents-Att Topo )" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 1)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("Failed to ping Ipv6 hosts. Retrying...")
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2178,10 +2673,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case170Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case170Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 300 host intents test PASS",
             onfail="IPv6 Ping across 300 host intents test FAIL" )
 
@@ -2195,15 +2690,13 @@
         import time
         main.case( "IPv6 ping all with after core links back up( Host Intents-Att Topo )" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 1)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("First ping failed. Retrying...")
             time1 = time.time()
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
-
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2214,10 +2707,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case180Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case180Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 300 host intents test PASS",
             onfail="IPv6 Ping across 300 host intents test FAIL" )
 
@@ -2231,15 +2724,13 @@
         import time
         main.case( "IPv6 ping all with some core links down( Point Intents-Att Topo )" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 1)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("First ping failed. Retrying...")
             time1 = time.time()
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
-
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2250,10 +2741,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case171Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case171Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 600 point intents test PASS",
             onfail="IPv6 Ping across 600 point intents test FAIL" )
 
@@ -2267,15 +2758,13 @@
         import time
         main.case( "IPv6 ping all with after core links back up( Point Intents-Att Topo )" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 1)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("First ping failed. Retrying...")
             time1 = time.time()
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
-
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2286,10 +2775,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case181Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case181Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 600 Point intents test PASS",
             onfail="IPv6 Ping across 600 Point intents test FAIL" )
 
@@ -2303,15 +2792,13 @@
         import time
         main.case( "IPv6 ping all with some core links down( Host Intents-Chordal Topo )" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 1)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("First ping failed. Retrying...")
             time1 = time.time()
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
-
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2322,10 +2809,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case172Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case172Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 300 host intents test PASS",
             onfail="IPv6 Ping across 300 host intents test FAIL" )
 
@@ -2339,15 +2826,13 @@
         import time
         main.case( "IPv6 ping all with after core links back up( Host Intents-Chordal Topo )" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 1)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("First ping failed. Retrying...")
             time1 = time.time()
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
-
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2358,10 +2843,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case182Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case182Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 300 host intents test PASS",
             onfail="IPv6 Ping across 300 host intents test FAIL" )
 
@@ -2375,15 +2860,13 @@
         import time
         main.case( "IPv6 ping all with some core links down( Point Intents-Chordal Topo )" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 1)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("First ping failed. Retrying...")
             time1 = time.time()
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
-
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2394,10 +2877,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case173Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case173Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 600 point intents test PASS",
             onfail="IPv6 Ping across 600 point intents test FAIL" )
 
@@ -2411,15 +2894,13 @@
         import time
         main.case( "IPv6 ping all with after core links back up( Point Intents-Chordal Topo )" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 1)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("First ping failed. Retrying...")
             time1 = time.time()
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
-
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2430,10 +2911,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case183Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case183Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 600 Point intents test PASS",
             onfail="IPv6 Ping across 600 Point intents test FAIL" )
 
@@ -2447,15 +2928,13 @@
         import time
         main.case( "IPv6 ping all with some core links down( Host Intents-Spine Topo )" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 11)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("First ping failed. Retrying...")
             time1 = time.time()
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
-
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2466,10 +2945,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case174Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case174Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 2278 host intents test PASS",
             onfail="IPv6 Ping across 2278 host intents test FAIL" )
 
@@ -2483,15 +2962,13 @@
         import time
         main.case( "IPv6 ping all with after core links back up( Host Intents-Spine Topo )" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 11)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("First ping failed. Retrying...")
             time1 = time.time()
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
-
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2502,10 +2979,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case184Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case184Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 2278 host intents test PASS",
             onfail="IPv6 Ping across 2278 host intents test FAIL" )
 
@@ -2519,15 +2996,13 @@
         import time
         main.case( "IPv6 ping all with some core links down( Point Intents-Spine Topo )" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 11)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("First ping failed. Retrying...")
             time1 = time.time()
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
-
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2538,10 +3013,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case175Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case175Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 4556 point intents test PASS",
             onfail="IPv6 Ping across 4556 point intents test FAIL" )
 
@@ -2555,15 +3030,13 @@
         import time
         main.case( "IPv6 ping all with after core links back up( Point Intents-Spine Topo )" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 11)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("First ping failed. Retrying...")
             time1 = time.time()
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
-
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2574,10 +3047,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case183Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case183Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 4556 Point intents test PASS",
             onfail="IPv6 Ping across 4556 Point intents test FAIL" )
 
@@ -2614,37 +3087,45 @@
                 intentIdList.append(thread.result)
         time2 = time.time()
         main.log.info("Time for adding point intents: %2f seconds" %(time2-time1))
-        intentResult = main.TRUE
-        intentsJson = main.ONOScli1.intents()
-        getIntentStateResult = main.ONOScli1.getIntentState(intentsId = intentIdList,
-                intentsJson = intentsJson)
-        # Takes awhile for all the onos to get the intents
-        time.sleep(60)
+
+        # Saving intent ids to check intents in later case
+        main.intentIds = list(intentIdList)
 
         main.step("Verify intents are installed")
-        for i in range(3):
+
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Waiting for onos to install intents...")
+            time.sleep( main.checkIntentsDelay )
+
             intentState = main.TRUE
-            failedIntents = 0
-            for intent in getIntentStateResult:
-                state = intent.items()[0][1]
-                if state != 'INSTALLED':
-                    main.log.info("Intent State: " + state)
-                    failedIntents += 1
-                    intentState = main.FALSE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = intentIdList ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
             if intentState:
                 break
-            main.log.error("Total: " + str(failedIntents))
-            time.sleep(5)
+        else:
+            #Dumping intent summary
+            main.log.info( "Intents:\n" + str( main.ONOScli1.intents( jsonFormat=False, summary=True ) ) )
 
         utilities.assert_equals( expect=main.TRUE, actual=intentState,
                                  onpass="INTENTS INSTALLED",
                                  onfail="SOME INTENTS NOT INSTALLED" )
 
-
         main.step( "Verify Ping across all hosts" )
-        pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
+        for i in range(main.numPings):
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
+
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2652,17 +3133,26 @@
             str( timeDiff ) +
             " seconds" )
         utilities.assert_equals( expect=main.TRUE, actual=pingResult,
-                                 onpass="PING tALL PASS",
+                                 onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case90Result = ( intentResult and pingResult )
+        caseResult = ( intentState and pingResult )
 
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case90Result,
+            actual=caseResult,
             onpass="Install 600 point Intents and Ping All test PASS",
             onfail="Install 600 point Intents and Ping All test FAIL" )
 
+        if not intentState:
+            main.log.debug( "Intents failed to install completely" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
+
     def CASE91( self ):
         """
         Install 600 point intents and verify ping all (Chordal Topology)
@@ -2697,37 +3187,45 @@
                 intentIdList.append(thread.result)
         time2 = time.time()
         main.log.info( "Time for adding point intents: %2f seconds" %(time2-time1) )
-        intentResult = main.TRUE
-        intentsJson = main.ONOScli1.intents()
-        getIntentStateResult = main.ONOScli1.getIntentState(intentsId = intentIdList,
-                intentsJson = intentsJson)
-        # Takes awhile for all the onos to get the intents
-        time.sleep(30)
+
+        # Saving intent ids to check intents in later case
+        main.intentIds = list(intentIdList)
 
         main.step("Verify intents are installed")
-        for i in range(3):
+
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Waiting for onos to install intents...")
+            time.sleep( main.checkIntentsDelay )
+
             intentState = main.TRUE
-            failedIntents = 0
-            for intent in getIntentStateResult:
-                state = intent.items()[0][1]
-                if state != 'INSTALLED':
-                    main.log.info("Intent State: " + state)
-                    failedIntents += 1
-                    intentState = main.FALSE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = intentIdList ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
             if intentState:
                 break
-            main.log.error("Total: " + str(failedIntents))
-            time.sleep(5)
+        else:
+            #Dumping intent summary
+            main.log.info( "Intents:\n" + str( main.ONOScli1.intents( jsonFormat=False, summary=True ) ) )
 
         utilities.assert_equals( expect=main.TRUE, actual=intentState,
                                  onpass="INTENTS INSTALLED",
                                  onfail="SOME INTENTS NOT INSTALLED" )
 
-
         main.step( "Verify Ping across all hosts" )
-        pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
+        for i in range(main.numPings):
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
+
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2738,14 +3236,23 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case91Result = ( intentResult and pingResult )
+        caseResult = ( intentState and pingResult )
 
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case91Result,
+            actual=caseResult,
             onpass="Install 600 point Intents and Ping All test PASS",
             onfail="Install 600 point Intents and Ping All test FAIL" )
 
+        if not intentState:
+            main.log.debug( "Intents failed to install completely" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
+
     def CASE92( self ):
         """
         Install 4556 point intents and verify ping all (Spine Topology)
@@ -2783,38 +3290,45 @@
                 intentIdList.append(thread.result)
         time2 = time.time()
         main.log.info("Time for adding point intents: %2f seconds" %(time2-time1))
-        intentResult = main.TRUE
-        intentsJson = main.ONOScli1.intents()
-        getIntentStateResult = main.ONOScli1.getIntentState(intentsId = intentIdList,
-                intentsJson = intentsJson)
-        #print getIntentStateResult
-        # Takes awhile for all the onos to get the intents
-        time.sleep(60)
+
+        # Saving intent ids to check intents in later case
+        main.intentIds = list(intentIdList)
 
         main.step("Verify intents are installed")
-        for i in range(3):
+
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Waiting for onos to install intents...")
+            time.sleep( main.checkIntentsDelay )
+
             intentState = main.TRUE
-            failedIntents = 0
-            for intent in getIntentStateResult:
-                state = intent.items()[0][1]
-                if state != 'INSTALLED':
-                    main.log.info("Intent State: " + state)
-                    failedIntents += 1
-                    intentState = main.FALSE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = intentIdList ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
             if intentState:
                 break
-            main.log.error("Total: " + str(failedIntents))
-            time.sleep(5)
+        else:
+            #Dumping intent summary
+            main.log.info( "Intents:\n" + str( main.ONOScli1.intents( jsonFormat=False, summary=True ) ) )
 
         utilities.assert_equals( expect=main.TRUE, actual=intentState,
                                  onpass="INTENTS INSTALLED",
                                  onfail="SOME INTENTS NOT INSTALLED" )
 
-
         main.step( "Verify Ping across all hosts" )
-        pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
+        for i in range(main.numPings):
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
+
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2825,14 +3339,23 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case92Result = ( intentResult and pingResult )
+        caseResult = ( intentState and pingResult )
 
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case92Result,
+            actual=caseResult,
             onpass="Install 4556 point Intents and Ping All test PASS",
             onfail="Install 4556 point Intents and Ping All test FAIL" )
 
+        if not intentState:
+            main.log.debug( "Intents failed to install completely" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
+
     def CASE93( self ):
         """
         Install multi-single point intents and verify Ping all works
@@ -2840,13 +3363,14 @@
         """
         import copy
         import time
+        from collections import Counter
         main.log.report( "Install multi-single point intents and verify Ping all" )
         main.log.report( "___________________________________________" )
         main.case( "Install multi-single point intents and Ping all" )
         deviceDPIDsCopy = copy.copy(main.deviceDPIDs)
         portIngressList = ['1']*(len(deviceDPIDsCopy) - 1)
         intentIdList = []
-        print "MACsDict", main.MACsDict
+        main.log.info( "MACsDict" + str(main.MACsDict) )
         time1 = time.time()
         for i in xrange(0,len(deviceDPIDsCopy),int(main.numCtrls)):
             pool = []
@@ -2861,7 +3385,6 @@
                         name="addMultipointToSinglepointIntent",
                         args =[ingressDeviceList,egressDevice,portIngressList,'1','','',main.MACsDict.get(egressDevice)])
                 pool.append(t)
-                #time.sleep(1)
                 t.start()
                 i = i + 1
                 main.threadID = main.threadID + 1
@@ -2870,44 +3393,90 @@
                 intentIdList.append(thread.result)
         time2 = time.time()
         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
-        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 " )
+        main.step("Verify intents are installed")
 
-        print "Checking flows state "
-        checkFlowsState = main.ONOScli1.checkFlowsState()
-        time.sleep(50)
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Waiting for onos to install intents...")
+            time.sleep( main.checkIntentsDelay )
+
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = intentIdList ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "Intents:\n" + str( main.ONOScli1.intents( jsonFormat=False, summary=True ) ) )
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
+        main.step("Verify flows are all added")
+
+        for i in range( main.flowCheck ):
+            if i != 0:
+                main.log.warn( "verification failed. Retrying..." )
+            main.log.info( "Waiting for onos to add flows..." )
+            time.sleep( main.checkFlowsDelay )
+
+            flowState = main.TRUE
+            for cli in main.CLIs:
+                flowState = cli.checkFlowState()
+                if not flowState:
+                    main.log.warn( "Not all flows added" )
+            if flowState:
+                break
+        else:
+            #Dumping summary
+            main.log.info( "Summary:\n" + str( main.ONOScli1.summary(jsonFormat=False) ) )
+
+        utilities.assert_equals( expect=main.TRUE, actual=flowState,
+                                 onpass="FLOWS INSTALLED",
+                                 onfail="SOME FLOWS NOT ADDED" )
+
         main.step( "Verify Ping across all hosts" )
-        pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
+        for i in range(main.numPings):
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
+
         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
+
+        caseResult = ( checkFlowsState and pingResult and intentState )
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case93Result,
+            actual=caseResult,
             onpass="Install 25 multi to single point Intents and Ping All test PASS",
             onfail="Install 25 multi to single point Intents and Ping All test FAIL" )
 
+        if not intentState:
+            main.log.debug( "Intents failed to install completely" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not checkFlowsState:
+            main.log.debug( "Flows failed to add completely" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
+
     def CASE94( self ):
         """
         Install multi-single point intents and verify Ping all works
@@ -2921,7 +3490,7 @@
         deviceDPIDsCopy = copy.copy(main.deviceDPIDs)
         portIngressList = ['1']*(len(deviceDPIDsCopy) - 1)
         intentIdList = []
-        print "MACsDict", main.MACsDict
+        main.log.info( "MACsDict" + str(main.MACsDict) )
         time1 = time.time()
         for i in xrange(0,len(deviceDPIDsCopy),int(main.numCtrls)):
             pool = []
@@ -2936,7 +3505,6 @@
                         name="addMultipointToSinglepointIntent",
                         args =[ingressDeviceList,egressDevice,portIngressList,'1','','',main.MACsDict.get(egressDevice)])
                 pool.append(t)
-                #time.sleep(1)
                 t.start()
                 i = i + 1
                 main.threadID = main.threadID + 1
@@ -2945,11 +3513,65 @@
                 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 intents are installed")
+
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Waiting for onos to install intents...")
+            time.sleep( main.checkIntentsDelay )
+
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = intentIdList ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "Intents:\n" + str( main.ONOScli1.intents( jsonFormat=False, summary=True ) ) )
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
+        main.step("Verify flows are all added")
+
+        for i in range( main.flowCheck ):
+            if i != 0:
+                main.log.warn( "verification failed. Retrying..." )
+            main.log.info( "Waiting for onos to add flows..." )
+            time.sleep( main.checkFlowsDelay )
+
+            flowState = main.TRUE
+            for cli in main.CLIs:
+                flowState = cli.checkFlowState()
+                if not flowState:
+                    main.log.warn( "Not all flows added" )
+            if flowState:
+                break
+        else:
+            #Dumping summary
+            main.log.info( "Summary:\n" + str( main.ONOScli1.summary(jsonFormat=False) ) )
+
+        utilities.assert_equals( expect=main.TRUE, actual=flowState,
+                                 onpass="FLOWS INSTALLED",
+                                 onfail="SOME FLOWS NOT ADDED" )
+
         main.step( "Verify Ping across all hosts" )
-        pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
+        for i in range(main.numPings):
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
+
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -2957,14 +3579,143 @@
             str( timeDiff ) +
             " seconds" )
 
-        case94Result = pingResult
+        caseResult = ( checkFlowsState and pingResult and intentState )
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case94Result,
+            actual=caseResult,
             onpass="Install 25 multi to single point Intents and Ping All test PASS",
             onfail="Install 25 multi to single point Intents and Ping All test FAIL" )
 
-    #def CASE95 multi-single point intent for Spine
+        if not intentState:
+            main.log.debug( "Intents failed to install completely" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not checkFlowsState:
+            main.log.debug( "Flows failed to add completely" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
+
+    def CASE95( self ):
+        """
+        Install multi-single point intents and verify Ping all works
+        for Spine topology
+        """
+        import copy
+        import time
+        main.log.report( "Install multi-single point intents and verify Ping all" )
+        main.log.report( "___________________________________________" )
+        main.case( "Install multi-single point intents and Ping all" )
+        deviceDPIDsCopy = copy.copy(main.deviceDPIDs)
+        portIngressList = ['1']*(len(deviceDPIDsCopy) - 1)
+        intentIdList = []
+        main.log.info( "MACsDict" + str(main.MACsDict) )
+        time1 = time.time()
+        for i in xrange(0,len(deviceDPIDsCopy),int(main.numCtrls)):
+            pool = []
+            for cli in main.CLIs:
+                egressDevice = deviceDPIDsCopy[i]
+                ingressDeviceList = copy.copy(deviceDPIDsCopy)
+                ingressDeviceList.remove(egressDevice)
+                if i >= len( deviceDPIDsCopy ):
+                    break
+                t = main.Thread( target=cli.addMultipointToSinglepointIntent,
+                        threadID=main.threadID,
+                        name="addMultipointToSinglepointIntent",
+                        args =[ingressDeviceList,egressDevice,portIngressList,'1','','',main.MACsDict.get(egressDevice)])
+                pool.append(t)
+                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))
+
+        main.step("Verify intents are installed")
+
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Waiting for onos to install intents...")
+            time.sleep( main.checkIntentsDelay )
+
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = intentIdList ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "Intents:\n" + str( main.ONOScli1.intents( jsonFormat=False, summary=True ) ) )
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
+        main.step("Verify flows are all added")
+
+        for i in range( main.flowCheck ):
+            if i != 0:
+                main.log.warn( "verification failed. Retrying..." )
+            main.log.info( "Waiting for onos to add flows..." )
+            time.sleep( main.checkFlowsDelay )
+
+            flowState = main.TRUE
+            for cli in main.CLIs:
+                flowState = cli.checkFlowState()
+                if not flowState:
+                    main.log.warn( "Not all flows added" )
+            if flowState:
+                break
+        else:
+            #Dumping summary
+            main.log.info( "Summary:\n" + str( main.ONOScli1.summary(jsonFormat=False) ) )
+
+        utilities.assert_equals( expect=main.TRUE, actual=flowState,
+                                 onpass="FLOWS INSTALLED",
+                                 onfail="SOME FLOWS NOT ADDED" )
+
+        main.step( "Verify Ping across all hosts" )
+        for i in range(main.numPings):
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
+
+        time2 = time.time()
+        timeDiff = round( ( time2 - time1 ), 2 )
+        main.log.report(
+            "Time taken for Ping All: " +
+            str( timeDiff ) +
+            " seconds" )
+
+        caseResult = ( checkFlowsState and pingResult and intentState )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=caseResult,
+            onpass="Install 25 multi to single point Intents and Ping All test PASS",
+            onfail="Install 25 multi to single point Intents and Ping All test FAIL" )
+
+        if not intentState:
+            main.log.debug( "Intents failed to install completely" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not checkFlowsState:
+            main.log.debug( "Flows failed to add completely" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
 
     def CASE96( self ):
         """
@@ -2978,7 +3729,7 @@
         deviceDPIDsCopy = copy.copy(main.deviceDPIDs)
         portEgressList = ['1']*(len(deviceDPIDsCopy) - 1)
         intentIdList = []
-        print "MACsDict", main.MACsDict
+        main.log.info( "MACsDict" + str(main.MACsDict) )
         time1 = time.time()
         for i in xrange(0,len(deviceDPIDsCopy),int(main.numCtrls)):
             pool = []
@@ -2993,7 +3744,6 @@
                         name="addSinglepointToMultipointIntent",
                         args =[ingressDevice,egressDeviceList,'1',portEgressList,'',main.MACsDict.get(ingressDevice)])
                 pool.append(t)
-                #time.sleep(1)
                 t.start()
                 i = i + 1
                 main.threadID = main.threadID + 1
@@ -3002,11 +3752,65 @@
                 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 intents are installed")
+
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Waiting for onos to install intents...")
+            time.sleep( main.checkIntentsDelay )
+
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = intentIdList ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "Intents:\n" + str( main.ONOScli1.intents( jsonFormat=False, summary=True ) ) )
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
+        main.step("Verify flows are all added")
+
+        for i in range( main.flowCheck ):
+            if i != 0:
+                main.log.warn( "verification failed. Retrying..." )
+            main.log.info( "Waiting for onos to add flows..." )
+            time.sleep( main.checkFlowsDelay )
+
+            flowState = main.TRUE
+            for cli in main.CLIs:
+                flowState = cli.checkFlowState()
+                if not flowState:
+                    main.log.warn( "Not all flows added" )
+            if flowState:
+                break
+        else:
+            #Dumping summary
+            main.log.info( "Summary:\n" + str( main.ONOScli1.summary(jsonFormat=False) ) )
+
+        utilities.assert_equals( expect=main.TRUE, actual=flowState,
+                                 onpass="FLOWS INSTALLED",
+                                 onfail="SOME FLOWS NOT ADDED" )
+
         main.step( "Verify Ping across all hosts" )
-        pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
+        for i in range(main.numPings):
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
+
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -3014,13 +3818,24 @@
             str( timeDiff ) +
             " seconds" )
 
-        case96Result = pingResult
+        caseResult = ( pingResult and intentState and flowState)
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case96Result,
+            actual=caseResult,
             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" )
 
+        if not intentState:
+            main.log.debug( "Intents failed to install completely" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not checkFlowsState:
+            main.log.debug( "Flows failed to add completely" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
+
     def CASE97( self ):
         """
         Install single-multi point intents and verify Ping all works
@@ -3033,7 +3848,7 @@
         deviceDPIDsCopy = copy.copy(main.deviceDPIDs)
         portEgressList = ['1']*(len(deviceDPIDsCopy) - 1)
         intentIdList = []
-        print "MACsDict", main.MACsDict
+        main.log.info( "MACsDict" + str(main.MACsDict) )
         time1 = time.time()
         for i in xrange(0,len(deviceDPIDsCopy),int(main.numCtrls)):
             pool = []
@@ -3048,7 +3863,6 @@
                         name="addSinglepointToMultipointIntent",
                         args =[ingressDevice,egressDeviceList,'1',portEgressList,'',main.MACsDict.get(ingressDevice),''])
                 pool.append(t)
-                #time.sleep(1)
                 t.start()
                 i = i + 1
                 main.threadID = main.threadID + 1
@@ -3057,11 +3871,65 @@
                 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 intents are installed")
+
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Waiting for onos to install intents...")
+            time.sleep( main.checkIntentsDelay )
+
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = intentIdList ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "Intents:\n" + str( main.ONOScli1.intents( jsonFormat=False, summary=True ) ) )
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
+        main.step("Verify flows are all added")
+
+        for i in range( main.flowCheck ):
+            if i != 0:
+                main.log.warn( "verification failed. Retrying..." )
+            main.log.info( "Waiting for onos to add flows..." )
+            time.sleep( main.checkFlowsDelay )
+
+            flowState = main.TRUE
+            for cli in main.CLIs:
+                flowState = cli.checkFlowState()
+                if not flowState:
+                    main.log.warn( "Not all flows added" )
+            if flowState:
+                break
+        else:
+            #Dumping summary
+            main.log.info( "Summary:\n" + str( main.ONOScli1.summary(jsonFormat=False) ) )
+
+        utilities.assert_equals( expect=main.TRUE, actual=flowState,
+                                 onpass="FLOWS INSTALLED",
+                                 onfail="SOME FLOWS NOT ADDED" )
+
         main.step( "Verify Ping across all hosts" )
-        pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
+        for i in range(main.numPings):
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
+
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -3069,13 +3937,24 @@
             str( timeDiff ) +
             " seconds" )
 
-        case97Result = pingResult
+        caseResult = ( pingResult and intentState and flowState)
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case97Result,
+            actual=caseResult,
             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" )
 
+        if not intentState:
+            main.log.debug( "Intents failed to install completely" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not checkFlowsState:
+            main.log.debug( "Flows failed to add completely" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
+
     def CASE98( self ):
         """
         Install single-multi point intents and verify Ping all works
@@ -3093,9 +3972,8 @@
         for i in range( len( deviceDPIDsCopy ) ):
             MACsDictCopy[ deviceDPIDsCopy[ i ] ] = main.hostMACs[i].split( '/' )[ 0 ]
 
-        print "deviceDPIDsCopy", deviceDPIDsCopy
-        print ""
-        print "MACsDictCopy", MACsDictCopy
+        main.log.info( "deviceDPIDsCopy" + str(deviceDPIDsCopy) )
+        main.log.info( "MACsDictCopy" +  str(MACsDictCopy) )
         time1 = time.time()
         for i in xrange(0,len(deviceDPIDsCopy),int(main.numCtrls)):
             pool = []
@@ -3110,7 +3988,6 @@
                         name="addSinglepointToMultipointIntent",
                         args =[ingressDevice,egressDeviceList,'1',portEgressList,'',MACsDictCopy.get(ingressDevice),''])
                 pool.append(t)
-                #time.sleep(1)
                 t.start()
                 i = i + 1
                 main.threadID = main.threadID + 1
@@ -3119,11 +3996,65 @@
                 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 intents are installed")
+
+        # Giving onos multiple chances to install intents
+        for i in range( main.intentCheck ):
+            if i != 0:
+                main.log.warn( "Verification failed. Retrying..." )
+            main.log.info("Waiting for onos to install intents...")
+            time.sleep( main.checkIntentsDelay )
+
+            intentState = main.TRUE
+            for e in range(int(main.numCtrls)):
+                main.log.info( "Checking intents on CLI %s" % (e+1) )
+                intentState = main.CLIs[e].checkIntentState( intentsId = intentIdList ) and\
+                        intentState
+                if not intentState:
+                    main.log.warn( "Not all intents installed" )
+            if intentState:
+                break
+        else:
+            #Dumping intent summary
+            main.log.info( "Intents:\n" + str( main.ONOScli1.intents( jsonFormat=False, summary=True ) ) )
+
+        utilities.assert_equals( expect=main.TRUE, actual=intentState,
+                                 onpass="INTENTS INSTALLED",
+                                 onfail="SOME INTENTS NOT INSTALLED" )
+
+        main.step("Verify flows are all added")
+
+        for i in range( main.flowCheck ):
+            if i != 0:
+                main.log.warn( "verification failed. Retrying..." )
+            main.log.info( "Waiting for onos to add flows..." )
+            time.sleep( main.checkFlowsDelay )
+
+            flowState = main.TRUE
+            for cli in main.CLIs:
+                flowState = cli.checkFlowState()
+                if not flowState:
+                    main.log.warn( "Not all flows added" )
+            if flowState:
+                break
+        else:
+            #Dumping summary
+            main.log.info( "Summary:\n" + str( main.ONOScli1.summary(jsonFormat=False) ) )
+
+        utilities.assert_equals( expect=main.TRUE, actual=flowState,
+                                 onpass="FLOWS INSTALLED",
+                                 onfail="SOME FLOWS NOT ADDED" )
+
         main.step( "Verify Ping across all hosts" )
-        pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout,shortCircuit=False,acceptableFailed=5)
+        for i in range(main.numPings):
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
+
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -3131,13 +4062,24 @@
             str( timeDiff ) +
             " seconds" )
 
-        case98Result = pingResult
+        caseResult = ( pingResult and intentState and flowState)
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case98Result,
+            actual=caseResult,
             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" )
 
+        if not intentState:
+            main.log.debug( "Intents failed to install completely" )
+        if not pingResult:
+            main.log.debug( "Pingall failed" )
+        if not checkFlowsState:
+            main.log.debug( "Flows failed to add completely" )
+
+        if not caseResult and main.failSwitch:
+            main.log.report("Stopping test")
+            main.stop( email=main.emailOnStop )
+
     def CASE190( self ):
         """
         Verify IPv6 ping across 600 Point intents (Att Topology)
@@ -3148,15 +4090,13 @@
         import time
         main.case( "IPv6 ping all 600 Point intents" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 1)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("First pingall failed. Retrying...")
             time1 = time.time()
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
-
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -3167,10 +4107,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case160Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case160Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 600 Point intents test PASS",
             onfail="IPv6 Ping across 600 Point intents test FAIL" )
 
@@ -3184,15 +4124,13 @@
         import time
         main.case( "IPv6 ping all 600 Point intents" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 1)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("First pingall failed. Retrying...")
             time1 = time.time()
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
-
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -3203,10 +4141,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case191Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case191Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 600 Point intents test PASS",
             onfail="IPv6 Ping across 600 Point intents test FAIL" )
 
@@ -3220,15 +4158,13 @@
         import time
         main.case( "IPv6 ping all 4556 Point intents" )
         main.step( "Verify IPv6 Ping across all hosts" )
-        hostList = [ ('h'+ str(x + 11)) for x in range (main.numMNhosts) ]
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
+        pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         if not pingResult:
             main.log.warn("First pingall failed. Retrying...")
             time1 = time.time()
-            pingResult = main.Mininet1.pingIpv6Hosts( hostList, prefix='1000::' )
-
+            pingResult = main.Mininet1.pingall( protocol="IPv6", timeout=main.pingTimeout )
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -3239,10 +4175,10 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case192Result = pingResult
+        caseResult = pingResult
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case192Result,
+            actual=caseResult,
             onpass="IPv6 Ping across 4556 Point intents test PASS",
             onfail="IPv6 Ping across 4556 Point intents test FAIL" )
 
@@ -3343,8 +4279,8 @@
             step1Result = main.FALSE
 
         print main.ONOScli1.intents()
-        caseResult10 = step1Result
-        utilities.assert_equals( expect=main.TRUE, actual=caseResult10,
+        caseResult = step1Result
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Intent removal test successful",
                                  onfail="Intent removal test failed" )
 
@@ -3389,10 +4325,15 @@
             installResult = main.TRUE
         main.log.info("Time for feature:install onos-app-ifwd: %2f seconds" %(time2-time1))
 
-        main.step( "Verify Pingall" )
-        pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall(timeout=600)
+        main.step( "Verify Ping across all hosts" )
+        for i in range(main.numPings):
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+            if not pingResult:
+                main.log.warn("First pingall failed. Retrying...")
+                time.sleep(main.pingSleep)
+            else: break
+
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -3436,7 +4377,7 @@
         # Waiting for reative flows to be cleared.
         time.sleep( 10 )
 
-        case11Result = installResult and pingResult and uninstallResult
-        utilities.assert_equals( expect=main.TRUE, actual=case11Result,
+        caseResult = installResult and pingResult and uninstallResult
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult,
                                  onpass="Intent based Reactive forwarding Pingall test PASS",
                                  onfail="Intent based Reactive forwarding Pingall test FAIL" )
diff --git a/TestON/tests/FUNCflow/Dependency/flow-2sw.py b/TestON/tests/FUNCflow/Dependency/flow-2sw.py
new file mode 100755
index 0000000..2299d9e
--- /dev/null
+++ b/TestON/tests/FUNCflow/Dependency/flow-2sw.py
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+
+"""
+Custom topology for Mininet
+"""
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import Host, RemoteController
+from mininet.node import Node
+from mininet.node import CPULimitedHost
+from mininet.link import TCLink
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+from mininet.util import dumpNodeConnections
+from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+
+class MyTopo( Topo ):
+
+    def __init__( self ):
+        # Initialize topology
+        Topo.__init__( self )
+        # Switch S5 Hosts
+        host1=self.addHost( 'h1', ip='10.1.0.1/24' )
+        host2=self.addHost( 'h2', ip='10.1.0.2/24' )
+        #host3=self.addHost( 'h3', ip='10.1.0.3/24', v6Addr='1000::3/64' )
+        #host4=self.addHost( 'h4', ip='10.1.0.4/24', v6Addr='1000::4/64' )
+
+        s1 = self.addSwitch( 's1' )
+        #s2 = self.addSwitch( 's2' )
+
+        self.addLink(s1, host1)
+        self.addLink(s1, host2)
+        #self.addLink(s1, host3)
+        #self.addLink(s1, host4)
+
+
+        topos = { 'mytopo': ( lambda: MyTopo() ) }
+
+def setupNetwork():
+    "Create network"
+    topo = MyTopo()
+    network = Mininet(topo=topo, autoSetMacs=True, controller=None)
+    network.start()
+    CLI( network )
+    network.stop()
+
+if __name__ == '__main__':
+    setLogLevel('info')
+    #setLogLevel('debug')
+    setupNetwork()
diff --git a/TestON/tests/FUNCflow/Dependency/startUp.py b/TestON/tests/FUNCflow/Dependency/startUp.py
new file mode 100644
index 0000000..bf2a2b6
--- /dev/null
+++ b/TestON/tests/FUNCflow/Dependency/startUp.py
@@ -0,0 +1,38 @@
+"""
+    This wrapper function is use for starting up onos instance
+"""
+
+import time
+import os
+import json
+
+def onosBuild( main, gitBranch ):
+    """
+        This includes pulling ONOS and building it using maven install
+    """
+
+    buildResult = main.FALSE
+
+    # Git checkout a branch of ONOS
+    checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
+    # Does the git pull on the branch that was checked out
+    if not checkOutResult:
+        main.log.warn( "Failed to checked out " + gitBranch +
+                                           " branch")
+    else:
+        main.log.info( "Successfully checked out " + gitBranch +
+                                           " branch")
+    gitPullResult = main.ONOSbench.gitPull()
+    if gitPullResult == main.ERROR:
+        main.log.error( "Error pulling git branch" )
+    else:
+        main.log.info( "Successfully pulled " + gitBranch + " branch" )
+
+    # Maven clean install
+    buildResult = main.ONOSbench.cleanInstall()
+
+    return buildResult
+
+
+
+
diff --git a/TestON/tests/FUNCflow/Dependency/topo-flow.py b/TestON/tests/FUNCflow/Dependency/topo-flow.py
new file mode 100755
index 0000000..2299d9e
--- /dev/null
+++ b/TestON/tests/FUNCflow/Dependency/topo-flow.py
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+
+"""
+Custom topology for Mininet
+"""
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import Host, RemoteController
+from mininet.node import Node
+from mininet.node import CPULimitedHost
+from mininet.link import TCLink
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+from mininet.util import dumpNodeConnections
+from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+
+class MyTopo( Topo ):
+
+    def __init__( self ):
+        # Initialize topology
+        Topo.__init__( self )
+        # Switch S5 Hosts
+        host1=self.addHost( 'h1', ip='10.1.0.1/24' )
+        host2=self.addHost( 'h2', ip='10.1.0.2/24' )
+        #host3=self.addHost( 'h3', ip='10.1.0.3/24', v6Addr='1000::3/64' )
+        #host4=self.addHost( 'h4', ip='10.1.0.4/24', v6Addr='1000::4/64' )
+
+        s1 = self.addSwitch( 's1' )
+        #s2 = self.addSwitch( 's2' )
+
+        self.addLink(s1, host1)
+        self.addLink(s1, host2)
+        #self.addLink(s1, host3)
+        #self.addLink(s1, host4)
+
+
+        topos = { 'mytopo': ( lambda: MyTopo() ) }
+
+def setupNetwork():
+    "Create network"
+    topo = MyTopo()
+    network = Mininet(topo=topo, autoSetMacs=True, controller=None)
+    network.start()
+    CLI( network )
+    network.stop()
+
+if __name__ == '__main__':
+    setLogLevel('info')
+    #setLogLevel('debug')
+    setupNetwork()
diff --git a/TestON/tests/FUNCflow/Dependency/topo.py b/TestON/tests/FUNCflow/Dependency/topo.py
new file mode 100644
index 0000000..b44e3fc
--- /dev/null
+++ b/TestON/tests/FUNCflow/Dependency/topo.py
@@ -0,0 +1,100 @@
+"""
+    These functions can be used for topology comparisons
+"""
+
+import time
+import os
+import json
+
+def getAllDevices( main ):
+    """
+        Return a list containing the devices output from each ONOS node
+    """
+    devices = []
+    threads = []
+    for i in range( main.numCtrls ):
+        t = main.Thread( target=main.CLIs[i].devices,
+                         name="devices-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        devices.append( t.result )
+    return devices
+
+def getAllHosts( main ):
+    """
+        Return a list containing the hosts output from each ONOS node
+    """
+    hosts = []
+    ipResult = main.TRUE
+    threads = []
+    for i in range( main.numCtrls ):
+        t = main.Thread( target=main.CLIs[i].hosts,
+                         name="hosts-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        hosts.append( t.result )
+    return hosts
+
+def getAllPorts( main ):
+    """
+        Return a list containing the ports output from each ONOS node
+    """
+    ports = []
+    threads = []
+    for i in range( main.numCtrls ):
+        t = main.Thread( target=main.CLIs[i].ports,
+                         name="ports-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        ports.append( t.result )
+    return ports
+
+def getAllLinks( main ):
+    """
+        Return a list containing the links output from each ONOS node
+    """
+    links = []
+    threads = []
+    for i in range( main.numCtrls ):
+        t = main.Thread( target=main.CLIs[i].links,
+                         name="links-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        links.append( t.result )
+    return links
+
+def getAllClusters( main ):
+    """
+        Return a list containing the clusters output from each ONOS node
+    """
+    clusters = []
+    threads = []
+    for i in range( main.numCtrls ):
+        t = main.Thread( target=main.CLIs[i].clusters,
+                         name="clusters-" + str( i ),
+                         args=[ ] )
+        threads.append( t )
+        t.start()
+
+    for t in threads:
+        t.join()
+        clusters.append( t.result )
+    return clusters
+
+
diff --git a/TestON/tests/FUNCflow/FUNCflow.params b/TestON/tests/FUNCflow/FUNCflow.params
new file mode 100755
index 0000000..e0dde55
--- /dev/null
+++ b/TestON/tests/FUNCflow/FUNCflow.params
@@ -0,0 +1,56 @@
+
+<PARAMS>
+    # CASE - Descritpion
+    # 1 - Variable initialization and optional pull and build ONOS package
+    # 2 - install ONOS
+    # 8 - Compare topology
+    # 9 - Report logs
+    # 10 - Start mininet and assign switches to controller
+    # 1000 - Add flows
+    # 2000 - Verify flows are in the ADDED state
+    # 3000 - Delete flows
+    <testcases>1,2,10,11,1000,2000,3000,100</testcases>
+
+    <SCALE>
+        <max>1</max>
+    </SCALE>
+
+    <DEPENDENCY>
+        <path>/tests/FUNCflow/Dependency/</path>
+        <wrapper1>startUp</wrapper1>
+        <wrapper2>topo</wrapper2>
+        <topology>topo-flow.py</topology>
+    </DEPENDENCY>
+
+
+    <TOPO>
+        <numSwitches>1</numSwitches>
+        <numHosts>2</numHosts>
+        <numLinks>0</numLinks>
+    </TOPO>
+
+    <MININET>
+        <deviceId>of:0000000000000001</deviceId>
+        <hostMac1>00:00:00:00:00:01</hostMac1>
+        <hostMac2>00:00:00:00:00:02</hostMac2>
+    </MININET>
+
+    <ENV>
+        <cellName>productionCell</cellName>
+        <cellApps>drivers,openflow</cellApps>
+    </ENV>
+
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
+
+    <CTRL>
+        <port>6653</port>
+    </CTRL>
+
+    <SLEEP>
+        <startup>15</startup>
+    </SLEEP>
+
+</PARAMS>
diff --git a/TestON/tests/FUNCflow/FUNCflow.py b/TestON/tests/FUNCflow/FUNCflow.py
new file mode 100644
index 0000000..fdd2c1f
--- /dev/null
+++ b/TestON/tests/FUNCflow/FUNCflow.py
@@ -0,0 +1,398 @@
+class FUNCflow:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):
+        import time
+        import os
+        import imp
+
+        """
+        - Construct tests variables
+        - GIT ( optional )
+            - Checkout ONOS master branch
+            - Pull latest ONOS code
+        - Building ONOS ( optional )
+            - Install ONOS package
+            - Build ONOS package
+        """
+
+        main.case( "Constructing test variables and building ONOS package" )
+        main.step( "Constructing test variables" )
+        stepResult = main.FALSE
+
+        # Test variables
+        main.testOnDirectory = os.path.dirname( os.getcwd ( ) )
+        main.cellName = main.params[ 'ENV' ][ 'cellName' ]
+        main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+        gitBranch = main.params[ 'GIT' ][ 'branch' ]
+        main.dependencyPath = main.testOnDirectory + \
+                              main.params[ 'DEPENDENCY' ][ 'path' ]
+        main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
+        main.maxNodes = int( main.params[ 'SCALE' ][ 'max' ] )
+        main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
+        main.numSwitches = int( main.params[ 'TOPO' ][ 'numSwitches' ] )
+        main.numHosts = int( main.params[ 'TOPO' ][ 'numHosts' ] )
+        main.numLinks = int( main.params[ 'TOPO' ][ 'numLinks' ] )
+        wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
+        wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
+        main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+        gitPull = main.params[ 'GIT' ][ 'pull' ]
+        main.cellData = {} # for creating cell file
+        main.CLIs = []
+        main.ONOSip = []
+
+        main.ONOSip = main.ONOSbench.getOnosIps()
+        print main.ONOSip
+
+        # Assigning ONOS cli handles to a list
+        for i in range( 1,  main.maxNodes + 1 ):
+            main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
+
+        # -- INIT SECTION, ONLY RUNS ONCE -- #
+        main.startUp = imp.load_source( wrapperFile1,
+                                        main.dependencyPath +
+                                        wrapperFile1 +
+                                        ".py" )
+
+        main.topo = imp.load_source( wrapperFile2,
+                                     main.dependencyPath +
+                                     wrapperFile2 +
+                                     ".py" )
+
+        copyResult = main.ONOSbench.scp( main.Mininet1,
+                                         main.dependencyPath+main.topology,
+                                         main.Mininet1.home+'/custom/',
+                                         direction="to" )
+
+        if main.CLIs:
+            stepResult = main.TRUE
+        else:
+            main.log.error( "Did not properly created list of ONOS CLI handle" )
+            stepResult = main.FALSE
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully construct " +
+                                        "test variables ",
+                                 onfail="Failed to construct test variables" )
+
+        if gitPull == 'True':
+            main.step( "Building ONOS in " + gitBranch + " branch" )
+            onosBuildResult = main.startUp.onosBuild( main, gitBranch )
+            stepResult = onosBuildResult
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=stepResult,
+                                     onpass="Successfully compiled " +
+                                            "latest ONOS",
+                                     onfail="Failed to compile " +
+                                            "latest ONOS" )
+        else:
+            main.log.warn( "Did not pull new code so skipping mvn " +
+                           "clean install" )
+
+    def CASE2( self, main ):
+        """
+        - Set up cell
+            - Create cell file
+            - Set cell file
+            - Verify cell file
+        - Kill ONOS process
+        - Uninstall ONOS cluster
+        - Verify ONOS start up
+        - Install ONOS cluster
+        - Connect to cli
+        """
+
+        main.numCtrls = int( main.maxNodes )
+
+        main.case( "Starting up " + str( main.numCtrls ) +
+                   " node(s) ONOS cluster" )
+
+        #kill off all onos processes
+        main.log.info( "Safety check, killing all ONOS processes" +
+                       " before initiating enviornment setup" )
+
+        for i in range( main.maxNodes ):
+            main.ONOSbench.onosDie( main.ONOSip[ i ] )
+
+        print "NODE COUNT = ", main.numCtrls
+
+        tempOnosIp = []
+        for i in range( main.numCtrls ):
+            tempOnosIp.append( main.ONOSip[i] )
+
+        main.ONOSbench.createCellFile( main.ONOSbench.ip_address, "temp", main.Mininet1.ip_address, main.apps, tempOnosIp )
+
+        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.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" )
+
+        time.sleep( main.startUpSleep )
+        main.step( "Uninstalling ONOS package" )
+        onosUninstallResult = main.TRUE
+        for i in range( main.numCtrls ):
+            onosUninstallResult = onosUninstallResult and \
+                    main.ONOSbench.onosUninstall( nodeIp=main.ONOSip[ i ] )
+        stepResult = onosUninstallResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully uninstalled ONOS package",
+                                 onfail="Failed to uninstall ONOS package" )
+
+        time.sleep( main.startUpSleep )
+        main.step( "Installing ONOS package" )
+        onosInstallResult = main.TRUE
+        for i in range( main.numCtrls ):
+            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" )
+
+        time.sleep( main.startUpSleep )
+        main.step( "Starting ONOS service" )
+        stopResult = main.TRUE
+        startResult = main.TRUE
+        onosIsUp = main.TRUE
+
+        for i in range( main.numCtrls ):
+            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
+        if onosIsUp == main.TRUE:
+            main.log.report( "ONOS instance is up and ready" )
+        else:
+            main.log.report( "ONOS instance may not be up, stop and " +
+                             "start ONOS again " )
+            for i in range( main.numCtrls ):
+                stopResult = stopResult and \
+                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
+            for i in range( main.numCtrls ):
+                startResult = startResult and \
+                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
+        stepResult = onosIsUp and stopResult and startResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="ONOS service is ready",
+                                 onfail="ONOS service did not start properly" )
+
+        main.step( "Start ONOS cli" )
+        cliResult = main.TRUE
+        for i in range( main.numCtrls ):
+            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" )
+
+    def CASE10( self, main ):
+        '''
+            Start Mininet
+        '''
+        main.case( "Setup mininet and assign switches to controllers" )
+        main.step( "Setup Mininet Topology" )
+        topology = main.Mininet1.home + '/custom/' + main.topology
+        mnCmd = 'mn --custom ' + topology + ' --mac --arp'
+        stepResult1 = main.Mininet1.startNet( mnCmd=mnCmd )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult1,
+                                 onpass="Successfully loaded topology",
+                                 onfail="Failed to load topology" )
+
+        main.step( "Assign switches to controllers" )
+        for i in range( main.numSwitches ):
+            stepResult2 = main.Mininet1.assignSwController(
+                                            sw="s" + str( i+1 ),
+                                            ip=main.ONOSip )
+            if not stepResult2:
+                break
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult2,
+                                 onpass="Controller assignment successfull",
+                                 onfail="Controller assignment failed" )
+
+        time.sleep(5)
+
+        caseResult = stepResult1 and stepResult2
+        if not caseResult:
+            main.cleanup()
+            main.exit()
+
+    def CASE11( self, main ):
+        '''
+            Compare topology
+        '''
+        import json
+
+        main.case( "Compare ONOS Topology view to Mininet topology" )
+        main.caseExplanation = "Compare topology elements between Mininet" +\
+                                " and ONOS"
+
+        main.step( "Gathering topology information" )
+        # TODO: add a paramaterized sleep here
+        devicesResults = main.TRUE
+        linksResults = main.TRUE
+        hostsResults = main.TRUE
+        devices = main.topo.getAllDevices( main )
+        hosts = main.topo.getAllHosts( main )
+        ports = main.topo.getAllPorts( main )
+        links = main.topo.getAllLinks( main )
+        clusters = main.topo.getAllClusters( main )
+
+        mnSwitches = main.Mininet1.getSwitches()
+        mnLinks = main.Mininet1.getLinks()
+        mnHosts = main.Mininet1.getHosts()
+
+        main.step( "Conmparing MN topology to ONOS topology" )
+        for controller in range( main.numCtrls ):
+            controllerStr = str( controller + 1 )
+            if devices[ controller ] and ports[ controller ] and\
+                "Error" not in devices[ controller ] and\
+                "Error" not in ports[ controller ]:
+
+                currentDevicesResult = main.Mininet1.compareSwitches(
+                        mnSwitches,
+                        json.loads( devices[ controller ] ),
+                        json.loads( ports[ controller ] ) )
+            else:
+                currentDevicesResult = main.FALSE
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=currentDevicesResult,
+                                     onpass="ONOS" + controllerStr +
+                                            " Switches view is correct",
+                                     onfail="ONOS" + controllerStr +
+                                            " Switches view is incorrect" )
+            if links[ controller ] and "Error" not in links[ controller ]:
+                currentLinksResult = main.Mininet1.compareLinks(
+                        mnSwitches, mnLinks,
+                        json.loads( links[ controller ] ) )
+            else:
+                currentLinksResult = main.FALSE
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=currentLinksResult,
+                                     onpass="ONOS" + controllerStr +
+                                            " links view is correct",
+                                     onfail="ONOS" + controllerStr +
+                                            " links view is incorrect" )
+
+            if hosts[ controller ] or "Error" not in hosts[ controller ]:
+                currentHostsResult = main.Mininet1.compareHosts(
+                        mnHosts,
+                        json.loads( hosts[ controller ] ) )
+            else:
+                currentHostsResult = main.FALSE
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=currentHostsResult,
+                                     onpass="ONOS" + controllerStr +
+                                            " hosts exist in Mininet",
+                                     onfail="ONOS" + controllerStr +
+                                            " hosts don't match Mininet")
+
+
+
+    def CASE1000( self, main ):
+        '''
+            Add flows
+        '''
+
+        main.step("Add flows through rest")
+
+        deviceId = main.params['MININET']['deviceId']
+        host1_mac = main.params['MININET']['hostMac1']
+        host2_mac = main.params['MININET']['hostMac2']
+
+        # Add flows that connects host1 to host 2
+        stepResult = main.ONOSrest.addFlow( deviceId=deviceId,
+                                            egressPort=2,
+                                            ingressPort=1,
+                                            ethSrc=host1_mac,
+                                            ethDst=host2_mac)
+
+        stepResult = stepResult and main.ONOSrest.addFlow( deviceId=deviceId,
+                                                           egressPort=1,
+                                                           ingressPort=2,
+                                                           ethSrc=host2_mac,
+                                                           ethDst=host1_mac)
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully added flows",
+                                 onfail="Failed add flows" )
+
+    def CASE2000( self, main ):
+        '''
+            Check flows are ADDED
+        '''
+        import json
+        main.step("Check flows  are in the ADDED state")
+        main.log.info("Check only the flows added through REST")
+
+        flows = json.loads( main.ONOSrest.flows() )
+
+        stepResult = main.TRUE
+        for f in flows:
+            if "rest" in f.get("appId"):
+                if "ADDED" in f.get("state"):
+                    stepResult = stepResult and main.ONOSrest.removeFlow( deviceId, flowId )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="All flows are in the ADDED state",
+                                 onfail="All flows are in the ADDED state" )
+
+    def CASE3000( self, main ):
+        '''
+            Delete flows that were added through REST
+        '''
+        import json
+        main.step("Remove flows")
+        main.log.info("Remove the flows that were added through rest")
+
+        flows = json.loads( main.ONOSrest.flows() )
+
+        stepResult = main.TRUE
+        for f in flows:
+            if "rest" in f.get("appId"):
+                flowId = f.get("id")
+                deviceId = f.get("deviceId")
+                stepResult = stepResult and main.ONOSrest.removeFlow( deviceId, flowId )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully removed all rest flows",
+                                 onfail="Failed to remove rest flows" )
+
+    def CASE100( self, main ):
+        '''
+            Report errors/warnings/exceptions
+        '''
+        main.log.info("Error report: \n" )
+        main.ONOSbench.logReport( main.ONOSip[ 0 ],
+                                  [ "INFO",
+                                    "FOLLOWER",
+                                    "WARN",
+                                    "flow",
+                                    "ERROR",
+                                    "Except" ],
+                                  "s" )
+
diff --git a/TestON/tests/FUNCflow/FUNCflow.topo b/TestON/tests/FUNCflow/FUNCflow.topo
new file mode 100755
index 0000000..9ea3d19
--- /dev/null
+++ b/TestON/tests/FUNCflow/FUNCflow.topo
@@ -0,0 +1,45 @@
+<TOPOLOGY>
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOScli1>
+            <host>localhost</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOScli1>
+
+        <Mininet1>
+            <host>localhost</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>MininetCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </Mininet1>
+
+        <ONOSrest>
+            <host>OC1</host>
+            <port>8181</port>
+            <user>onos</user>
+            <password>rocks</password>
+            <type>OnosRestDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOSrest>
+
+    </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/FUNCflow/__init__.py b/TestON/tests/FUNCflow/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/FUNCflow/__init__.py
diff --git a/TestON/tests/FUNCintent/Dependency/FuncIntentFunction.py b/TestON/tests/FUNCintent/Dependency/FuncIntentFunction.py
index ff886a2..9efe5d0 100644
--- a/TestON/tests/FUNCintent/Dependency/FuncIntentFunction.py
+++ b/TestON/tests/FUNCintent/Dependency/FuncIntentFunction.py
@@ -153,13 +153,22 @@
                        " something wrong with ONOS performance" )
 
     # Ping hosts again...
-    pingResult = pingResult and pingallHosts( main, hostNames )
+    pingTemp = pingallHosts( main, hostNames )
+    pingResult = pingResult and pingTemp
+    if pingTemp:
+        main.assertReturnString += 'Initial Pingall Passed\n'
+    else:
+        main.assertReturnString += 'Initial Pingall Failed\n'
 
     # Test rerouting if these variables exist
     if sw1 and sw2 and expectedLink:
-        # link down
+        # Link down
         linkDownResult = link( main, sw1, sw2, "down" )
-        intentResult = intentResult and checkIntentState( main, intentsId )
+
+        if linkDownResult:
+            main.assertReturnString += 'Link Down Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Failed\n'
 
         # Check flows count in each node
         checkFlowsCount( main )
@@ -168,11 +177,27 @@
 
         # Check OnosTopology
         topoResult = checkTopology( main, expectedLink )
+        if topoResult:
+            main.assertReturnString += 'Link Down Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Topology State Failed\n'
 
         # Ping hosts
-        pingResult = pingResult and pingallHosts( main, hostNames )
+        pingTemp = pingallHosts( main, hostNames )
+        pingResult = pingResult and pingTemp
 
-        intentResult = checkIntentState( main, intentsId )
+        if pingTemp:
+            main.assertReturnString += 'Link Down Pingall Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Pingall Failed\n'
+
+        # Check intent states
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Down Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Intent State Failed\n'
 
         # Checks ONOS state in link down
         if linkDownResult and topoResult and pingResult and intentResult:
@@ -180,10 +205,15 @@
         else:
             main.log.error( itemName + ": Failed to bring link down" )
 
-        # link up
+        # Link up
         linkUpResult = link( main, sw1, sw2, "up" )
         time.sleep( main.rerouteSleep )
 
+        if linkUpResult:
+            main.assertReturnString += 'Link Up Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Failed\n'
+
         # Check flows count in each node
         checkFlowsCount( main )
         # Verify flows
@@ -192,10 +222,26 @@
         # Check OnosTopology
         topoResult = checkTopology( main, main.numLinks )
 
-        # Ping hosts
-        pingResult = pingResult and pingallHosts( main, hostNames )
+        if topoResult:
+            main.assertReturnString += 'Link Up Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Topology State Failed\n'
 
-        intentResult = checkIntentState( main, intentsId )
+        # Ping hosts
+        pingTemp = pingallHosts( main, hostNames )
+        pingResult = pingResult and pingTemp
+
+        if pingTemp:
+            main.assertReturnString += 'Link Up Pingall Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Pingall Failed\n'
+
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Up Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Intent State Failed\n'
 
         # Checks ONOS state in link up
         if linkUpResult and topoResult and pingResult and intentResult:
@@ -206,6 +252,11 @@
     # Remove all intents
     removeIntentResult = removeAllIntents( main, intentsId )
 
+    if removeIntentResult:
+        main.assertReturnString += 'Remove Intents Passed'
+    else:
+        main.assertReturnString += 'Remove Intents Failed'
+
     stepResult = pingResult and linkDownResult and linkUpResult \
                  and intentResult and removeIntentResult
 
@@ -354,13 +405,22 @@
     checkFlowsState( main )
 
     # Ping hosts
-    pingResult = pingResult and pingallHosts( main, hostNames )
+    pingTemp = pingallHosts( main, hostNames )
+    pingResult = pingResult and pingTemp
+    if pingTemp:
+        main.assertReturnString += 'Initial Pingall Passed\n'
+    else:
+        main.assertReturnString += 'Initial Pingall Failed\n'
 
     # Test rerouting if these variables exist
     if sw1 and sw2 and expectedLink:
         # link down
         linkDownResult = link( main, sw1, sw2, "down" )
-        intentResult = intentResult and checkIntentState( main, intentsId )
+
+        if linkDownResult:
+            main.assertReturnString += 'Link Down Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Failed\n'
 
         # Check flows count in each node
         checkFlowsCount( main )
@@ -369,11 +429,26 @@
 
         # Check OnosTopology
         topoResult = checkTopology( main, expectedLink )
+        if topoResult:
+            main.assertReturnString += 'Link Down Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Topology State Failed\n'
 
         # Ping hosts
-        pingResult = pingResult and pingallHosts( main, hostNames )
+        pingTemp = pingallHosts( main, hostNames )
+        pingResult = pingResult and pingTemp
+        if pingTemp:
+            main.assertReturnString += 'Link Down Pingall Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Pingall Failed\n'
 
-        intentResult = checkIntentState( main, intentsId )
+        # Check intent state
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Down Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Intent State Failed\n'
 
         # Checks ONOS state in link down
         if linkDownResult and topoResult and pingResult and intentResult:
@@ -383,6 +458,11 @@
 
         # link up
         linkUpResult = link( main, sw1, sw2, "up" )
+        if linkUpResult:
+            main.assertReturnString += 'Link Up Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Failed\n'
+
         time.sleep( main.rerouteSleep )
 
         # Check flows count in each node
@@ -392,11 +472,26 @@
 
         # Check OnosTopology
         topoResult = checkTopology( main, main.numLinks )
+        if topoResult:
+            main.assertReturnString += 'Link Up Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Topology State Failed\n'
 
         # Ping hosts
-        pingResult = pingResult and pingallHosts( main, hostNames )
+        pingTemp = pingallHosts( main, hostNames )
+        pingResult = pingResult and pingTemp
 
-        intentResult = checkIntentState( main, intentsId )
+        if pingTemp:
+            main.assertReturnString += 'Link Up Pingall Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Pingall Failed\n'
+
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Up Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Intent State Failed\n'
 
         # Checks ONOS state in link up
         if linkUpResult and topoResult and pingResult and intentResult:
@@ -406,6 +501,10 @@
 
     # Remove all intents
     removeIntentResult = removeAllIntents( main, intentsId )
+    if removeIntentResult:
+        main.assertReturnString += 'Remove Intents Passed'
+    else:
+        main.assertReturnString += 'Remove Intents Failed'
 
     stepResult = pingResult and linkDownResult and linkUpResult \
                  and intentResult and removeIntentResult
@@ -588,14 +687,22 @@
     checkFlowsState( main )
 
     # Run iperf to both host
-    iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
-                                                          host2, 10 )
+    iperfTemp = main.Mininet1.iperftcp( host1,host2,10 )
+    iperfResult = iperfResult and iperfTemp
+    if iperfTemp:
+        main.assertReturnString += 'Initial Iperf Passed\n'
+    else:
+        main.assertReturnString += 'Initial Iperf Failed\n'
 
     # Test rerouting if these variables exist
     if sw1 and sw2 and expectedLink:
         # link down
         linkDownResult = link( main, sw1, sw2, "down" )
-        intentResult = intentResult and checkIntentState( main, intentsId )
+
+        if linkDownResult:
+            main.assertReturnString += 'Link Down Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Failed\n'
 
         # Check flows count in each node
         checkFlowsCount( main )
@@ -604,12 +711,26 @@
 
         # Check OnosTopology
         topoResult = checkTopology( main, expectedLink )
+        if topoResult:
+            main.assertReturnString += 'Link Down Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Topology State Failed\n'
 
         # Run iperf to both host
-        iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
-                                                              host2, 10 )
+        iperfTemp = main.Mininet1.iperftcp( host1,host2,10 )
+        iperfResult = iperfResult and iperfTemp
+        if iperfTemp:
+            main.assertReturnString += 'Link Down Iperf Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Iperf Failed\n'
 
-        intentResult = checkIntentState( main, intentsId )
+        # Check intent state
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Down Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Intent State Failed\n'
 
         # Checks ONOS state in link down
         if linkDownResult and topoResult and iperfResult and intentResult:
@@ -619,6 +740,11 @@
 
         # link up
         linkUpResult = link( main, sw1, sw2, "up" )
+        if linkUpTemp:
+            main.assertReturnString += 'Link Up Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Failed\n'
+
         time.sleep( main.rerouteSleep )
 
         # Check flows count in each node
@@ -629,11 +755,26 @@
         # Check OnosTopology
         topoResult = checkTopology( main, main.numLinks )
 
-        # Run iperf to both host
-        iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
-                                                              host2, 10 )
+        if topoResult:
+            main.assertReturnString += 'Link Up Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Topology State Failed\n'
 
-        intentResult = checkIntentState( main, intentsId )
+        # Run iperf to both host
+        iperfTemp = main.Mininet1.iperftcp( host1,host2,10 )
+        iperfResult = iperfResult and iperfTemp
+        if iperfTemp:
+            main.assertReturnString += 'Link Up Iperf Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Iperf Failed\n'
+
+        # Check intent state
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Down Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Intent State Failed\n'
 
         # Checks ONOS state in link up
         if linkUpResult and topoResult and iperfResult and intentResult:
@@ -643,6 +784,10 @@
 
     # Remove all intents
     removeIntentResult = removeAllIntents( main, intentsId )
+    if removeIntentResult:
+        main.assertReturnString += 'Remove Intents Passed'
+    else:
+        main.assertReturnString += 'Remove Intents Failed'
 
     stepResult = iperfResult and linkDownResult and linkUpResult \
                  and intentResult and removeIntentResult
@@ -819,7 +964,7 @@
                                             tcpDst="" ) )
 
     # Wait some time for the flow to go through when using multi instance
-    pingResult = pingallHosts( main, hostNames )
+    pingTemp = pingallHosts( main, hostNames )
 
     # Check intents state
     time.sleep( main.checkIntentSleep )
@@ -834,13 +979,22 @@
     # Verify flows
     checkFlowsState( main )
 
-    pingResult = pingResult and pingallHosts( main, hostNames )
+    pingTemp = pingallHosts( main, hostNames )
+    pingResult = pingResult and pingTemp
+    if pingTemp:
+        main.assertReturnString += 'Initial Pingall Passed\n'
+    else:
+        main.assertReturnString += 'Initial Pingall Failed\n'
 
     # Test rerouting if these variables exist
     if sw1 and sw2 and expectedLink:
         # link down
         linkDownResult = link( main, sw1, sw2, "down" )
-        intentResult = intentResult and checkIntentState( main, intentsId )
+
+        if linkDownResult:
+            main.assertReturnString += 'Link Down Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Failed\n'
 
         # Check flows count in each node
         checkFlowsCount( main )
@@ -849,11 +1003,26 @@
 
         # Check OnosTopology
         topoResult = checkTopology( main, expectedLink )
+        if topoResult:
+            main.assertReturnString += 'Link Down Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Topology State Failed\n'
 
         # Ping hosts
-        pingResult = pingResult and pingallHosts( main, hostNames )
+        pingTemp = pingallHosts( main, hostNames )
+        pingResult = pingResult and pingTemp
+        if pingTemp:
+            main.assertReturnString += 'Link Down Pingall Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Pingall Failed\n'
 
-        intentResult = checkIntentState( main, intentsId )
+        # Check intent state
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Down Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Intent State Failed\n'
 
         # Checks ONOS state in link down
         if linkDownResult and topoResult and pingResult and intentResult:
@@ -863,6 +1032,11 @@
 
         # link up
         linkUpResult = link( main, sw1, sw2, "up" )
+        if linkUpResult:
+            main.assertReturnString += 'Link Up Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Failed\n'
+
         time.sleep( main.rerouteSleep )
 
         # Check flows count in each node
@@ -872,11 +1046,26 @@
 
         # Check OnosTopology
         topoResult = checkTopology( main, main.numLinks )
+        if topoResult:
+            main.assertReturnString += 'Link Up Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Topology State Failed\n'
 
         # Ping hosts
-        pingResult = pingResult and pingallHosts( main, hostNames )
+        pingTemp = pingallHosts( main, hostNames )
+        pingResult = pingResult and pingTemp
+        if pingTemp:
+            main.assertReturnString += 'Link Up Pingall Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Pingall Failed\n'
 
-        intentResult = checkIntentState( main, intentsId )
+        # Check Intents
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Up Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Intent State Failed\n'
 
         # Checks ONOS state in link up
         if linkUpResult and topoResult and pingResult and intentResult:
@@ -886,6 +1075,10 @@
 
     # Remove all intents
     removeIntentResult = removeAllIntents( main, intentsId )
+    if removeIntentResult:
+        main.assertReturnString += 'Remove Intents Passed'
+    else:
+        main.assertReturnString += 'Remove Intents Failed'
 
     stepResult = pingResult and linkDownResult and linkUpResult \
                  and intentResult and removeIntentResult
@@ -1059,7 +1252,7 @@
                                             tcpSrc="",
                                             tcpDst="" ) )
 
-    pingResult = pingallHosts( main, hostNames )
+    pingTemp = pingallHosts( main, hostNames )
 
     # Check intents state
     time.sleep( main.checkIntentSleep )
@@ -1075,15 +1268,25 @@
     checkFlowsState( main )
 
     # Ping hosts
-    pingResult = pingResult and pingallHosts( main, hostNames )
+    pingTemp = pingallHosts( main, hostNames )
+
     # Ping hosts again...
-    pingResult = pingResult and pingallHosts( main, hostNames )
+    pingTemp = pingallHosts( main, hostNames )
+    pingResult = pingResult and pingTemp
+    if pingTemp:
+        main.assertReturnString += 'Initial Pingall Passed\n'
+    else:
+        main.assertReturnString += 'Initial Pingall Failed\n'
 
     # Test rerouting if these variables exist
     if sw1 and sw2 and expectedLink:
         # link down
         linkDownResult = link( main, sw1, sw2, "down" )
-        intentResult = intentResult and checkIntentState( main, intentsId )
+
+        if linkDownResult:
+            main.assertReturnString += 'Link Down Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Failed\n'
 
         # Check flows count in each node
         checkFlowsCount( main )
@@ -1092,11 +1295,26 @@
 
         # Check OnosTopology
         topoResult = checkTopology( main, expectedLink )
+        if topoResult:
+            main.assertReturnString += 'Link Down Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Topology State Failed\n'
 
         # Ping hosts
-        pingResult = pingResult and pingallHosts( main, hostNames )
+        pingTemp = pingallHosts( main, hostNames )
+        pingResult = pingResult and pingTemp
+        if pingTemp:
+            main.assertReturnString += 'Link Down Pingall Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Pingall Failed\n'
 
-        intentResult = checkIntentState( main, intentsId )
+        # Check intent state
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Down Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Down Intent State Failed\n'
 
         # Checks ONOS state in link down
         if linkDownResult and topoResult and pingResult and intentResult:
@@ -1106,6 +1324,11 @@
 
         # link up
         linkUpResult = link( main, sw1, sw2, "up" )
+        if linkUpResult:
+            main.assertReturnString += 'Link Up Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Failed\n'
+
         time.sleep( main.rerouteSleep )
 
         # Check flows count in each node
@@ -1115,11 +1338,26 @@
 
         # Check OnosTopology
         topoResult = checkTopology( main, main.numLinks )
+        if topoResult:
+            main.assertReturnString += 'Link Up Topology State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Topology State Failed\n'
 
         # Ping hosts
-        pingResult = pingResult and pingallHosts( main, hostNames )
+        pingTemp = pingallHosts( main, hostNames )
+        pingResult = pingResult and pingTemp
+        if pingTemp:
+            main.assertReturnString += 'Link Up Pingall Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Pingall Failed\n'
 
-        intentResult = checkIntentState( main, intentsId )
+        # Check Intents
+        intentTemp = checkIntentState( main, intentsId )
+        intentResult = intentResult and intentTemp
+        if intentTemp:
+            main.assertReturnString += 'Link Up Intent State Passed\n'
+        else:
+            main.assertReturnString += 'Link Up Intent State Failed\n'
 
         # Checks ONOS state in link up
         if linkUpResult and topoResult and pingResult and intentResult:
@@ -1129,6 +1367,10 @@
 
     # Remove all intents
     removeIntentResult = removeAllIntents( main, intentsId )
+    if removeIntentResult:
+        main.assertReturnString += 'Remove Intents Passed'
+    else:
+        main.assertReturnString += 'Remove Intents Failed'
 
     stepResult = pingResult and linkDownResult and linkUpResult \
                  and intentResult and removeIntentResult
@@ -1226,6 +1468,7 @@
         main.log.info( itemName + ": Intents are installed correctly" )
     else:
         # Wait for at least 5 second before checking the intents again
+        main.log.error( "Intents are not installed correctly. Waiting 5 sec" )
         time.sleep( 5 )
         results = []
         # Second check of intents since some of the intents may be in
@@ -1236,6 +1479,7 @@
             results.append( tempResult )
         if all( result == main.TRUE for result in results ):
             main.log.info( itemName + ": Intents are installed correctly" )
+            intentResult = main.TRUE
         else:
             main.log.error( itemName + ": Intents are NOT installed correctly" )
             intentResult = main.FALSE
diff --git a/TestON/tests/FUNCintent/Dependency/newFuncTopo.py b/TestON/tests/FUNCintent/Dependency/newFuncTopo.py
index 5edf7f7..df808a7 100755
--- a/TestON/tests/FUNCintent/Dependency/newFuncTopo.py
+++ b/TestON/tests/FUNCintent/Dependency/newFuncTopo.py
@@ -15,19 +15,20 @@
 from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
 
 class VLANHost( Host ):
-    def config( self, vlan=100, **params ):
+    def config( self, vlan=100, v6Addr='3000::1/64', **params ):
         r = super( Host, self ).config( **params )
         intf = self.defaultIntf()
         self.cmd( 'ifconfig %s inet 0' % intf )
         self.cmd( 'vconfig add %s %d' % ( intf, vlan ) )
         self.cmd( 'ifconfig %s.%d inet %s' % ( intf, vlan, params['ip'] ) )
+        self.cmd( 'ip -6 addr add %s dev %s.%d' % ( v6Addr, intf, vlan ) )
         newName = '%s.%d' % ( intf, vlan )
         intf.name = newName
         self.nameToIntf[ newName ] = intf
         return r
 
 class IPv6Host( Host ):
-    def config( self, v6Addr='1000:1/64', **params ):
+    def config( self, v6Addr='1000::1/64', **params ):
         r = super( Host, self ).config( **params )
         intf = self.defaultIntf()
         self.cmd( 'ifconfig %s inet 0' % intf )
@@ -47,42 +48,51 @@
         # Initialize topology
         Topo.__init__( self )
         # Switch S5 Hosts
+        # IPv4 only Host
         host1=self.addHost( 'h1', ip='10.1.0.2/24' )
+        # IPv6 only Host
         host2=self.addHost( 'h2', cls=IPv6Host, v6Addr='1000::2/64' )
+        # Dual Stack Host
         host3=self.addHost( 'h3', ip='10.1.0.3/24', cls=dualStackHost, v6Addr='2000::2/64' )
-        #VLAN hosts
-        host4=self.addHost( 'h4', ip='100.1.0.2/24', cls=VLANHost, vlan=100 )
-        host5=self.addHost( 'h5', ip='200.1.0.2/24', cls=VLANHost, vlan=200 )
-        #VPN-1 and VPN-2 Hosts
+        # VLAN hosts
+        host4=self.addHost( 'h4', ip='100.1.0.2/24', cls=VLANHost, vlan=100, v6Addr='3000::2/64' )
+        host5=self.addHost( 'h5', ip='200.1.0.2/24', cls=VLANHost, vlan=200, v6Addr='4000::2/64' )
+        # VPN-1 and VPN-2 Hosts
         host6=self.addHost( 'h6', ip='11.1.0.2/24' )
         host7=self.addHost( 'h7', ip='12.1.0.2/24' )
-        #Multicast Sender
+        # Multicast Sender
         host8=self.addHost( 'h8', ip='10.1.0.4/24' )
 
         # Switch S6 Hosts
+        # IPv4 only Host
         host9=self.addHost( 'h9', ip='10.1.0.5/24' )
+        # IPv6 only Host
         host10=self.addHost( 'h10', cls=IPv6Host, v6Addr='1000::3/64' )
+        # Dual Stack Host
         host11=self.addHost( 'h11', ip='10.1.0.6/24', cls=dualStackHost, v6Addr='2000::3/64' )
-        #VLAN hosts
-        host12=self.addHost( 'h12', ip='100.1.0.3/24', cls=VLANHost, vlan=100 )
-        host13=self.addHost( 'h13', ip='200.1.0.3/24', cls=VLANHost, vlan=200 )
-        #VPN-1 and VPN-2 Hosts
+        # VLAN hosts
+        host12=self.addHost( 'h12', ip='100.1.0.3/24', cls=VLANHost, vlan=100, v6Addr='3000::3/64' )
+        host13=self.addHost( 'h13', ip='200.1.0.3/24', cls=VLANHost, vlan=200, v6Addr='4000::3/64' )
+        # VPN-1 and VPN-2 Hosts
         host14=self.addHost( 'h14', ip='11.1.0.3/24' )
         host15=self.addHost( 'h15', ip='12.1.0.3/24' )
-        #Multicast Receiver
+        # Multicast Receiver
         host16=self.addHost( 'h16', ip='10.1.0.7/24' )
 
         # Switch S7 Hosts
+        # IPv4 only Host
         host17=self.addHost( 'h17', ip='10.1.0.8/24' )
+        # IPv6 only Host
         host18=self.addHost( 'h18', cls=IPv6Host, v6Addr='1000::4/64' )
+        # Dual Stack Host
         host19=self.addHost( 'h19', ip='10.1.0.9/24', cls=dualStackHost, v6Addr='2000::4/64' )
-        #VLAN hosts
-        host20=self.addHost( 'h20', ip='100.1.0.4/24', cls=VLANHost, vlan=100 )
-        host21=self.addHost( 'h21', ip='200.1.0.4/24', cls=VLANHost, vlan=200 )
-        #VPN-1 and VPN-2 Hosts
+        # VLAN hosts
+        host20=self.addHost( 'h20', ip='100.1.0.4/24', cls=VLANHost, vlan=100, v6Addr='3000::4/64' )
+        host21=self.addHost( 'h21', ip='200.1.0.4/24', cls=VLANHost, vlan=200, v6Addr='4000::4/64' )
+        # VPN-1 and VPN-2 Hosts
         host22=self.addHost( 'h22', ip='11.1.0.4/24' )
         host23=self.addHost( 'h23', ip='12.1.0.4/24' )
-        #Multicast Receiver
+        # Multicast Receiver
         host24=self.addHost( 'h24', ip='10.1.0.10/24' )
 
         s1 = self.addSwitch( 's1' )
diff --git a/TestON/tests/FUNCintent/FUNCintent.py b/TestON/tests/FUNCintent/FUNCintent.py
index 4dab42c..483b2b4 100644
--- a/TestON/tests/FUNCintent/FUNCintent.py
+++ b/TestON/tests/FUNCintent/FUNCintent.py
@@ -56,6 +56,7 @@
             main.hostsData = {}
             main.CLIs = []
             main.ONOSip = []
+            main.assertReturnString = ''  # Assembled assert return string
 
             main.ONOSip = main.ONOSbench.getOnosIps()
             print main.ONOSip
@@ -454,6 +455,7 @@
                                         "to controller",
                                  onfail="Failed to assign switches to " +
                                         "controller" )
+
     def CASE13( self, main ):
         """
             Discover all hosts and store its data to a dictionary
@@ -533,6 +535,7 @@
                                 + " OVS running in Mininet"
 
         main.step( "IPV4: Add host intents between h1 and h9" )
+        main.assertReturnString = "Assertion Result for IPV4 host intent with mac addresses\n"
         stepResult = main.TRUE
         stepResult = main.intentFunction.hostIntent( main,
                                               onosNode='0',
@@ -544,15 +547,13 @@
                                               sw1='s5',
                                               sw2='s2',
                                               expectedLink=18 )
-
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="IPV4: Host intent test successful " +
-                                        "between two IPV4 hosts",
-                                 onfail="IPV4: Host intent test failed " +
-                                        "between two IPV4 hosts")
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString)
 
         main.step( "DUALSTACK1: Add host intents between h3 and h11" )
+        main.assertReturnString = "Assertion Result for dualstack IPV4 with MAC addresses\n"
         stepResult = main.TRUE
         stepResult = main.intentFunction.hostIntent( main,
                                               name='DUALSTACK',
@@ -566,15 +567,11 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="DUALSTACK: Host intent test " +
-                                        "successful between two " +
-                                        "dual stack host using IPV4",
-                                 onfail="DUALSTACK: Host intent test " +
-                                        "failed between two" +
-                                        "dual stack host using IPV4" )
-
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         main.step( "DUALSTACK2: Add host intents between h1 and h11" )
+        main.assertReturnString = "Assertion Result for dualstack2 host intent\n"
         stepResult = main.TRUE
         stepResult = main.intentFunction.hostIntent( main,
                                               name='DUALSTACK2',
@@ -586,14 +583,11 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="DUALSTACK2: Host intent test " +
-                                        "successful between two " +
-                                        "dual stack host using IPV4",
-                                 onfail="DUALSTACK2: Host intent test " +
-                                        "failed between two" +
-                                        "dual stack host using IPV4" )
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         main.step( "1HOP: Add host intents between h1 and h3" )
+        main.assertReturnString = "Assertion Result for 1HOP for IPV4 same switch\n"
         stepResult = main.TRUE
         stepResult = main.intentFunction.hostIntent( main,
                                               name='1HOP',
@@ -602,14 +596,11 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="1HOP: Host intent test " +
-                                        "successful between two " +
-                                        "host using IPV4 in the same switch",
-                                 onfail="1HOP: Host intent test " +
-                                        "failed between two" +
-                                        "host using IPV4 in the same switch" )
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         main.step( "VLAN1: Add vlan host intents between h4 and h12" )
+        main.assertReturnString = "Assertion Result vlan IPV4\n"
         stepResult = main.TRUE
         stepResult = main.intentFunction.hostIntent( main,
                                               name='VLAN1',
@@ -623,14 +614,11 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="VLAN1: Host intent test " +
-                                        "successful between two " +
-                                        "host using IPV4 in the same VLAN",
-                                 onfail="VLAN1: Host intent test " +
-                                        "failed between two" +
-                                        "host using IPV4 in the same VLAN" )
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         main.step( "VLAN2: Add inter vlan host intents between h13 and h20" )
+        main.assertReturnString = "Assertion Result different VLAN negative test\n"
         stepResult = main.TRUE
         stepResult = main.intentFunction.hostIntent( main,
                                               name='VLAN2',
@@ -639,12 +627,8 @@
 
         utilities.assert_equals( expect=main.FALSE,
                                  actual=stepResult,
-                                 onpass="VLAN2: Host intent negative test " +
-                                        "successful between two " +
-                                        "host using IPV4 in different VLAN",
-                                 onfail="VLAN2: Host intent negative test " +
-                                        "failed between two" +
-                                        "host using IPV4 in different VLAN" )
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
 
         intentLeadersNew = main.CLIs[ 0 ].leaderCandidates()
@@ -697,6 +681,7 @@
 
         # No option point intents
         main.step( "NOOPTION: Add point intents between h1 and h9" )
+        main.assertReturnString = "Assertion Result for NOOPTION point intent\n"
         stepResult = main.TRUE
         stepResult = main.intentFunction.pointIntent(
                                        main,
@@ -711,13 +696,12 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="NOOPTION: Point intent test " +
-                                        "successful using no match action",
-                                 onfail="NOOPTION: Point intent test " +
-                                        "failed using no match action" )
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         stepResult = main.TRUE
         main.step( "IPV4: Add point intents between h1 and h9" )
+        main.assertReturnString = "Assertion Result for IPV4 point intent\n"
         stepResult = main.intentFunction.pointIntent(
                                        main,
                                        name="IPV4",
@@ -743,14 +727,10 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="IPV4: Point intent test " +
-                                        "successful using IPV4 type with " +
-                                        "MAC addresses",
-                                 onfail="IPV4: Point intent test " +
-                                        "failed using IPV4 type with " +
-                                        "MAC addresses" )
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
         main.step( "IPV4_2: Add point intents between h1 and h9" )
-        stepResult = main.TRUE
+        main.assertReturnString = "Assertion Result for IPV4 no mac address point intents\n"
         stepResult = main.intentFunction.pointIntent(
                                        main,
                                        name="IPV4_2",
@@ -769,15 +749,11 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="IPV4_2: Point intent test " +
-                                        "successful using IPV4 type with " +
-                                        "no MAC addresses",
-                                 onfail="IPV4_2: Point intent test " +
-                                        "failed using IPV4 type with " +
-                                        "no MAC addresses" )
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         main.step( "SDNIP-ICMP: Add point intents between h1 and h9" )
-        stepResult = main.TRUE
+        main.assertReturnString = "Assertion Result for SDNIP-ICMP IPV4 using TCP point intents\n"
         mac1 = main.hostsData[ 'h1' ][ 'mac' ]
         mac2 = main.hostsData[ 'h9' ][ 'mac' ]
         try:
@@ -810,15 +786,11 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="SDNIP-ICMP: Point intent test " +
-                                        "successful using IPV4 type with " +
-                                        "IP protocol TCP enabled",
-                                 onfail="SDNIP-ICMP: Point intent test " +
-                                        "failed using IPV4 type with " +
-                                        "IP protocol TCP enabled" )
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         main.step( "SDNIP-TCP: Add point intents between h1 and h9" )
-        stepResult = main.TRUE
+        main.assertReturnString = "Assertion Result for SDNIP-TCP IPV4 using ICMP point intents\n"
         mac1 = main.hostsData[ 'h1' ][ 'mac' ]
         mac2 = main.hostsData[ 'h9' ][ 'mac' ]
         ip1 = str( main.hostsData[ 'h1' ][ 'ipAddresses' ][ 0 ] ) + "/32"
@@ -845,15 +817,11 @@
 
         utilities.assert_equals( expect=main.TRUE,
                              actual=stepResult,
-                                 onpass="SDNIP-TCP: Point intent test " +
-                                        "successful using IPV4 type with " +
-                                        "IP protocol ICMP enabled",
-                                 onfail="SDNIP-TCP: Point intent test " +
-                                        "failed using IPV4 type with " +
-                                        "IP protocol ICMP enabled" )
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
-        main.step( "DUALSTACK1: Add point intents between h1 and h9" )
-        stepResult = main.TRUE
+        main.step( "DUALSTACK1: Add point intents between h3 and h11" )
+        main.assertReturnString = "Assertion Result for Dualstack1 IPV4 with mac address point intents\n"
         stepResult = main.intentFunction.pointIntent(
                                        main,
                                        name="DUALSTACK1",
@@ -879,15 +847,11 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="DUALSTACK1: Point intent test " +
-                                        "successful using IPV4 type with " +
-                                        "MAC addresses",
-                                 onfail="DUALSTACK1: Point intent test " +
-                                        "failed using IPV4 type with " +
-                                        "MAC addresses" )
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         main.step( "VLAN: Add point intents between h5 and h21" )
-        stepResult = main.TRUE
+        main.assertReturnString = "Assertion Result for VLAN IPV4 with mac address point intents\n"
         stepResult = main.intentFunction.pointIntent(
                                        main,
                                        name="VLAN",
@@ -913,15 +877,11 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="VLAN1: Point intent test " +
-                                        "successful using IPV4 type with " +
-                                        "MAC addresses",
-                                 onfail="VLAN1: Point intent test " +
-                                        "failed using IPV4 type with " +
-                                        "MAC addresses" )
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         main.step( "1HOP: Add point intents between h1 and h3" )
-        stepResult = main.TRUE
+        main.assertReturnString = "Assertion Result for 1HOP IPV4 with no mac address point intents\n"
         stepResult = main.intentFunction.hostIntent( main,
                                               name='1HOP',
                                               host1='h1',
@@ -929,12 +889,8 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="1HOP: Point intent test " +
-                                        "successful using IPV4 type with " +
-                                        "no MAC addresses",
-                                 onfail="1HOP: Point intent test " +
-                                        "failed using IPV4 type with " +
-                                        "no MAC addresses" )
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         main.intentFunction.report( main )
 
@@ -1006,7 +962,7 @@
         #                                 " with no match action" )
 
         main.step( "IPV4: Add single point to multi point intents" )
-        stepResult = main.TRUE
+        main.assertReturnString = "Assertion results for IPV4 single to multi point intent with IPV4 type and MAC addresses\n"
         stepResult = main.intentFunction.singleToMultiIntent(
                                          main,
                                          name="IPV4",
@@ -1026,15 +982,11 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="IPV4: Successfully added single "
-                                        + " point to multi point intents" +
-                                        " with IPV4 type and MAC addresses",
-                                 onfail="IPV4: Failed to add single point"
-                                        + " point to multi point intents" +
-                                        " with IPV4 type and MAC addresses" )
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         main.step( "IPV4_2: Add single point to multi point intents" )
-        stepResult = main.TRUE
+        main.assertReturnString = "Assertion results for IPV4 single to multi point intent with IPV4 type and no MAC addresses\n"
         hostNames = [ 'h8', 'h16', 'h24' ]
         stepResult = main.intentFunction.singleToMultiIntent(
                                          main,
@@ -1045,15 +997,11 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="IPV4_2: Successfully added single "
-                                        + " point to multi point intents" +
-                                        " with IPV4 type and no MAC addresses",
-                                 onfail="IPV4_2: Failed to add single point"
-                                        + " point to multi point intents" +
-                                        " with IPV4 type and no MAC addresses" )
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         main.step( "VLAN: Add single point to multi point intents" )
-        stepResult = main.TRUE
+        main.assertReturnString = "Assertion results for IPV4 single to multi point intent with IPV4 type and MAC addresses in the same VLAN\n"
         hostNames = [ 'h4', 'h12', 'h20' ]
         devices = [ 'of:0000000000000005/4', 'of:0000000000000006/4', \
                     'of:0000000000000007/4' ]
@@ -1077,14 +1025,8 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="VLAN: Successfully added single "
-                                        + " point to multi point intents" +
-                                        " with IPV4 type and MAC addresses" +
-                                        " in the same VLAN",
-                                 onfail="VLAN: Failed to add single point"
-                                        + " point to multi point intents" +
-                                        " with IPV4 type and MAC addresses" +
-                                        " in the same VLAN")
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         main.intentFunction.report( main )
 
@@ -1156,7 +1098,7 @@
         #                                 " with no match action" )
 
         main.step( "IPV4: Add multi point to single point intents" )
-        stepResult = main.TRUE
+        main.assertReturnString = "Assertion results for IPV4 multi to single point intent with IPV4 type and MAC addresses\n"
         stepResult = main.intentFunction.multiToSingleIntent(
                                          main,
                                          name="IPV4",
@@ -1176,15 +1118,11 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="IPV4: Successfully added multi point"
-                                        + " to single point intents" +
-                                        " with IPV4 type and MAC addresses",
-                                 onfail="IPV4: Failed to add multi point" +
-                                        " to single point intents" +
-                                        " with IPV4 type and MAC addresses" )
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         main.step( "IPV4_2: Add multi point to single point intents" )
-        stepResult = main.TRUE
+        main.assertReturnString = "Assertion results for IPV4 multi to single point intent with IPV4 type and no MAC addresses\n"
         hostNames = [ 'h8', 'h16', 'h24' ]
         stepResult = main.intentFunction.multiToSingleIntent(
                                          main,
@@ -1195,15 +1133,11 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="IPV4_2: Successfully added multi point"
-                                        + " to single point intents" +
-                                        " with IPV4 type and no MAC addresses",
-                                 onfail="IPV4_2: Failed to add multi point" +
-                                        " to single point intents" +
-                                        " with IPV4 type and no MAC addresses" )
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         main.step( "VLAN: Add multi point to single point intents" )
-        stepResult = main.TRUE
+        main.assertReturnString = "Assertion results for IPV4 multi to single point intent with IPV4 type and no MAC addresses in the same VLAN\n"
         hostNames = [ 'h5', 'h13', 'h21' ]
         devices = [ 'of:0000000000000005/5', 'of:0000000000000006/5', \
                     'of:0000000000000007/5' ]
@@ -1227,16 +1161,13 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="VLAN: Successfully added multi point"
-                                        + " to single point intents" +
-                                        " with IPV4 type and MAC addresses" +
-                                        " in the same VLAN",
-                                 onfail="VLAN: Failed to add multi point" +
-                                        " to single point intents" )
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
     def CASE5000( self, main ):
         """
-        Will add description in next patch set
+        Tests Host Mobility
+        Modifies the topology location of h1
         """
         assert main, "There is no main"
         assert main.CLIs, "There is no main.CLIs"
@@ -1257,13 +1188,13 @@
         utilities.assert_equals( expect="of:0000000000000006",
                                  actual=h1PostMove,
                                  onpass="Mobility: Successfully moved h1 to s6",
-                                 onfail="Mobility: Failed to moved h1 to s6" +
+                                 onfail="Mobility: Failed to move h1 to s6" +
                                         " to single point intents" +
                                         " with IPV4 type and MAC addresses" +
                                         " in the same VLAN" )
 
         main.step( "IPV4: Add host intents between h1 and h9" )
-        stepResult = main.TRUE
+        main.assertReturnString = "Assert result for IPV4 host intent between h1, moved, and h9\n"
         stepResult = main.intentFunction.hostIntent( main,
                                               onosNode='0',
                                               name='IPV4',
@@ -1274,9 +1205,7 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="IPV4: Host intent test successful " +
-                                        "between two IPV4 hosts",
-                                 onfail="IPV4: Host intent test failed " +
-                                        "between two IPV4 hosts")
+                                 onpass=main.assertReturnString,
+                                 onfail=main.assertReturnString )
 
         main.intentFunction.report( main )
diff --git a/TestON/tests/FUNCintentRest/FUNCintentRest.params b/TestON/tests/FUNCintentRest/FUNCintentRest.params
index 4158f33..058b57a 100644
--- a/TestON/tests/FUNCintentRest/FUNCintentRest.params
+++ b/TestON/tests/FUNCintentRest/FUNCintentRest.params
@@ -3,7 +3,8 @@
     # 1 - Variable initialization and optional pull and build ONOS package
     # 2 - Install ONOS
     # 9 - Report logs
-    # 11 - Start Mininet
+    # 10 - Start Mininet with Openflow 1.0
+    # 11 - Start Mininet with Openflow 1.3
     # 12 - Assign switch to controller
     # 13 - Create a data of hosts information
     # 14 - Stop Mininet
@@ -11,11 +12,12 @@
     # 2000 - Test point intents
     # 3000 - Test single to multi point intents
     # 4000 - Test multi to single point intents
+    # 5000 - Test host mobility
 
-    <testcases>1,2,10,12,13,1000,2000</testcases>
+    <testcases>1,[2,10,12,13,1000,2000,14],[2,11,12,13,1000,2000,14]</testcases>
 
     <SCALE>
-        <size>1,3</size>
+        <size>1,1</size>
     </SCALE>
 
     <DEPENDENCY>
diff --git a/TestON/tests/FUNCovsdbtest/FUNCovsdbtest.py b/TestON/tests/FUNCovsdbtest/FUNCovsdbtest.py
index 95e90fd..3c76596 100644
--- a/TestON/tests/FUNCovsdbtest/FUNCovsdbtest.py
+++ b/TestON/tests/FUNCovsdbtest/FUNCovsdbtest.py
@@ -384,7 +384,8 @@
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
                                  onpass="ovsdb node 1 manager is " + str( response ) ,
-                                 onfail="ovsdb node 1 manager check failed" )
+                                 onfail="ovsdb node 1 manager check failed\n" +\
+                                 str( main.OVSDB1.show() ) )
 
         main.step( "Check ovsdb node 2 manager is " + str( ctrlip ) )
         response = main.OVSDB2.getManager()
@@ -395,7 +396,8 @@
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
                                  onpass="ovsdb node 2 manager is " + str( response ) ,
-                                 onfail="ovsdb node 2 manager check failed" )
+                                 onfail="ovsdb node 2 manager check failed\n" +\
+                                 str( main.OVSDB2.show() ) )
 
         main.step( "Check ovsdb node 1 bridge br-int controller set to " + str( ctrlip ) )
         response = main.OVSDB1.getController( "br-int" )
@@ -408,7 +410,7 @@
                                  onpass="Check ovsdb node 1 bridge br-int controller set to " +\
                                   str( ctrlip ) + " sucess",
                                  onfail="Check ovsdb node 1 bridge br-int controller set to " +\
-                                  str( ctrlip ) + " failed" )
+                                  str( ctrlip ) + " failed\n" + str( main.OVSDB1.show() ) )
 
         main.step( "Check ovsdb node 2 bridge br-int controller set to  " + str( ctrlip ) )
         response = main.OVSDB2.getController( "br-int" )
@@ -421,7 +423,7 @@
                                  onpass="Check ovsdb node 2 bridge br-int controller set to " +\
                                   str( ctrlip ) + " sucess",
                                  onfail="Check ovsdb node 2 bridge br-int controller set to " +\
-                                  str( ctrlip ) + " failed" )
+                                  str( ctrlip ) + " failed\n" + str( main.OVSDB2.show()) )
 
         main.step( "Check onoscli devices have ovs " + str( OVSDB1Ip ) )
         response = main.ONOScli1.devices()
diff --git a/TestON/tests/FUNCvirNetNB/FUNCvirNetNB.py b/TestON/tests/FUNCvirNetNB/FUNCvirNetNB.py
index 0b35b0e..fd828e0 100644
--- a/TestON/tests/FUNCvirNetNB/FUNCvirNetNB.py
+++ b/TestON/tests/FUNCvirNetNB/FUNCvirNetNB.py
@@ -407,12 +407,12 @@
         Getstatus, result = main.ONOSrest.send( ctrlip, port, network.id, path+'networks/',
                                                 'GET', None, None )
         utilities.assert_equals(
-                expect='The tenantNetwork does not exists',
+                expect='Network is not found',
                 actual=result,
                 onpass="Get Success",
                 onfail="Get Failed " + str( Getstatus ) + str( result ) )
 
-        if result != 'The tenantNetwork does not exists':
+        if result != 'Network is not found':
             main.log.error( "Delete Network failed" )
 
     def CASE5( self, main ):
@@ -678,12 +678,12 @@
         Getstatus, result = main.ONOSrest.send( ctrlip, port, subnet.id, path + 'subnets/',
                                                  'GET', None, None )
         utilities.assert_equals(
-                expect='The subnet does not exists',
+                expect='Subnet is not found',
                 actual=result,
                 onpass="Get Subnet Success",
                 onfail="Get Subnet Failed " + str( Getstatus ) + str( result ) )
 
-        if result != 'The subnet does not exists':
+        if result != 'Subnet is not found':
             main.log.error( "Delete Subnet failed" )
 
     def CASE8( self, main ):
@@ -1001,12 +1001,12 @@
         Getstatus, result = main.ONOSrest.send( ctrlip, httpport, port.id, path + 'ports/',
                                                  'GET', None, None )
         utilities.assert_equals(
-                expect='The virtualPort does not exists',
+                expect='VirtualPort is not found',
                 actual=result,
                 onpass="Get Port Success",
                 onfail="Get Port Failed " + str( Getstatus ) + "," + str( result ) )
 
-        if result != 'The virtualPort does not exists':
+        if result != 'VirtualPort is not found':
             main.log.error( "Delete Port failed" )
 
         main.step( "Clean Data via HTTP" )
@@ -1191,4 +1191,4 @@
                 expect='500',
                 actual=Poststatus,
                 onpass="The Json is wrong,can't post",
-                onfail="Wrong Json can post successfully" )
\ No newline at end of file
+                onfail="Wrong Json can post successfully" )
diff --git a/TestON/tests/HAclusterRestart/HAclusterRestart.params b/TestON/tests/HAclusterRestart/HAclusterRestart.params
index f10636e..4626c39 100644
--- a/TestON/tests/HAclusterRestart/HAclusterRestart.params
+++ b/TestON/tests/HAclusterRestart/HAclusterRestart.params
@@ -40,7 +40,7 @@
         <port7>6653</port7>
     </CTRL>
     <BACKUP>
-        <ENABLED>True</ENABLED>
+        <ENABLED>False</ENABLED>
         <TESTONUSER>admin</TESTONUSER>
         <TESTONIP>10.128.30.9</TESTONIP>
     </BACKUP>
diff --git a/TestON/tests/HAminorityRestart/HAminorityRestart.py b/TestON/tests/HAminorityRestart/HAminorityRestart.py
index d175fd7..ca8a194 100644
--- a/TestON/tests/HAminorityRestart/HAminorityRestart.py
+++ b/TestON/tests/HAminorityRestart/HAminorityRestart.py
@@ -48,6 +48,7 @@
         start tcpdump
         """
         import imp
+        import pexpect
         main.log.info( "ONOS HA test: Restart minority of ONOS nodes - " +
                          "initialization" )
         main.case( "Setting up test environment" )
@@ -189,6 +190,16 @@
         main.log.wiki(graphs)
 
         main.step( "Creating ONOS package" )
+        # copy gen-partions file to ONOS
+        # NOTE: this assumes TestON and ONOS are on the same machine
+        srcFile = main.testDir + "/" + main.TEST + "/dependencies/onos-gen-partitions"
+        dstDir = main.ONOSbench.home + "/tools/test/bin/onos-gen-partitions"
+        cpResult = main.ONOSbench.secureCopy( main.ONOSbench.user_name,
+                                              main.ONOSbench.ip_address,
+                                              srcFile,
+                                              dstDir,
+                                              pwd=main.ONOSbench.pwd,
+                                              direction="from" )
         packageResult = main.ONOSbench.onosPackage()
         utilities.assert_equals( expect=main.TRUE, actual=packageResult,
                                  onpass="ONOS package successful",
@@ -203,6 +214,19 @@
         utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
                                  onpass="ONOS install successful",
                                  onfail="ONOS install failed" )
+        # clean up gen-partitions file
+        try:
+            main.ONOSbench.handle.sendline( "cd " + main.ONOSbench.home )
+            main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
+            main.ONOSbench.handle.sendline( "git checkout -- tools/test/bin/onos-gen-partitions" )
+            main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
+            main.log.info( " Cleaning custom gen partitions file, response was: \n" +
+                           str( main.ONOSbench.handle.before ) )
+        except ( pexpect.TIMEOUT, pexpect.EOF ):
+            main.log.exception( "ONOSbench: pexpect exception found:" +
+                                main.ONOSbench.handle.before )
+            main.cleanup()
+            main.exit()
 
         main.step( "Checking if ONOS is up yet" )
         for i in range( 2 ):
@@ -1680,17 +1704,19 @@
             main.log.debug( "Checking logs for errors on " + node.name + ":" )
             main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
 
-        main.step( "Killing 3 ONOS nodes" )
+        n = len( main.nodes )  # Number of nodes
+        p = ( ( n + 1 ) / 2 ) + 1  # Number of partitions
+        main.kill = [ 0 ]  # ONOS node to kill, listed by index in main.nodes
+        if n > 3:
+            main.kill.append( p - 1 )
+            # NOTE: This only works for cluster sizes of 3,5, or 7.
+
+        main.step( "Killing " + str( len( main.kill ) ) + " ONOS nodes" )
         killTime = time.time()
-        # TODO: Randomize these nodes or base this on partitions
-        # TODO: use threads in this case
-        killResults = main.ONOSbench.onosKill( main.nodes[0].ip_address )
-        time.sleep( 10 )
-        killResults = killResults and\
-                      main.ONOSbench.onosKill( main.nodes[1].ip_address )
-        time.sleep( 10 )
-        killResults = killResults and\
-                      main.ONOSbench.onosKill( main.nodes[2].ip_address )
+        killResults = main.TRUE
+        for i in main.kill:
+            killResults = killResults and\
+                          main.ONOSbench.onosKill( main.nodes[i].ip_address )
         utilities.assert_equals( expect=main.TRUE, actual=killResults,
                                  onpass="ONOS Killed successfully",
                                  onfail="ONOS kill NOT successful" )
@@ -1699,21 +1725,20 @@
         count = 0
         onosIsupResult = main.FALSE
         while onosIsupResult == main.FALSE and count < 10:
-            onos1Isup = main.ONOSbench.isup( main.nodes[0].ip_address )
-            onos2Isup = main.ONOSbench.isup( main.nodes[1].ip_address )
-            onos3Isup = main.ONOSbench.isup( main.nodes[2].ip_address )
-            onosIsupResult = onos1Isup and onos2Isup and onos3Isup
+            onosIsupResult = main.TRUE
+            for i in main.kill:
+                onosIsupResult = onosIsupResult and\
+                                 main.ONOSbench.isup( main.nodes[i].ip_address )
             count = count + 1
-        # TODO: if it becomes an issue, we can retry this step  a few times
         utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
                                  onpass="ONOS restarted successfully",
                                  onfail="ONOS restart NOT successful" )
 
         main.step( "Restarting ONOS main.CLIs" )
-        cliResult1 = main.ONOScli1.startOnosCli( main.nodes[0].ip_address )
-        cliResult2 = main.ONOScli2.startOnosCli( main.nodes[1].ip_address )
-        cliResult3 = main.ONOScli3.startOnosCli( main.nodes[2].ip_address )
-        cliResults = cliResult1 and cliResult2 and cliResult3
+        cliResults = main.TRUE
+        for i in main.kill:
+            cliResults = cliResults and\
+                         main.CLIs[i].startOnosCli( main.nodes[i].ip_address )
         utilities.assert_equals( expect=main.TRUE, actual=cliResults,
                                  onpass="ONOS cli restarted",
                                  onfail="ONOS cli did not restart" )
@@ -1722,17 +1747,6 @@
         # protocol has had time to work
         main.restartTime = time.time() - killTime
         main.log.debug( "Restart time: " + str( main.restartTime ) )
-        '''
-        # FIXME: revisit test plan for election with madan
-        # Rerun for election on restarted nodes
-        run1 = main.CLIs[0].electionTestRun()
-        run2 = main.CLIs[1].electionTestRun()
-        run3 = main.CLIs[2].electionTestRun()
-        runResults = run1 and run2 and run3
-        utilities.assert_equals( expect=main.TRUE, actual=runResults,
-                                 onpass="Reran for election",
-                                 onfail="Failed to rerun for election" )
-        '''
         # TODO: MAke this configurable. Also, we are breaking the above timer
         time.sleep( 60 )
         main.log.debug( main.CLIs[0].nodes( jsonFormat=False ) )
@@ -2052,11 +2066,12 @@
         main.step( "Leadership Election is still functional" )
         # Test of LeadershipElection
         leaderList = []
-        # FIXME: make sure this matches nodes that were restarted
-        restarted = [ main.nodes[0].ip_address, main.nodes[1].ip_address,
-                      main.nodes[2].ip_address ]
 
+        restarted = []
+        for i in main.kill:
+            restarted.append( main.nodes[i].ip_address )
         leaderResult = main.TRUE
+
         for cli in main.CLIs:
             leaderN = cli.electionTestLeader()
             leaderList.append( leaderN )
@@ -3409,23 +3424,7 @@
                                  onfail="Added counters are incorrect" )
 
         main.step( "Check counters are consistant across nodes" )
-        onosCounters = []
-        threads = []
-        for i in range( main.numCtrls ):
-            t = main.Thread( target=main.CLIs[i].counters,
-                             name="counters-" + str( i ) )
-            threads.append( t )
-            t.start()
-        for t in threads:
-            t.join()
-            onosCounters.append( t.result )
-        tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
-        if all( tmp ):
-            main.log.info( "Counters are consistent across all nodes" )
-            consistentCounterResults = main.TRUE
-        else:
-            main.log.error( "Counters are not consistent across all nodes" )
-            consistentCounterResults = main.FALSE
+        onosCounters, consistentCounterResults = main.Counters.consistentCheck()
         utilities.assert_equals( expect=main.TRUE,
                                  actual=consistentCounterResults,
                                  onpass="ONOS counters are consistent " +
@@ -3441,7 +3440,6 @@
                                  actual=incrementCheck,
                                  onpass="Added counters are correct",
                                  onfail="Added counters are incorrect" )
-
         # DISTRIBUTED SETS
         main.step( "Distributed Set get" )
         size = len( onosSet )
diff --git a/TestON/tests/HAminorityRestart/README b/TestON/tests/HAminorityRestart/README
new file mode 100644
index 0000000..a913f85
--- /dev/null
+++ b/TestON/tests/HAminorityRestart/README
@@ -0,0 +1,24 @@
+This test is designed to verify that an ONOS cluster behaves correctly when
+ONOS nodes die. Currently, we will kill nodes so that each raft partition will
+lose a member, but we make sure that there is always a majority of nodes
+available in each partition.
+
+As written, the test only supports an ONOS cluster of 3,5, or 7 nodes.
+This is because the test doesn't apply to a single node cluster, ONOS clusters
+should be deployed in odd numbers, and the partition generation and node
+killing scheme used doesn't give the same properties for clusters of more
+than 7 nodes. Namely, each partition won't have exactly one node killed.
+
+The gerneral structure for the test:
+- Startup
+- Assign switches
+- Verify ONOS state and functionality
+    - Device mastership
+    - Intents
+    - Leadership election
+    - Distributed Primitives
+- Kill some ONOS nodes
+- Verify ONOS state and functionality
+- Dataplane failures
+    - link down and up
+    - switch down and up
diff --git a/TestON/tests/HAminorityRestart/dependencies/Counters.py b/TestON/tests/HAminorityRestart/dependencies/Counters.py
index 21308c2..6614887 100644
--- a/TestON/tests/HAminorityRestart/dependencies/Counters.py
+++ b/TestON/tests/HAminorityRestart/dependencies/Counters.py
@@ -1,14 +1,19 @@
 def __init__( self ):
     self.default = ''
 
-def counterCheck( counterName, counterValue ):
+def consistentCheck():
     """
-    Add Text here
+    Checks that TestON counters are consistent across all nodes.
+
+    Returns the tuple (onosCounters, consistent)
+    - onosCounters is the parsed json output of the counters command on all nodes
+    - consistent is main.TRUE if all "TestON" counters are consitent across all
+        nodes or main.FALSE
     """
     import json
     correctResults = main.TRUE
     # Get onos counters results
-    onosCounters = []
+    onosCountersRaw = []
     threads = []
     for i in range( main.numCtrls ):
         t = main.Thread( target=main.CLIs[i].counters,
@@ -17,25 +22,58 @@
         t.start()
     for t in threads:
         t.join()
-        onosCounters.append( t.result )
-    tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
+        onosCountersRaw.append( t.result )
+    onosCounters = []
+    for i in range( main.numCtrls ):
+        try:
+            onosCounters.append( json.loads( onosCountersRaw[i] ) )
+        except ( ValueError, TypeError ):
+            main.log.error( "Could not parse counters response from ONOS" +
+                            str( i + 1 ) )
+            main.log.warn( repr( onosCountersRaw[ i ] ) )
+            return main.FALSE
+
+    testCounters = {}
+    # make a list of all the "TestON-*" counters in ONOS
+    # lookes like a dict whose keys are the name of the ONOS node and values
+    # are a list of the counters. I.E.
+    # { "ONOS1": [ {"name":"TestON-inMemory","value":56},
+    #              {"name":"TestON-Partitions","value":56} ]
+    # }
+    # NOTE: There is an assumtion that all nodes are active
+    #        based on the above for loops
+    for controller in enumerate( onosCounters ):
+        for dbType in controller[1]:
+            for dbName, items in dbType.iteritems():
+                for item in items:
+                    if 'TestON' in item['name']:
+                        node = 'ONOS' + str( controller[0] + 1 )
+                        try:
+                            testCounters[node].append( item )
+                        except KeyError:
+                            testCounters[node] = [ item ]
+    # compare the counters on each node
+    tmp = [ v == testCounters['ONOS1'] for k, v in testCounters.iteritems() ]
     if all( tmp ):
         consistent = main.TRUE
     else:
         consistent = main.FALSE
-        main.log.error( "ONOS nodes have different values for counters" )
-        for node in onosCounters:
-            main.log.debug( node )
+        main.log.error( "ONOS nodes have different values for counters:\n" +
+                        testCounters )
+    return ( onosCounters, consistent )
 
+def counterCheck( counterName, counterValue ):
+    """
+    Checks that TestON counters are consistent across all nodes and that
+    specified counter is in ONOS with the given value
+    """
+    import json
+    correctResults = main.TRUE
+    # Get onos counters results and consistentCheck
+    onosCounters, consistent = main.Counters.consistentCheck()
     # Check for correct values
     for i in range( main.numCtrls ):
-        try:
-            current = json.loads( onosCounters[i] )
-        except ( ValueError, TypeError ):
-            main.log.error( "Could not parse counters response from ONOS" +
-                            str( i + 1 ) )
-            main.log.warn( repr( onosCounters[ i ] ) )
-            return main.FALSE
+        current = onosCounters[i]
         onosValue = None
         try:
             for database in current:
diff --git a/TestON/tests/HAminorityRestart/dependencies/onos-gen-partitions b/TestON/tests/HAminorityRestart/dependencies/onos-gen-partitions
new file mode 100755
index 0000000..bf9a77b
--- /dev/null
+++ b/TestON/tests/HAminorityRestart/dependencies/onos-gen-partitions
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+'''
+  Generate the partitions json file from the $OC* environment variables
+
+  Usage: onos-gen-partitions [output file]
+  If output file is not provided, the json is written to stdout.
+'''
+
+from os import environ
+from collections import deque, OrderedDict
+import re
+import json
+import sys
+
+convert = lambda text: int(text) if text.isdigit() else text.lower()
+alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
+
+def get_OC_vars():
+  vars = []
+  for var in environ:
+    if re.match(r"OC[0-9]+", var):
+      vars.append(var)
+  return sorted(vars, key=alphanum_key)
+
+def get_nodes(vars, port=9876):
+  node = lambda k: { 'id': k, 'ip': k, 'tcpPort': port }
+  return [ node(environ[v]) for v in vars ]
+
+def generate_permutations(nodes, k):
+  l = deque(nodes)
+  perms = {}
+  for i in range(1, len(nodes)+1):
+    perms['p%d' % i] = list(l)[:k]
+    l.rotate(-1)
+  return OrderedDict(sorted(perms.iteritems(), key=lambda (k, v): alphanum_key(k)))
+
+def generate_permutations2(nodes, k):
+  l = deque(nodes)
+  perms = {}
+  for i in range(1, (len(nodes) + 1) / 2 + 1):
+    perms['p%d' % i] = list(l)[:k]
+    l.rotate(-2)
+  return OrderedDict(sorted(perms.iteritems(), key=lambda (k, v): alphanum_key(k)))
+
+
+if __name__ == '__main__':
+  vars = get_OC_vars()
+  nodes = get_nodes(vars)
+  partitions = generate_permutations2(nodes, 3)
+  data = {
+           'nodes': nodes,
+           'partitions': partitions
+         }
+  output = json.dumps(data, indent=4)
+
+  if len(sys.argv) == 2:
+    filename = sys.argv[1]
+    with open(filename, 'w') as f:
+      f.write(output)
+  else:
+    print output
diff --git a/TestON/tests/SCPFintentRerouteLat/SCPFintentRerouteLat.py b/TestON/tests/SCPFintentRerouteLat/SCPFintentRerouteLat.py
index 3b74dcf..0dafc51 100644
--- a/TestON/tests/SCPFintentRerouteLat/SCPFintentRerouteLat.py
+++ b/TestON/tests/SCPFintentRerouteLat/SCPFintentRerouteLat.py
@@ -170,7 +170,6 @@
         #from scipy import stats
 
         ts = time.time()
-        date = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d')
 
         sampleSize = int(main.params[ 'TEST' ][ 'sampleSize' ])
         warmUp = int(main.params[ 'TEST' ][ 'warmUp' ])
@@ -258,13 +257,24 @@
                         break
                     time.sleep(2)
 
+                if debug: main.log.debug("raw: " + raw)
+
                 temp = raw.splitlines()
-                for line in temp:
-                    if str(date) in line:
-                        temp = line
-                        break
+
+                if debug: main.log.debug("temp (after splitlines): " + str(temp))
+
+                # Since the string is deterministic the date is always the 3rd element.
+                # However, if the data were grepping for in the onos log changes then this will
+                # not work. This is why we print out the raw and temp string so we can visually
+                # check if everything is in the correct order. temp should like this:
+                # temp = ['/onos$ onos-ssh $OC1 cat /opt/onos/log/karaf.log | grep Top ', 
+                #         'ologyManager| tail -1', '2015-10-15 12:03:33,736 ... ]
+                temp = temp[2]
+
+                if debug: main.log.debug("temp (checking for date): " + str(temp))
 
                 cutTimestamp = (temp.split(" "))[0] + " " + (temp.split(" "))[1]
+
                 if debug: main.log.info("Cut timestamp: " + cutTimestamp)
 
                 #validate link count and flow count
diff --git a/TestON/tests/SCPFscaleTopo/Dependency/scaleTopoFunction.py b/TestON/tests/SCPFscaleTopo/Dependency/scaleTopoFunction.py
index 4965331..075f4f2 100644
--- a/TestON/tests/SCPFscaleTopo/Dependency/scaleTopoFunction.py
+++ b/TestON/tests/SCPFscaleTopo/Dependency/scaleTopoFunction.py
@@ -198,7 +198,7 @@
     switchList =  main.Mininet1.getSwitch()
     assignResult = main.Mininet1.assignSwController( sw=switchList,
                                                      ip=main.ONOSip[ 0 ],
-                                                     port=6653 )
+                                                     port=6633 )
 
     for sw in switchList:
         response = main.Mininet1.getSwController( sw )
diff --git a/TestON/tests/SCPFscaleTopo/Dependency/topo.py b/TestON/tests/SCPFscaleTopo/Dependency/topo.py
index b44e3fc..0dbb02d 100644
--- a/TestON/tests/SCPFscaleTopo/Dependency/topo.py
+++ b/TestON/tests/SCPFscaleTopo/Dependency/topo.py
@@ -12,7 +12,7 @@
     """
     devices = []
     threads = []
-    for i in range( main.numCtrls ):
+    for i in main.activeNodes:
         t = main.Thread( target=main.CLIs[i].devices,
                          name="devices-" + str( i ),
                          args=[ ] )
@@ -31,7 +31,7 @@
     hosts = []
     ipResult = main.TRUE
     threads = []
-    for i in range( main.numCtrls ):
+    for i in main.activeNodes:
         t = main.Thread( target=main.CLIs[i].hosts,
                          name="hosts-" + str( i ),
                          args=[ ] )
@@ -49,7 +49,7 @@
     """
     ports = []
     threads = []
-    for i in range( main.numCtrls ):
+    for i in main.activeNodes:
         t = main.Thread( target=main.CLIs[i].ports,
                          name="ports-" + str( i ),
                          args=[ ] )
@@ -67,7 +67,7 @@
     """
     links = []
     threads = []
-    for i in range( main.numCtrls ):
+    for i in main.activeNodes:
         t = main.Thread( target=main.CLIs[i].links,
                          name="links-" + str( i ),
                          args=[ ] )
@@ -85,7 +85,7 @@
     """
     clusters = []
     threads = []
-    for i in range( main.numCtrls ):
+    for i in main.activeNodes:
         t = main.Thread( target=main.CLIs[i].clusters,
                          name="clusters-" + str( i ),
                          args=[ ] )
diff --git a/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.params b/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.params
index 62150b3..1e8635e 100755
--- a/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.params
+++ b/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.params
@@ -1,21 +1,23 @@
 <PARAMS>
 
-    <testcases>1,2,1001,8,1002,8</testcases>
+    # 1 - optional pull and build ONOS package
+    # 2 - set cell and install ONOS
+    # 10 - start mininet and assign switches to controller
+    # 11 - pingall
+    # 12 - compare topology
+    # 100 - balance master
+    # 200 - bring down onos node
+    # 300 - bring up onos node
+    # 1000 - report logs
 
-    <SCALE>
-        <size>3</size>
-        <max>3</max>
-    </SCALE>
+    <testcases>1,2,[10,100,11,12,200,100,11,12,300,100,11,12,1000]*3</testcases>
 
     <DEPENDENCY>
         <path>/tests/SCPFscaleTopo/Dependency/</path>
         <wrapper1>startUp</wrapper1>
         <wrapper2>scaleTopoFunction</wrapper2>
         <wrapper3>topo</wrapper3>
-        <topology>spine.py</topology>
         <multiovs>multiovs.py</multiovs>
-        <spine>spine,15,30</spine>
-        <torus>torus,28,28</torus>
     </DEPENDENCY>
 
     <ENV>
@@ -29,11 +31,25 @@
 
     <CTRL>
         <port>6653</port>
+        <numCtrls>3</numCtrls>
     </CTRL>
 
     <SLEEP>
         <startup>15</startup>
         <fwd>30</fwd>
+        <topoAttempts>1</topoAttempts>
+        <balance>10</balance>
+        <nodeDown>10</nodeDown>
+        <nodeUp>10</nodeUp>
     </SLEEP>
 
+    <TIMEOUT>
+        <pingall>1000</pingall>
+    </TIMEOUT>
+
+    <TOPOLOGY>
+        <topology>torus</topology>
+        <scale>5,10,20</scale>
+    </TOPOLOGY>
+
 </PARAMS>
diff --git a/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.py b/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.py
index 24e8842..b44d482 100644
--- a/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.py
+++ b/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.py
@@ -33,73 +33,77 @@
             gitBranch = main.params[ 'GIT' ][ 'branch' ]
             main.dependencyPath = main.testOnDirectory + \
                                   main.params[ 'DEPENDENCY' ][ 'path' ]
-            main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
             main.multiovs = main.params[ 'DEPENDENCY' ][ 'multiovs' ]
-            main.torus = main.params[ 'DEPENDENCY' ][ 'torus' ]
-            main.spine = main.params[ 'DEPENDENCY' ][ 'spine' ]
-            main.scale = ( main.params[ 'SCALE' ][ 'size' ] ).split( "," )
-            if main.ONOSbench.maxNodes:
-                main.maxNodes = int( main.ONOSbench.maxNodes )
-            else:
-                main.maxNodes = 0
+            main.topoName = main.params[ 'TOPOLOGY' ][ 'topology' ]
+            main.numCtrls = int( main.params[ 'CTRL' ][ 'numCtrls' ] )
+            main.topoScale = ( main.params[ 'TOPOLOGY' ][ 'scale' ] ).split( "," )
+            main.topoScaleSize = len( main.topoScale )
             wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
             wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
             wrapperFile3 = main.params[ 'DEPENDENCY' ][ 'wrapper3' ]
+            main.checkTopoAttempts = int( main.params['SLEEP']['topoAttempts'])
             main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
             main.fwdSleep = int( main.params[ 'SLEEP' ][ 'fwd' ] )
+            main.balanceSleep = int( main.params[ 'SLEEP' ][ 'balance' ] )
+            main.nodeDownSleep = int( main.params[ 'SLEEP' ][ 'nodeDown' ] )
+            main.nodeUpSleep = int( main.params[ 'SLEEP' ][ 'nodeUp' ] )
+            main.pingallTimeout = int( main.params[ 'TIMEOUT' ][ 'pingall' ] )
             gitPull = main.params[ 'GIT' ][ 'pull' ]
+            main.homeDir = os.path.expanduser('~')
             main.cellData = {} # for creating cell file
             main.hostsData = {}
             main.CLIs = []
             main.ONOSip = []
-
+            main.activeNodes = []
             main.ONOSip = main.ONOSbench.getOnosIps()
-            print main.ONOSip
 
-            # Assigning ONOS cli handles to a list
-            for i in range( 1,  main.maxNodes + 1 ):
-                main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
+        except Exception:
+            main.log.exception( "Exception: constructing test variables" )
+            main.cleanup()
+            main.exit()
 
-            # -- INIT SECTION, ONLY RUNS ONCE -- #
+        try:
+            for i in range(main.numCtrls):
+                main.CLIs.append( getattr( main, 'ONOScli%s' % (i+1) ) )
+
+        except Exception:
+            main.log.exception( "Exception: assinging ONOS cli handles to a list" )
+            main.cleanup()
+            main.exit()
+
+        try:
             main.startUp = imp.load_source( wrapperFile1,
                                             main.dependencyPath +
                                             wrapperFile1 +
                                             ".py" )
 
             main.scaleTopoFunction = imp.load_source( wrapperFile2,
-                                                   main.dependencyPath +
-                                                   wrapperFile2 +
-                                                   ".py" )
+                                                      main.dependencyPath +
+                                                      wrapperFile2 +
+                                                      ".py" )
 
             main.topo = imp.load_source( wrapperFile3,
                                          main.dependencyPath +
                                          wrapperFile3 +
                                          ".py" )
-
-            copyResult1 = main.ONOSbench.scp( main.Mininet1,
-                                              main.dependencyPath +
-                                              main.topology,
-                                              main.Mininet1.home,
-                                              direction="to" )
-            time.sleep(3)
-            copyResult2 = main.ONOSbench.scp( main.Mininet1,
-                                              main.dependencyPath +
-                                              main.multiovs,
-                                              main.Mininet1.home,
-                                              direction="to" )
-            time.sleep(3)
-            if main.CLIs:
-                stepResult = main.TRUE
-            else:
-                main.log.error( "Did not properly created list of " +
-                                "ONOS CLI handle" )
-                stepResult = main.FALSE
-
-        except Exception as e:
-            main.log.exception(e)
+        except Exception:
+            main.log.exception( "Exception: importing wrapper files" )
             main.cleanup()
             main.exit()
 
+        main.ONOSbench.scp( main.Mininet1,
+                            main.dependencyPath +
+                            main.multiovs,
+                            main.Mininet1.home,
+                            direction="to" )
+
+        if main.CLIs:
+                stepResult = main.TRUE
+        else:
+            main.log.error( "Did not properly created list of " +
+                            "ONOS CLI handle" )
+            stepResult = main.FALSE
+
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
                                  onpass="Successfully construct " +
@@ -119,22 +123,9 @@
         else:
             main.log.warn( "Did not pull new code so skipping mvn " +
                            "clean install" )
-        main.ONOSbench.getVersion( report=True )
-        if gitPull == 'True':
-            main.step( "Building ONOS in " + gitBranch + " branch" )
-            onosBuildResult = main.startUp.onosBuild( main, gitBranch )
-            stepResult = onosBuildResult
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=stepResult,
-                                     onpass="Successfully compiled " +
-                                            "latest ONOS",
-                                     onfail="Failed to compile " +
-                                            "latest ONOS" )
-        else:
-            main.log.warn( "Did not pull new code so skipping mvn " +
-                           "clean install" )
 
-    def CASE2( self, main ):
+
+    def CASE2( self, main):
         """
         - Set up cell
             - Create cell file
@@ -147,29 +138,27 @@
         - Connect to cli
         """
 
-        # main.scale[ 0 ] determines the current number of ONOS controller
-        main.numCtrls = int( main.scale[ 0 ] )
-
         main.case( "Starting up " + str( main.numCtrls ) +
                    " node(s) ONOS cluster" )
+        main.caseExplanation = "Set up ONOS with " + str( main.numCtrls ) +\
+                                " node(s) ONOS cluster"
+
+
 
         #kill off all onos processes
         main.log.info( "Safety check, killing all ONOS processes" +
                        " before initiating enviornment setup" )
 
-        for i in range( main.maxNodes ):
+        for i in range( main.numCtrls ):
             main.ONOSbench.onosDie( main.ONOSip[ i ] )
 
-        print "NODE COUNT = ", main.numCtrls
-
         tempOnosIp = []
         for i in range( main.numCtrls ):
             tempOnosIp.append( main.ONOSip[i] )
 
         main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
                                        "temp", main.Mininet1.ip_address,
-                                       main.apps,
-                                       tempOnosIp )
+                                       main.apps, tempOnosIp )
 
         main.step( "Apply cell to environment" )
         cellResult = main.ONOSbench.setCell( "temp" )
@@ -189,11 +178,124 @@
                                  onpass="Successfully created ONOS package",
                                  onfail="Failed to create ONOS package" )
 
+        time.sleep( main.startUpSleep )
+        main.step( "Uninstalling ONOS package" )
+        onosUninstallResult = main.TRUE
+        for ip in main.ONOSip:
+            onosUninstallResult = onosUninstallResult and \
+                    main.ONOSbench.onosUninstall( nodeIp=ip )
+        stepResult = onosUninstallResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully uninstalled ONOS package",
+                                 onfail="Failed to uninstall ONOS package" )
 
-        # Remove the first element in main.scale list
-        #main.scale.remove( main.scale[ 0 ] )
+        time.sleep( main.startUpSleep )
+        main.step( "Installing ONOS package" )
+        onosInstallResult = main.TRUE
+        for i in range( main.numCtrls ):
+            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" )
 
-    def CASE8( self, main ):
+        time.sleep( main.startUpSleep )
+        main.step( "Starting ONOS service" )
+        stopResult = main.TRUE
+        startResult = main.TRUE
+        onosIsUp = main.TRUE
+
+        for i in range( main.numCtrls ):
+            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
+        if onosIsUp == main.TRUE:
+            main.log.report( "ONOS instance is up and ready" )
+        else:
+            main.log.report( "ONOS instance may not be up, stop and " +
+                             "start ONOS again " )
+
+            for i in range( main.numCtrls ):
+                stopResult = stopResult and \
+                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
+            for i in range( main.numCtrls ):
+                startResult = startResult and \
+                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
+        stepResult = onosIsUp and stopResult and startResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="ONOS service is ready",
+                                 onfail="ONOS service did not start properly" )
+
+        main.step( "Start ONOS cli" )
+        cliResult = main.TRUE
+        for i in range( main.numCtrls ):
+            cliResult = cliResult and \
+                        main.CLIs[ i ].startOnosCli( main.ONOSip[ i ] )
+            main.activeNodes.append( i )
+        stepResult = cliResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully start ONOS cli",
+                                 onfail="Failed to start ONOS cli" )
+
+
+    def CASE10( self, main ):
+        """
+            Starting up torus topology
+        """
+        main.case( "Starting up torus topology" )
+        main.step( "Starting up torus topology" )
+
+        main.log.info( "Checking if mininet is already running" )
+        if len( main.topoScale ) < main.topoScaleSize:
+            main.log.info( "Mininet is already running. Stopping mininet." )
+            main.Mininet1.stopNet()
+            time.sleep(5)
+        else:
+            main.log.info( "Mininet was not running" )
+
+        try:
+            scale = main.topoScale.pop(0)
+        except Exception:
+            main.log.exception("Exception: popping from list of topology scales ")
+            main.cleanup()
+            main.exit()
+
+        mnCmd = " mn --custom=" + main.homeDir + "/mininet/custom/multiovs.py " +\
+                "--switch=ovsm --topo " + main.topoName + ","+ scale + "," + scale +\
+                " --controller=remote,ip=" + main.ONOSip[ 0 ] +\
+                " --controller=remote,ip=" + main.ONOSip[ 1 ] +\
+                " --controller=remote,ip=" + main.ONOSip[ 2 ] + " --mac"
+        stepResult = main.Mininet1.startNet(mnCmd=mnCmd)
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass=main.topoName +
+                                    " topology started successfully",
+                                 onfail=main.topoName +
+                                    " topology failed to start" )
+
+
+    def CASE11( self, main ):
+        '''
+            Pingall
+        '''
+        main.case( "Pingall" )
+        main.step( "Pingall" )
+        pingResult = main.Mininet1.pingall( timeout=main.pingallTimeout )
+        if not pingResult:
+            main.log.warn( "First pingall failed. Retrying..." )
+            time.sleep(3)
+            pingResult = main.Mininet1.pingall( timeout=main.pingallTimeout )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=pingResult,
+                                 onpass="Pingall successfull",
+                                 onfail="Pingall failed" )
+
+
+    def CASE12( self, main ):
         """
         Compare Topo
         """
@@ -204,10 +306,10 @@
                                 " and ONOS"
 
         main.step( "Gathering topology information" )
-        # TODO: add a paramaterized sleep here
         devicesResults = main.TRUE
         linksResults = main.TRUE
         hostsResults = main.TRUE
+
         devices = main.topo.getAllDevices( main )
         hosts = main.topo.getAllHosts( main )
         ports = main.topo.getAllPorts( main )
@@ -218,9 +320,10 @@
         mnLinks = main.Mininet1.getLinks()
         mnHosts = main.Mininet1.getHosts()
 
-        main.step( "Conmparing MN topology to ONOS topology" )
-        for controller in range( main.numCtrls ):
-            controllerStr = str( controller + 1 )
+        main.step( "Comparing MN topology to ONOS topology" )
+
+        for controller in range(len(main.activeNodes)):
+            controllerStr = str( main.activeNodes[controller] + 1 )
             if devices[ controller ] and ports[ controller ] and\
                 "Error" not in devices[ controller ] and\
                 "Error" not in ports[ controller ]:
@@ -257,14 +360,95 @@
                         json.loads( hosts[ controller ] ) )
             else:
                 currentHostsResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentHostsResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " hosts exist in Mininet",
-                                     onfail="ONOS" + controllerStr +
-                                     " hosts don't match Mininet" )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=currentHostsResult,
+                                 onpass="ONOS" + controllerStr +
+                                 " hosts exist in Mininet",
+                                 onfail="ONOS" + controllerStr +
+                                 " hosts don't match Mininet" )
 
-    def CASE9( self, main ):
+    def CASE100( self, main ):
+        '''
+            Balance master
+        '''
+        main.case("Balancing Masters")
+        main.step("Balancing Masters")
+        try:
+            controller = main.activeNodes[0]
+            stepResult = main.CLIs[controller].balanceMasters()
+        except Exception:
+            main.log.exception("Exception: balancing masters")
+            main.cleanup()
+            main.exit()
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Balance masters was successfull",
+                                 onfail="Failed to balance masters")
+
+        time.sleep(main.balanceSleep)
+
+
+    def CASE200( self, main ):
+        '''
+            Bring third node down
+        '''
+        main.case( "Stopping an ONOS service" )
+        main.step( "Bringing down node 3" )
+
+        # Always bring down the third node
+        main.deadNode = 2
+
+        # Printing purposes
+        node = main.deadNode + 1
+
+        main.log.info( "deadnode: %s" % node )
+
+        main.log.info( "Stopping node %s" % node )
+        startResult = main.ONOSbench.onosStop( main.ONOSip[ main.deadNode ] )
+
+        try:
+            main.activeNodes.pop( main.deadNode )
+        except Exception:
+            main.log.exception( "Exception: popping from list of active nodes" )
+            main.cleanup()
+            main.exit()
+
+        utilities.assert_equals( expect=main.TRUE,
+                             actual=stepResult,
+                             onpass="Successfully brought down onos node %s" % node,
+                             onfail="Failed to bring down onos node %s" % node )
+
+        time.sleep(main.nodeDownSleep)
+
+
+    def CASE300( self, main ):
+        '''
+            Bring up onos node
+        '''
+        main.case( "Bring the dead ONOS node back up" )
+        main.step( "Bringing up an onos node" )
+
+        node = main.deadNode + 1
+
+        main.log.info( "Starting node %s" % node )
+        startResult = main.ONOSbench.onosStart( main.ONOSip[ main.deadNode ] )
+
+        main.log.info( "Starting onos cli" )
+        startCliResult = main.CLIs[ main.deadNode ].startOnosCli( main.ONOSip[ main.deadNode ] )
+
+        main.activeNodes.append( main.deadNode )
+
+        stepResult = startResult and startCliResult
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully brought up onos node %s" % node,
+                                 onfail="Failed to bring up onos node %s" % node )
+
+
+        time.sleep(main.nodeUpSleep)
+
+    def CASE1000( self, main ):
         '''
             Report errors/warnings/exceptions
         '''
@@ -277,79 +461,3 @@
                                     "ERROR",
                                     "Except" ],
                                   "s" )
-
-    def CASE11( self, main ):
-        """
-            Start mininet
-        """
-        main.log.report( "Start Mininet topology" )
-        main.log.case( "Start Mininet topology" )
-
-        main.step( "Starting Mininet Topology" )
-        topology = main.dependencyPath + main.topology
-        topoResult = main.Mininet1.startNet( topoFile=topology )
-        stepResult = topoResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully loaded topology",
-                                 onfail="Failed to load topology" )
-        # Exit if topology did not load properly
-        if not topoResult:
-            main.cleanup()
-            main.exit()
-
-    def CASE1001( self, main ):
-        """
-            Topology test
-        """
-        import time
-        main.topoName = "SPINE"
-        main.case( "Spine topology test" )
-        main.step( main.topoName + " topology" )
-        mnCmd = "sudo mn --custom " + main.dependencyPath +\
-                main.multiovs + " --switch=ovsm --custom " +\
-                main.dependencyPath + main.topology +\
-                " --topo " + main.spine + " --controller=remote,ip=" +\
-                main.ONOSip[ 0 ] + " --mac"
-
-        stepResult = main.scaleTopoFunction.testTopology( main,
-                                                          mnCmd=mnCmd,
-                                                          timeout=900,
-                                                          clean=False )
-
-        time.sleep(3)
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass=main.spine + " topology successful",
-                                 onfail=main.spine +
-                                 "Spine topology failed" )
-
-        time.sleep(60)
-
-        '''
-        main.ONOSbench.scp( main.Mininet1,
-                           "~/mininet/custom/spine.json",
-                           "/tmp/",
-                           direction="to" )
-        '''
-
-    def CASE1002( self, main ):
-        """
-            Topology test
-        """
-        main.topoName = "TORUS"
-        main.case( "Topology discovery test" )
-        stepResult = main.TRUE
-        main.step( main.torus + " topology" )
-        mnCmd = "sudo mn --custom=mininet/custom/multiovs.py " +\
-                "--switch=ovsm --topo " + main.torus +\
-                " --controller=remote,ip=" + main.ONOSip[ 0 ]  +" --mac"
-        stepResult = main.scaleTopoFunction.testTopology( main,
-                                                          mnCmd=mnCmd,
-                                                          timeout=900,
-                                                          clean=True )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass=main.torus + " topology successful",
-                                 onfail=main.torus + " topology failed" )
diff --git a/TestON/tests/USECASE_SdnipFunction/Dependency/Functions.py b/TestON/tests/USECASE_SdnipFunction/Dependency/Functions.py
index 0f25012..ddd8c1e 100644
--- a/TestON/tests/USECASE_SdnipFunction/Dependency/Functions.py
+++ b/TestON/tests/USECASE_SdnipFunction/Dependency/Functions.py
@@ -9,8 +9,8 @@
     main.log.info( routeNumActual )
     utilities.assertEquals( \
         expect = routeNumExpected, actual = routeNumActual,
-        onpass = "***Route number is correct!***",
-        onfail = "***Route number is wrong!***" )
+        onpass = "Route number is correct!",
+        onfail = "Route number is wrong!" )
 
 def checkM2SintentNum( main, intentNumExpected ):
     main.step( "Check M2S intents installed" )
@@ -23,8 +23,8 @@
     main.log.info( intentNumActual )
     utilities.assertEquals( \
         expect = intentNumExpected, actual = intentNumActual,
-        onpass = "***M2S intent number is correct!***",
-        onfail = "***M2S intent number is wrong!***" )
+        onpass = "M2S intent number is correct!",
+        onfail = "M2S intent number is wrong!" )
 
 def checkP2PintentNum( main, intentNumExpected ):
     main.step( "Check P2P intents installed" )
@@ -37,8 +37,8 @@
     main.log.info( intentNumActual )
     utilities.assertEquals( \
         expect = intentNumExpected, actual = intentNumActual,
-        onpass = "***P2P intent number is correct!***",
-        onfail = "***P2P intent number is wrong!***" )
+        onpass = "P2P intent number is correct!",
+        onfail = "P2P intent number is wrong!" )
 
 def checkFlowNum( main, switch, flowNumExpected ):
     main.step( "Check flow entry number in " + switch )
@@ -49,8 +49,8 @@
     main.log.info( flowNumActual )
     utilities.assertEquals( \
         expect = flowNumExpected, actual = flowNumActual,
-        onpass = "***Flow number in " + switch + " is correct!***",
-        onfail = "***Flow number in " + switch + " is wrong!***" )
+        onpass = "Flow number in " + switch + " is correct!",
+        onfail = "Flow number in " + switch + " is wrong!" )
 
 
 def pingSpeakerToPeer( main, speakers = ["speaker1"],
@@ -74,11 +74,9 @@
         main.exit()
 
     if expectAllSuccess:
-        main.step( "Check ping between BGP peers and speakers, expect all tests\
-        will SUCCEED" )
+        main.step( "BGP speakers ping peers, expect all tests to succeed" )
     else:
-        main.step( "Check ping between BGP peers and speakers, expect all tests\
-        will FAIL" )
+        main.step( "BGP speakers ping peers, expect all tests to fail" )
 
     result = True
     if expectAllSuccess:
@@ -137,7 +135,9 @@
                              onpass = "Ping test results are expected",
                              onfail = "Ping test results are Not expected" )
 
+    '''
     if result == False:
         main.cleanup()
         main.exit()
+    '''
 
diff --git a/TestON/tests/USECASE_SdnipFunction/USECASE_SdnipFunction.params b/TestON/tests/USECASE_SdnipFunction/USECASE_SdnipFunction.params
index 5ba6b2d..a7a8f72 100644
--- a/TestON/tests/USECASE_SdnipFunction/USECASE_SdnipFunction.params
+++ b/TestON/tests/USECASE_SdnipFunction/USECASE_SdnipFunction.params
@@ -14,7 +14,6 @@
     </CTRL>
 
     <GIT>
-        <autoPull>on</autoPull>
         <branch1>master</branch1>
         <branch2>onos-1.3</branch2>
     </GIT>
@@ -37,6 +36,7 @@
 
     <timers>
         <SdnIpSetup>10</SdnIpSetup>
+        <TopoDiscovery>60</TopoDiscovery>
         <PingTestWithRoutes>20</PingTestWithRoutes>
         <PingTestWithoutRoutes>100</PingTestWithoutRoutes>
         <RouteDelivery>60</RouteDelivery>
diff --git a/TestON/tests/USECASE_SdnipFunction/USECASE_SdnipFunction.py b/TestON/tests/USECASE_SdnipFunction/USECASE_SdnipFunction.py
index ed93999..ee0b120 100644
--- a/TestON/tests/USECASE_SdnipFunction/USECASE_SdnipFunction.py
+++ b/TestON/tests/USECASE_SdnipFunction/USECASE_SdnipFunction.py
@@ -12,7 +12,7 @@
         """
         import os
         import imp
-        main.log.case( "This case is to setup the Mininet testbed" )
+        main.log.case( "Setup the Mininet testbed" )
         main.dependencyPath = main.testDir + \
                               main.params[ 'DEPENDENCY' ][ 'path' ]
         main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
@@ -53,23 +53,22 @@
 
         tunnelResult = main.TRUE
         tunnelResult = main.Mininet.node( "root", command )
-        if not tunnelResult:
-            main.log.report("Failed to create tunnel")
+        utilities.assert_equals( expect = True,
+                             actual = ( "PasswordAuthentication" in tunnelResult ),
+                             onpass = "Created tunnel succeeded",
+                             onfail = "Create tunnel failed" )
+        if ("PasswordAuthentication" not in tunnelResult) :
             main.cleanup()
             main.exit()
-        elif "PasswordAuthentication" in tunnelResult:
-            main.log.report("Successfully created tunnel")
 
 
     # This case is to setup ONOS
     def CASE101( self, main ):
         """
-           CASE100 is to compile ONOS and install it
+           Package ONOS and install it
            Startup sequence:
            cell <name>
            onos-verify-cell
-           git pull
-           mvn clean install
            onos-package
            onos-install -f
            onos-wait-for-start
@@ -84,68 +83,122 @@
 
         main.step( "Applying cell variable to environment" )
         cellResult = main.ONOSbench.setCell( cellName )
+        utilities.assert_equals( expect = main.TRUE,
+                             actual = cellResult,
+                             onpass = "Set cell succeeded",
+                             onfail = "Set cell failed" )
+
         verifyResult = main.ONOSbench.verifyCell()
+        utilities.assert_equals( expect = main.TRUE,
+                             actual = verifyResult,
+                             onpass = "Verify cell succeeded",
+                             onfail = "Verify cell failed" )
 
         branchName = main.ONOSbench.getBranchName()
-        main.log.info( "ONOS is on branch: " + branchName )
+        main.log.report( "ONOS is on branch: " + branchName )
 
-        main.log.report( "Uninstalling ONOS" )
-        main.ONOSbench.onosUninstall( ONOS1Ip )
-
-        # cleanInstallResult = main.TRUE
-        # gitPullResult = main.TRUE
-
+        main.log.step( "Uninstalling ONOS" )
+        uninstallResult = main.ONOSbench.onosUninstall( ONOS1Ip )
+        utilities.assert_equals( expect = main.TRUE,
+                                actual = uninstallResult,
+                                onpass = "Uninstall ONOS succeeded",
+                                onfail = "Uninstall ONOS failed" )
+        '''
         main.step( "Git pull" )
         gitPullResult = main.ONOSbench.gitPull()
+        main.log.info( "gitPullResult" )
+        main.log.info( gitPullResult )
+        gitPullResult2 = ( gitPullResult == main.TRUE ) or ( gitPullResult == 3 )
+        utilities.assert_equals( expect = True,
+                                 actual = gitPullResult2,
+                                 onpass = "Git pull ONOS succeeded",
+                                 onfail = "Git pull ONOS failed" )
 
         main.step( "Using mvn clean install" )
         if gitPullResult == main.TRUE:
-            cleanInstallResult = main.ONOSbench.cleanInstall( mciTimeout = 1000 )
+            mciResult = main.ONOSbench.cleanInstall( mciTimeout = 1000 )
+            utilities.assert_equals( expect = main.TRUE,
+                                     actual = mciResult,
+                                     onpass = "Maven clean install ONOS succeeded",
+                                     onfail = "Maven clean install ONOS failed" )
         else:
              main.log.warn( "Did not pull new code so skipping mvn " +
                             "clean install" )
-             cleanInstallResult = main.TRUE
+             mciResult = main.TRUE
+        '''
 
         main.ONOSbench.getVersion( report = True )
 
         main.step( "Creating ONOS package" )
         packageResult = main.ONOSbench.onosPackage( opTimeout = 500 )
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = packageResult,
+                                 onpass = "Package ONOS succeeded",
+                                 onfail = "Package ONOS failed" )
 
         main.step( "Installing ONOS package" )
         onos1InstallResult = main.ONOSbench.onosInstall( options = "-f",
-                                                           node = ONOS1Ip )
+                                                         node = ONOS1Ip )
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = onos1InstallResult,
+                                 onpass = "Install ONOS succeeded",
+                                 onfail = "Install ONOS failed" )
 
         main.step( "Checking if ONOS is up yet" )
-        for i in range( 2 ):
-            onos1Isup = main.ONOSbench.isup( ONOS1Ip, timeout = 420 )
-            if onos1Isup:
-                break
-        if not onos1Isup:
-            main.log.report( "ONOS1 didn't start!" )
+        onos1UpResult = main.ONOSbench.isup( ONOS1Ip, timeout = 420 )
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = onos1UpResult,
+                                 onpass = "ONOS is up",
+                                 onfail = "ONOS is NOT up" )
 
+        main.step( "Checking if ONOS CLI is ready" )
         cliResult = main.ONOScli.startOnosCli( ONOS1Ip,
                 commandlineTimeout = 100, onosStartTimeout = 600 )
+        utilities.assert_equals( expect = main.TRUE,
+                         actual = cliResult,
+                         onpass = "ONOS CLI is ready",
+                         onfail = "ONOS CLI is NOT ready" )
 
-        caseResult = ( cleanInstallResult and packageResult and
-                        cellResult and verifyResult and
-                        onos1InstallResult and
-                        onos1Isup and cliResult )
+        caseResult = ( cellResult and verifyResult and
+                       packageResult and
+                       onos1InstallResult and onos1UpResult and cliResult )
 
         utilities.assert_equals( expect = main.TRUE, actual = caseResult,
                                  onpass = "ONOS startup successful",
                                  onfail = "ONOS startup NOT successful" )
 
         if caseResult == main.FALSE:
+            main.log.info( "ONOS startup failed!" )
             main.cleanup()
             main.exit()
 
-        main.step( "Get links in the network" )
+        main.log.info( "Get links in the network" )
+        time.sleep( int ( main.params['timers']['TopoDiscovery'] ) )
+        summaryResult = main.ONOScli.summary()
+        linkNum = json.loads( summaryResult )[ "links" ]
+        if linkNum < 100:
+            main.log.info( "Link number is wrong!" )
+            listResult = main.ONOScli.links( jsonFormat = False )
+            main.log.info( listResult )
+            main.cleanup()
+            main.exit()
+
         listResult = main.ONOScli.links( jsonFormat = False )
         main.log.info( listResult )
-        main.log.info( "Activate sdn-ip application" )
-        main.ONOScli.activateApp( "org.onosproject.sdnip" )
 
-        main.log.info( "Wait sdn-ip to finish installing connectivity intents, \
+        main.step( "Activate sdn-ip application" )
+        activeSDNIPresult = main.ONOScli.activateApp( "org.onosproject.sdnip" )
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = activeSDNIPresult,
+                                 onpass = "Activate SDN-IP succeeded",
+                                 onfail = "Activate SDN-IP failed" )
+        if not activeSDNIPresult:
+            main.log.info( "Activate SDN-IP failed!" )
+            main.cleanup()
+            main.exit()
+
+
+        main.log.info( "Wait SDN-IP to finish installing connectivity intents \
         and the BGP paths in data plane are ready..." )
         time.sleep( int( main.params[ 'timers' ][ 'SdnIpSetup' ] ) )
         main.log.info( "Wait Quagga to finish delivery all routes to each \
@@ -158,7 +211,7 @@
         '''
         This test case is to load the methods from other Python files.
         '''
-        main.case( "Loading the methods from other Python file" )
+        main.case( "Loading methods from other Python file" )
         # load the methods from other file
         wrapperFile = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
         main.Functions = imp.load_source( wrapperFile,
@@ -172,7 +225,7 @@
         ping test from 3 bgp peers to BGP speaker
         '''
 
-        main.case( "This case is to check ping between BGP peers and speakers" )
+        main.case( "Ping tests between BGP peers and speakers" )
         main.Functions.pingSpeakerToPeer( main, speakers = ["speaker1"],
                        peers = ["peer64514", "peer64515", "peer64516"],
                        expectAllSuccess = True )
@@ -182,10 +235,10 @@
         '''
         point-to-point intents test for each BGP peer and BGP speaker pair
         '''
-        main.case( "This case is to check point-to-point intents" )
+        main.case( "Check point-to-point intents" )
         main.log.info( "There are %s BGP peers in total "
                        % main.params[ 'config' ][ 'peerNum' ] )
-        main.step( "Get point-to-point intents from ONOS CLI" )
+        main.step( "Check P2P intents number from ONOS CLI" )
 
         getIntentsResult = main.ONOScli.intents( jsonFormat = True )
         bgpIntentsActualNum = \
@@ -198,15 +251,15 @@
         utilities.assertEquals( \
             expect = True,
             actual = eq( bgpIntentsExpectedNum, bgpIntentsActualNum ),
-            onpass = "***PointToPointIntent Intent Num in SDN-IP are correct!***",
-            onfail = "***PointToPointIntent Intent Num in SDN-IP are wrong!***" )
+            onpass = "PointToPointIntent Intent Num is correct!",
+            onfail = "PointToPointIntent Intent Num is wrong!" )
 
 
     def CASE3( self, main ):
         '''
         routes and intents check to all BGP peers
         '''
-        main.case( "This case is to check routes and intents to all BGP peers" )
+        main.case( "Check routes and M2S intents to all BGP peers" )
 
         allRoutesExpected = []
         allRoutesExpected.append( "4.0.0.0/24" + "/" + "10.0.4.1" )
@@ -226,10 +279,10 @@
         main.log.info( allRoutesStrActual )
         utilities.assertEquals( \
             expect = allRoutesStrExpected, actual = allRoutesStrActual,
-            onpass = "***Routes in SDN-IP are correct!***",
-            onfail = "***Routes in SDN-IP are wrong!***" )
+            onpass = "Routes are correct!",
+            onfail = "Routes are wrong!" )
 
-        main.step( "Check MultiPointToSinglePointIntent intents installed" )
+        main.step( "Check M2S intents installed" )
         getIntentsResult = main.ONOScli.intents( jsonFormat = True )
         routeIntentsActualNum = \
             main.QuaggaCliSpeaker1.extractActualRouteIntentNum( getIntentsResult )
@@ -242,25 +295,22 @@
         utilities.assertEquals( \
             expect = True,
             actual = eq( routeIntentsExpectedNum, routeIntentsActualNum ),
-            onpass = "***MultiPointToSinglePoint Intent Num in SDN-IP is \
-            correct!***",
-            onfail = "***MultiPointToSinglePoint Intent Num in SDN-IP is \
-            wrong!***" )
+            onpass = "MultiPointToSinglePoint Intent Num is correct!",
+            onfail = "MultiPointToSinglePoint Intent Num is wrong!" )
 
         main.step( "Check whether all flow status are ADDED" )
         utilities.assertEquals( \
             expect = main.TRUE,
             actual = main.ONOScli.checkFlowsState( isPENDING_ADD = False ),
-            onpass = "***Flow status is correct!***",
-            onfail = "***Flow status is wrong!***" )
+            onpass = "Flow status is correct!",
+            onfail = "Flow status is wrong!" )
 
 
     def CASE4( self, main ):
         '''
         Ping test in data plane for each route
         '''
-        main.case( "This case is to check ping for each route, \
-        all hosts behind BGP peers" )
+        main.case( "Ping test for each route, all hosts behind BGP peers" )
         main.Functions.pingHostToHost( main,
                         hosts = ["host64514", "host64515", "host64516"],
                         expectAllSuccess = True )
@@ -271,46 +321,62 @@
         Cut links to peers one by one, check routes/intents
         '''
         import time
-        main.case( "This case is to bring down links and check routes/intents" )
+        main.case( "Bring down links and check routes/intents" )
         main.step( "Bring down the link between sw32 and peer64514" )
-        result = main.Mininet.link( END1 = "sw32", END2 = "peer64514",
-                                    OPTION = "down" )
-        if result == main.TRUE:
+        linkResult1 = main.Mininet.link( END1 = "sw32", END2 = "peer64514",
+                                         OPTION = "down" )
+        utilities.assertEquals( expect = main.TRUE,
+                                actual = linkResult1,
+                                onpass = "Bring down link succeeded!",
+                                onfail = "Bring down link failed!" )
+
+        if linkResult1 == main.TRUE:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
             main.Functions.checkRouteNum( main, 2 )
             main.Functions.checkM2SintentNum( main, 2 )
         else:
-            main.log.info( "Bring down link failed!!!" )
-            main.exit();
+            main.log.info( "Bring down link failed!" )
+            main.cleanup()
+            main.exit()
 
         main.step( "Bring down the link between sw8 and peer64515" )
-        result = main.Mininet.link( END1 = "sw8", END2 = "peer64515",
-                                    OPTION = "down" )
-        if result == main.TRUE:
+        linkResult2 = main.Mininet.link( END1 = "sw8", END2 = "peer64515",
+                                         OPTION = "down" )
+        utilities.assertEquals( expect = main.TRUE,
+                                actual = linkResult2,
+                                onpass = "Bring down link succeeded!",
+                                onfail = "Bring down link failed!" )
+        if linkResult2 == main.TRUE:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
             main.Functions.checkRouteNum( main, 1 )
             main.Functions.checkM2SintentNum( main, 1 )
         else:
-            main.log.info( "Bring down link failed!!!" )
-            main.exit();
+            main.log.info( "Bring down link failed!" )
+            main.cleanup()
+            main.exit()
 
         main.step( "Bring down the link between sw28 and peer64516" )
-        result = main.Mininet.link( END1 = "sw28", END2 = "peer64516",
-                                    OPTION = "down" )
-        if result == main.TRUE:
+        linkResult3 = main.Mininet.link( END1 = "sw28", END2 = "peer64516",
+                                         OPTION = "down" )
+        utilities.assertEquals( expect = main.TRUE,
+                                actual = linkResult3,
+                                onpass = "Bring down link succeeded!",
+                                onfail = "Bring down link failed!" )
+        if linkResult3 == main.TRUE:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
             main.Functions.checkRouteNum( main, 0 )
             main.Functions.checkM2SintentNum( main, 0 )
         else:
-            main.log.info( "Bring down link failed!!!" )
-            main.exit();
+            main.log.info( "Bring down link failed!" )
+            main.cleanup()
+            main.exit()
 
         main.step( "Check whether all flow status are ADDED" )
         utilities.assertEquals( \
             expect = main.TRUE,
             actual = main.ONOScli.checkFlowsState( isPENDING_ADD = False ),
-            onpass = "***Flow status is correct!***",
-            onfail = "***Flow status is wrong!***" )
+            onpass = "Flow status is correct!",
+            onfail = "Flow status is wrong!" )
 
         # Ping test
         main.Functions.pingSpeakerToPeer( main, speakers = ["speaker1"],
@@ -326,46 +392,61 @@
         Recover links to peers one by one, check routes/intents
         '''
         import time
-        main.case( "This case is to bring up links and check routes/intents" )
+        main.case( "Bring up links and check routes/intents" )
         main.step( "Bring up the link between sw32 and peer64514" )
-        result = main.Mininet.link( END1 = "sw32", END2 = "peer64514",
-                                    OPTION = "up" )
-        if result == main.TRUE:
+        linkResult1 = main.Mininet.link( END1 = "sw32", END2 = "peer64514",
+                                         OPTION = "up" )
+        utilities.assertEquals( expect = main.TRUE,
+                                actual = linkResult1,
+                                onpass = "Bring up link succeeded!",
+                                onfail = "Bring up link failed!" )
+        if linkResult1 == main.TRUE:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
             main.Functions.checkRouteNum( main, 1 )
             main.Functions.checkM2SintentNum( main, 1 )
         else:
-            main.log.info( "Bring up link failed!!!" )
-            main.exit();
+            main.log.info( "Bring up link failed!" )
+            main.cleanup()
+            main.exit()
 
         main.step( "Bring up the link between sw8 and peer64515" )
-        result = main.Mininet.link( END1 = "sw8", END2 = "peer64515",
-                                    OPTION = "up" )
-        if result == main.TRUE:
+        linkResult2 = main.Mininet.link( END1 = "sw8", END2 = "peer64515",
+                                         OPTION = "up" )
+        utilities.assertEquals( expect = main.TRUE,
+                                actual = linkResult2,
+                                onpass = "Bring up link succeeded!",
+                                onfail = "Bring up link failed!" )
+        if linkResult2 == main.TRUE:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
             main.Functions.checkRouteNum( main, 2 )
             main.Functions.checkM2SintentNum( main, 2 )
         else:
-            main.log.info( "Bring up link failed!!!" )
-            main.exit();
+            main.log.info( "Bring up link failed!" )
+            main.cleanup()
+            main.exit()
 
         main.step( "Bring up the link between sw28 and peer64516" )
-        result = main.Mininet.link( END1 = "sw28", END2 = "peer64516",
-                                    OPTION = "up" )
-        if result == main.TRUE:
+        linkResult3 = main.Mininet.link( END1 = "sw28", END2 = "peer64516",
+                                         OPTION = "up" )
+        utilities.assertEquals( expect = main.TRUE,
+                                actual = linkResult3,
+                                onpass = "Bring up link succeeded!",
+                                onfail = "Bring up link failed!" )
+        if linkResult3 == main.TRUE:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
             main.Functions.checkRouteNum( main, 3 )
             main.Functions.checkM2SintentNum( main, 3 )
         else:
-            main.log.info( "Bring up link failed!!!" )
-            main.exit();
+            main.log.info( "Bring up link failed!" )
+            main.cleanup()
+            main.exit()
 
         main.step( "Check whether all flow status are ADDED" )
         utilities.assertEquals( \
             expect = main.TRUE,
             actual = main.ONOScli.checkFlowsState( isPENDING_ADD = False ),
-            onpass = "***Flow status is correct!***",
-            onfail = "***Flow status is wrong!***" )
+            onpass = "Flow status is correct!",
+            onfail = "Flow status is wrong!" )
 
         # Ping test
         main.Functions.pingSpeakerToPeer( main, speakers = ["speaker1"],
@@ -381,18 +462,22 @@
         Shut down a edge switch, check P-2-P and M-2-S intents, ping test
         '''
         import time
-        main.case( "This case is to stop 1 edge switch,\
-        check P-2-P and M-2-S intents, ping test" )
+        main.case( "Stop edge sw32,check P-2-P and M-2-S intents, ping test" )
         main.step( "Stop sw32" )
         result = main.Mininet.switch( SW = "sw32", OPTION = "stop" )
+        utilities.assertEquals( expect = main.TRUE, actual = result,
+                                onpass = "Stopping switch succeeded!",
+                                onfail = "Stopping switch failed!" )
+
         if result == main.TRUE:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
             main.Functions.checkRouteNum( main, 2 )
             main.Functions.checkM2SintentNum( main, 2 )
             main.Functions.checkP2PintentNum( main, 12 )
         else:
-            main.log.info( "Stop switch failed!!!" )
-            main.exit();
+            main.log.info( "Stopping switch failed!" )
+            main.cleanup()
+            main.exit()
 
         main.step( "Check ping between hosts behind BGP peers" )
         result1 = main.Mininet.pingHost( src = "host64514", target = "host64515" )
@@ -428,47 +513,31 @@
         utilities.assertEquals( \
             expect = main.TRUE,
             actual = main.ONOScli.checkFlowsState( isPENDING_ADD = False ),
-            onpass = "***Flow status is correct!***",
-            onfail = "***Flow status is wrong!***" )
-
-        '''
-        main.step( "Stop sw8" )
-        result = main.Mininet.switch( SW = "sw8", OPTION = "stop" )
-        if result == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 1 )
-
-            # Note: there should be 0 M2S intent, not 1.
-            main.Functions.checkM2SintentNum( main, 0 )
-            main.Functions.checkP2PintentNum( main, 6 )
-        else:
-            main.log.info( "Stop switch failed!!!" )
-            main.exit();
-
-        main.step( "Stop sw28" )
-        result = main.Mininet.switch( SW = "sw28", OPTION = "stop" )
-        if result == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 0 )
-            main.Functions.checkM2SintentNum( main, 0 )
-            main.Functions.checkP2PintentNum( main, 0 )
-        else:
-            main.log.info( "Stop switch failed!!!" )
-            main.exit();
-        '''
+            onpass = "Flow status is correct!",
+            onfail = "Flow status is wrong!" )
 
 
     def CASE8( self, main ):
         '''
-        Bring up the edge switch which was shut down in CASE7,
+        Bring up the edge switch (sw32) which was shut down in CASE7,
         check P-2-P and M-2-S intents, ping test
         '''
         import time
-        main.case( "This case is to start the switch which was shut down in CASE7,\
-        check P-2-P and M-2-S intents, ping test" )
+        main.case( "Start the edge sw32, check P-2-P and M-2-S intents, ping test" )
         main.step( "Start sw32" )
         result1 = main.Mininet.switch( SW = "sw32", OPTION = "start" )
+        utilities.assertEquals( \
+            expect = main.TRUE,
+            actual = result1,
+            onpass = "Starting switch succeeded!",
+            onfail = "Starting switch failed!" )
+
         result2 = main.Mininet.assignSwController( "sw32", ONOS1Ip )
+        utilities.assertEquals( \
+            expect = main.TRUE,
+            actual = result2,
+            onpass = "Connect switch to ONOS succeeded!",
+            onfail = "Connect switch to ONOS failed!" )
 
         if result1 and result2:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
@@ -476,16 +545,16 @@
             main.Functions.checkM2SintentNum( main, 3 )
             main.Functions.checkP2PintentNum( main, 18 )
         else:
-            main.log.info( "Start switch failed!!!" )
+            main.log.info( "Starting switch failed!" )
             main.cleanup()
-            main.exit();
+            main.exit()
 
         main.step( "Check whether all flow status are ADDED" )
         utilities.assertEquals( \
             expect = main.TRUE,
             actual = main.ONOScli.checkFlowsState( isPENDING_ADD = False ),
-            onpass = "***Flow status is correct!***",
-            onfail = "***Flow status is wrong!***" )
+            onpass = "Flow status is correct!",
+            onfail = "Flow status is wrong!" )
 
         # Ping test
         main.Functions.pingSpeakerToPeer( main, speakers = ["speaker1"],
@@ -501,10 +570,10 @@
         Bring down a switch in best path, check:
         route number, P2P intent number, M2S intent number, ping test
         '''
-        main.case( "This case is to stop switch in best path, \
+        main.case( "Stop sw11 located in best path, \
         check route number, P2P intent number, M2S intent number, ping test" )
 
-        main.step( "Check the flow status before stopping sw11" )
+        main.log.info( "Check the flow number correctness before stopping sw11" )
         main.Functions.checkFlowNum( main, "sw11", 13 )
         main.Functions.checkFlowNum( main, "sw1", 3 )
         main.Functions.checkFlowNum( main, "sw7", 3 )
@@ -514,22 +583,26 @@
 
         main.step( "Stop sw11" )
         result = main.Mininet.switch( SW = "sw11", OPTION = "stop" )
+        utilities.assertEquals( expect = main.TRUE, actual = result,
+                                onpass = "Stopping switch succeeded!",
+                                onfail = "Stopping switch failed!" )
         if result:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
             main.Functions.checkRouteNum( main, 3 )
             main.Functions.checkM2SintentNum( main, 3 )
             main.Functions.checkP2PintentNum( main, 18 )
         else:
-            main.log.info( "Stop switch failed!!!" )
+            main.log.info( "Stopping switch failed!" )
             main.cleanup()
-            main.exit();
+            main.exit()
 
         main.step( "Check whether all flow status are ADDED" )
         utilities.assertEquals( \
             expect = main.TRUE,
             actual = main.ONOScli.checkFlowsState( isPENDING_ADD = False ),
-            onpass = "***Flow status is correct!***",
-            onfail = "***Flow status is wrong!***" )
+            onpass = "Flow status is correct!",
+            onfail = "Flow status is wrong!" )
         # Ping test
         main.Functions.pingSpeakerToPeer( main, speakers = ["speaker1"],
                        peers = ["peer64514", "peer64515", "peer64516"],
@@ -544,34 +617,44 @@
         Bring up the switch which was stopped in CASE9, check:
         route number, P2P intent number, M2S intent number, ping test
         '''
-        main.case( "This case is to start switch which was stopped in CASE9, \
+        main.case( "Start sw11 which was stopped in CASE9, \
         check route number, P2P intent number, M2S intent number, ping test" )
+
+        main.log.info( "Check the flow status before starting sw11" )
+        main.Functions.checkFlowNum( main, "sw1", 11 )
+        main.Functions.checkFlowNum( main, "sw7", 5 )
+        main.log.info( main.Mininet.checkFlows( "sw1" ) )
+        main.log.info( main.Mininet.checkFlows( "sw7" ) )
+
         main.step( "Start sw11" )
-        result = main.Mininet.switch( SW = "sw11", OPTION = "start" )
-        if result:
+        result1 = main.Mininet.switch( SW = "sw11", OPTION = "start" )
+        utilities.assertEquals( expect = main.TRUE, actual = result1,
+                                onpass = "Starting switch succeeded!",
+                                onfail = "Starting switch failed!" )
+        result2 = main.Mininet.assignSwController( "sw11", ONOS1Ip )
+        utilities.assertEquals( expect = main.TRUE, actual = result2,
+                                onpass = "Connect switch to ONOS succeeded!",
+                                onfail = "Connect switch to ONOS failed!" )
+        if result1 and result2:
             time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
             main.Functions.checkRouteNum( main, 3 )
             main.Functions.checkM2SintentNum( main, 3 )
             main.Functions.checkP2PintentNum( main, 18 )
 
-            main.step( "Check the flow status after stop and start sw11" )
-            main.Functions.checkFlowNum( main, "sw11", 3 )
-            main.Functions.checkFlowNum( main, "sw1", 11 )
-            main.Functions.checkFlowNum( main, "sw7", 5 )
-            main.log.info( main.Mininet.checkFlows( "sw11" ) )
-            main.log.info( main.Mininet.checkFlows( "sw1" ) )
-            main.log.info( main.Mininet.checkFlows( "sw7" ) )
+            main.log.debug( main.Mininet.checkFlows( "sw11" ) )
+            main.log.debug( main.Mininet.checkFlows( "sw1" ) )
+            main.log.debug( main.Mininet.checkFlows( "sw7" ) )
         else:
-            main.log.info( "Start switch failed!!!" )
+            main.log.info( "Starting switch failed!" )
             main.cleanup()
-            main.exit();
+            main.exit()
 
         main.step( "Check whether all flow status are ADDED" )
         utilities.assertEquals( \
             expect = main.TRUE,
             actual = main.ONOScli.checkFlowsState( isPENDING_ADD = False ),
-            onpass = "***Flow status is correct!***",
-            onfail = "***Flow status is wrong!***" )
+            onpass = "Flow status is correct!",
+            onfail = "Flow status is wrong!" )
         # Ping test
         main.Functions.pingSpeakerToPeer( main, speakers = ["speaker1"],
                        peers = ["peer64514", "peer64515", "peer64516"],
diff --git a/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/Functions.py b/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/Functions.py
new file mode 100644
index 0000000..8d4007a
--- /dev/null
+++ b/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/Functions.py
@@ -0,0 +1,178 @@
+
+def checkRouteNum( main, routeNumExpected, ONOScli = "ONOScli1" ):
+    main.step( "Check routes installed" )
+    main.log.info( "Route number expected:" )
+    main.log.info( routeNumExpected )
+    main.log.info( "Route number from ONOS CLI:" )
+
+    if ONOScli == "ONOScli1":
+        routeNumActual = main.ONOScli1.ipv4RouteNumber()
+    else:
+        routeNumActual = main.ONOScli2.ipv4RouteNumber()
+
+    main.log.info( routeNumActual )
+    utilities.assertEquals( \
+        expect = routeNumExpected, actual = routeNumActual,
+        onpass = "Route number is correct!",
+        onfail = "Route number is wrong!" )
+
+def checkM2SintentNum( main, intentNumExpected, ONOScli = "ONOScli1" ):
+    main.step( "Check M2S intents installed" )
+    main.log.info( "Intent number expected:" )
+    main.log.info( intentNumExpected )
+    main.log.info( "Intent number from ONOS CLI:" )
+    if ONOScli == "ONOScli1":
+        jsonResult = main.ONOScli1.intents( jsonFormat = True, summary = True,
+                                            TYPE = "multiPointToSinglePoint" )
+    else:
+        jsonResult = main.ONOScli2.intents( jsonFormat = True, summary = True,
+                                            TYPE = "multiPointToSinglePoint" )
+    intentNumActual = jsonResult['installed']
+    main.log.info( intentNumActual )
+    utilities.assertEquals( \
+        expect = intentNumExpected, actual = intentNumActual,
+        onpass = "M2S intent number is correct!",
+        onfail = "M2S intent number is wrong!" )
+
+def checkP2PintentNum( main, intentNumExpected, ONOScli = "ONOScli1" ):
+    main.step( "Check P2P intents installed" )
+    main.log.info( "Intent number expected:" )
+    main.log.info( intentNumExpected )
+    main.log.info( "Intent number from ONOS CLI:" )
+    if ONOScli == "ONOScli1":
+        jsonResult = main.ONOScli1.intents( jsonFormat = True, summary = True,
+                                            TYPE = "pointToPoint" )
+    else:
+        jsonResult = main.ONOScli2.intents( jsonFormat = True, summary = True,
+                                            TYPE = "pointToPoint" )
+    intentNumActual = jsonResult['installed']
+    main.log.info( intentNumActual )
+    utilities.assertEquals( \
+        expect = intentNumExpected, actual = intentNumActual,
+        onpass = "P2P intent number is correct!",
+        onfail = "P2P intent number is wrong!" )
+
+def checkFlowNum( main, switch, flowNumExpected ):
+    main.step( "Check flow entry number in " + switch )
+    main.log.info( "Flow number expected:" )
+    main.log.info( flowNumExpected )
+    main.log.info( "Flow number actual:" )
+    flowNumActual = main.Mininet.getSwitchFlowCount( switch )
+    main.log.info( flowNumActual )
+    utilities.assertEquals( \
+        expect = flowNumExpected, actual = flowNumActual,
+        onpass = "Flow number in " + switch + " is correct!",
+        onfail = "Flow number in " + switch + " is wrong!" )
+
+
+def pingSpeakerToPeer( main, speakers = ["speaker1"],
+                       peers = ["peer64514", "peer64515", "peer64516"],
+                       expectAllSuccess = True ):
+    """
+    Carry out ping test between each BGP speaker and peer pair
+    Optional argument:
+        * speakers - BGP speakers
+        * peers - BGP peers
+        * expectAllSuccess - boolean indicating if you expect all results
+        succeed if True, otherwise expect all results fail if False
+    """
+    if len( speakers ) == 0:
+        main.log.error( "Parameter speakers can not be empty." )
+        main.cleanup()
+        main.exit()
+    if len( peers ) == 0:
+        main.log.error( "Parameter speakers can not be empty." )
+        main.cleanup()
+        main.exit()
+
+    if expectAllSuccess:
+        main.step( "BGP speakers ping peers, expect all tests to succeed" )
+    else:
+        main.step( "BGP speakers ping peers, expect all tests to fail" )
+
+    result = True
+    if expectAllSuccess:
+        for speaker in speakers:
+            for peer in peers:
+                tmpResult = main.Mininet.pingHost( src = speaker,
+                                                   target = peer )
+                result = result and ( tmpResult == main.TRUE )
+    else:
+        for speaker in speakers:
+            for peer in peers:
+                tmpResult = main.Mininet.pingHost( src = speaker,
+                                                   target = peer )
+
+    utilities.assert_equals( expect = True, actual = result,
+                             onpass = "Ping test results are expected",
+                             onfail = "Ping test results are Not expected" )
+
+    if result == False:
+        main.cleanup()
+        main.exit()
+
+
+def pingHostToHost( main, hosts = ["host64514", "host64515", "host64516"],
+                expectAllSuccess = True ):
+    """
+    Carry out ping test between each BGP host pair
+    Optional argument:
+        * hosts - hosts behind BGP peer routers
+        * expectAllSuccess - boolean indicating if you expect all results
+        succeed if True, otherwise expect all results fail if False
+    """
+    main.step( "Check ping between each host pair" )
+    if len( hosts ) == 0:
+        main.log.error( "Parameter hosts can not be empty." )
+        main.cleanup()
+        main.exit()
+
+    result = True
+    if expectAllSuccess:
+        for srcHost in hosts:
+            for targetHost in hosts:
+                if srcHost != targetHost:
+                    tmpResult = main.Mininet.pingHost( src = srcHost,
+                                                       target = targetHost )
+                    result = result and ( tmpResult == main.TRUE )
+    else:
+        for srcHost in hosts:
+            for targetHost in hosts:
+                if srcHost != targetHost:
+                    tmpResult = main.Mininet.pingHost( src = srcHost,
+                                                       target = targetHost )
+                    result = result and ( tmpResult == main.FALSE )
+
+    utilities.assert_equals( expect = True, actual = result,
+                             onpass = "Ping test results are expected",
+                             onfail = "Ping test results are Not expected" )
+
+    '''
+    if result == False:
+        main.cleanup()
+        main.exit()
+    '''
+
+
+def setupTunnel( main, srcIp, srcPort, dstIp, dstPort ):
+    """
+    Create a tunnel from Mininet host to host outside Mininet
+    """
+    main.step( "Set up tunnel from Mininet node " +
+               str( srcIp ) + ":" + str( srcPort ) + " to ONOS node "
+               + str(dstIp) + ":" + str(dstPort) )
+    forwarding = '%s:%s:%s:%s' % ( srcIp, srcPort, dstIp, dstPort )
+    command = 'ssh -nNT -o "PasswordAuthentication no" \
+        -o "StrictHostKeyChecking no" -l sdn -L %s %s & ' % ( forwarding, dstIp )
+
+
+    tunnelResult = main.TRUE
+    tunnelResult = main.Mininet.node( "root", command )
+    utilities.assert_equals( expect = True,
+                             actual = ( "PasswordAuthentication" in tunnelResult ),
+                             onpass = "Created tunnel succeeded",
+                             onfail = "Create tunnel failed" )
+    if ( "PasswordAuthentication" not in tunnelResult ) :
+        main.cleanup()
+        main.exit()
+
diff --git a/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/USECASE_SdnipI2MN_Cluster.py b/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/USECASE_SdnipI2MN_Cluster.py
new file mode 100755
index 0000000..f5d0cfd
--- /dev/null
+++ b/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/USECASE_SdnipI2MN_Cluster.py
@@ -0,0 +1,422 @@
+#!/usr/bin/python
+
+"""
+Set up the SDN-IP topology as same as it on Internet2
+"""
+
+"""
+AS 64513, (SDN AS)
+AS 64514, reachable by 10.0.4.1, 10.0.14.1
+AS 64515, reachable by 10.0.5.1, 10.0.15.1
+AS 64516, reachable by 10.0.6.1, 10.0.16.1
+"""
+
+from mininet.net import Mininet
+from mininet.node import Controller, RemoteController
+from mininet.log import setLogLevel, info
+from mininet.cli import CLI
+from mininet.topo import Topo
+from mininet.util import quietRun
+from mininet.moduledeps import pathCheck
+
+import os.path
+import time
+from subprocess import Popen, STDOUT, PIPE
+
+QUAGGA_DIR = '/usr/lib/quagga'
+QUAGGA_RUN_DIR = '/usr/local/var/run/quagga'
+QUAGGA_CONFIG_DIR = '~/OnosSystemTest/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/'
+numSw = 39
+
+# net = Mininet( controller = RemoteController )
+
+class SDNTopo( Topo ):
+    "SDN Topology"
+
+    def __init__( self, *args, **kwargs ):
+
+        Topo.__init__( self, *args, **kwargs )
+
+        # BGP peer hosts
+        peer64514 = self.addHost( 'peer64514' )
+        peer64515 = self.addHost( 'peer64515' )
+        peer64516 = self.addHost( 'peer64516' )
+
+        '''
+        sw1 = self.addSwitch( 'SEAT', dpid = '00000000000000a1' )
+        sw2 = self.addSwitch( 'PORT', dpid = '00000000000000a2' )
+        sw3 = self.addSwitch( 'SUNN', dpid = '00000000000000a3' )
+        sw4 = self.addSwitch( 'RENO', dpid = '00000000000000a4' )
+        sw5 = self.addSwitch( 'LOSA', dpid = '00000000000000a5' )
+        sw6 = self.addSwitch( 'MISS', dpid = '00000000000000a6' )
+        sw7 = self.addSwitch( 'LASV', dpid = '00000000000000a7' )
+        sw8 = self.addSwitch( 'SALT', dpid = '00000000000000a8' )
+        sw9 = self.addSwitch( 'PHOE', dpid = '00000000000000a9' )
+        sw10 = self.addSwitch( 'TUCS', dpid = '0000000000000a10' )
+        sw11 = self.addSwitch( 'DENV', dpid = '0000000000000a11' )
+        sw12 = self.addSwitch( 'ELPA', dpid = '0000000000000a12' )
+        sw13 = self.addSwitch( 'MINN', dpid = '0000000000000a13' )
+        sw14 = self.addSwitch( 'KANS', dpid = '0000000000000a14' )
+        sw15 = self.addSwitch( 'TULS', dpid = '0000000000000a15' )
+        sw16 = self.addSwitch( 'DALL', dpid = '0000000000000a16' )
+        sw17 = self.addSwitch( 'HOUH', dpid = '0000000000000a17' )
+        sw18 = self.addSwitch( 'COLU', dpid = '0000000000000a18' )
+        sw19 = self.addSwitch( 'JCSN', dpid = '0000000000000a19' )
+        sw20 = self.addSwitch( 'BATO', dpid = '0000000000000a20' )
+        sw21 = self.addSwitch( 'EQCH', dpid = '0000000000000a21' )
+        sw22 = self.addSwitch( 'STAR', dpid = '0000000000000a22' )
+        sw23 = self.addSwitch( 'CHIC', dpid = '0000000000000a23' )
+        sw24 = self.addSwitch( 'INDI', dpid = '0000000000000a24' )
+        sw25 = self.addSwitch( 'CINC', dpid = '0000000000000a25' )
+        sw26 = self.addSwitch( 'LOUI', dpid = '0000000000000a26' )
+        sw27 = self.addSwitch( 'ATLA', dpid = '0000000000000a27' )
+        sw28 = self.addSwitch( 'JACK', dpid = '0000000000000a28' )
+        sw29 = self.addSwitch( 'CLEV', dpid = '0000000000000a29' )
+        sw30 = self.addSwitch( 'PITT', dpid = '0000000000000a30' )
+        sw31 = self.addSwitch( 'ASHB', dpid = '0000000000000a31' )
+        sw32 = self.addSwitch( 'WASH', dpid = '0000000000000a32' )
+        sw33 = self.addSwitch( 'RALE', dpid = '0000000000000a33' )
+        sw34 = self.addSwitch( 'CHAR', dpid = '0000000000000a34' )
+        sw35 = self.addSwitch( 'ALBA', dpid = '0000000000000a35' )
+        sw36 = self.addSwitch( 'BOST', dpid = '0000000000000a36' )
+        sw37 = self.addSwitch( 'HART', dpid = '0000000000000a37' )
+        sw38 = self.addSwitch( 'NEWY', dpid = '0000000000000a38' )
+        sw39 = self.addSwitch( 'PHIL', dpid = '0000000000000a39' )
+        '''
+        sw1 = self.addSwitch( 'sw1', dpid = '00000000000000a1' )
+        sw2 = self.addSwitch( 'sw2', dpid = '00000000000000a2' )
+        sw3 = self.addSwitch( 'sw3', dpid = '00000000000000a3' )
+        sw4 = self.addSwitch( 'sw4', dpid = '00000000000000a4' )
+        sw5 = self.addSwitch( 'sw5', dpid = '00000000000000a5' )
+        sw6 = self.addSwitch( 'sw6', dpid = '00000000000000a6' )
+        sw7 = self.addSwitch( 'sw7', dpid = '00000000000000a7' )
+        sw8 = self.addSwitch( 'sw8', dpid = '00000000000000a8' )
+        sw9 = self.addSwitch( 'sw9', dpid = '00000000000000a9' )
+        sw10 = self.addSwitch( 'sw10', dpid = '0000000000000a10' )
+        sw11 = self.addSwitch( 'sw11', dpid = '0000000000000a11' )
+        sw12 = self.addSwitch( 'sw12', dpid = '0000000000000a12' )
+        sw13 = self.addSwitch( 'sw13', dpid = '0000000000000a13' )
+        sw14 = self.addSwitch( 'sw14', dpid = '0000000000000a14' )
+        sw15 = self.addSwitch( 'sw15', dpid = '0000000000000a15' )
+        sw16 = self.addSwitch( 'sw16', dpid = '0000000000000a16' )
+        sw17 = self.addSwitch( 'sw17', dpid = '0000000000000a17' )
+        sw18 = self.addSwitch( 'sw18', dpid = '0000000000000a18' )
+        sw19 = self.addSwitch( 'sw19', dpid = '0000000000000a19' )
+        sw20 = self.addSwitch( 'sw20', dpid = '0000000000000a20' )
+        sw21 = self.addSwitch( 'sw21', dpid = '0000000000000a21' )
+        sw22 = self.addSwitch( 'sw22', dpid = '0000000000000a22' )
+        sw23 = self.addSwitch( 'sw23', dpid = '0000000000000a23' )
+        sw24 = self.addSwitch( 'sw24', dpid = '0000000000000a24' )
+        sw25 = self.addSwitch( 'sw25', dpid = '0000000000000a25' )
+        sw26 = self.addSwitch( 'sw26', dpid = '0000000000000a26' )
+        sw27 = self.addSwitch( 'sw27', dpid = '0000000000000a27' )
+        sw28 = self.addSwitch( 'sw28', dpid = '0000000000000a28' )
+        sw29 = self.addSwitch( 'sw29', dpid = '0000000000000a29' )
+        sw30 = self.addSwitch( 'sw30', dpid = '0000000000000a30' )
+        sw31 = self.addSwitch( 'sw31', dpid = '0000000000000a31' )
+        sw32 = self.addSwitch( 'sw32', dpid = '0000000000000a32' )
+        sw33 = self.addSwitch( 'sw33', dpid = '0000000000000a33' )
+        sw34 = self.addSwitch( 'sw34', dpid = '0000000000000a34' )
+        sw35 = self.addSwitch( 'sw35', dpid = '0000000000000a35' )
+        sw36 = self.addSwitch( 'sw36', dpid = '0000000000000a36' )
+        sw37 = self.addSwitch( 'sw37', dpid = '0000000000000a37' )
+        sw38 = self.addSwitch( 'sw38', dpid = '0000000000000a38' )
+        sw39 = self.addSwitch( 'sw39', dpid = '0000000000000a39' )
+
+
+        # Add a layer2 switch for control plane connectivity
+        # This switch isn't part of the SDN topology
+        # We'll use the ovs-controller to turn this into a learning switch
+        swCtl100 = self.addSwitch( 'swCtl100', dpid = '0000000000000100' )
+
+
+        # BGP speaker hosts
+        speaker1 = self.addHost( 'speaker1' )
+        speaker2 = self.addHost( 'speaker2' )
+
+        root = self.addHost( 'root', inNamespace = False , ip = '0' )
+
+        # hosts behind each AS
+        host64514 = self.addHost( 'host64514' )
+        host64515 = self.addHost( 'host64515' )
+        host64516 = self.addHost( 'host64516' )
+
+        self.addLink( 'speaker1', sw24 )
+        self.addLink( 'speaker2', sw24 )
+
+        # connect all switches
+        self.addLink( sw1, sw2 )
+        self.addLink( sw1, sw6 )
+        self.addLink( sw1, sw8 )
+        self.addLink( sw2, sw3 )
+        self.addLink( sw3, sw4 )
+        self.addLink( sw3, sw5 )
+        self.addLink( sw4, sw8 )
+        self.addLink( sw5, sw7 )
+        self.addLink( sw5, sw9 )
+        self.addLink( sw6, sw13 )
+        self.addLink( sw7, sw8 )
+        self.addLink( sw8, sw11 )
+        self.addLink( sw9, sw10 )
+        self.addLink( sw10, sw12 )
+        self.addLink( sw11, sw12 )
+        self.addLink( sw11, sw14 )
+        self.addLink( sw12, sw17 )
+        self.addLink( sw13, sw14 )
+        self.addLink( sw13, sw21 )
+        self.addLink( sw14, sw15 )
+        self.addLink( sw14, sw18 )
+        self.addLink( sw14, sw23 )
+        self.addLink( sw15, sw16 )
+        self.addLink( sw16, sw17 )
+        self.addLink( sw17, sw19 )
+        self.addLink( sw17, sw20 )
+        self.addLink( sw18, sw23 )
+        self.addLink( sw19, sw27 )
+        self.addLink( sw20, sw28 )
+        self.addLink( sw21, sw22 )
+        self.addLink( sw21, sw29 )
+        self.addLink( sw22, sw23 )
+        self.addLink( sw23, sw24 )
+        self.addLink( sw23, sw31 )
+        self.addLink( sw24, sw25 )
+        self.addLink( sw25, sw26 )
+        self.addLink( sw26, sw27 )
+        self.addLink( sw27, sw28 )
+        self.addLink( sw27, sw34 )
+        self.addLink( sw29, sw30 )
+        self.addLink( sw29, sw35 )
+        self.addLink( sw30, sw31 )
+        self.addLink( sw31, sw32 )
+        self.addLink( sw32, sw33 )
+        self.addLink( sw32, sw39 )
+        self.addLink( sw33, sw34 )
+        self.addLink( sw35, sw36 )
+        self.addLink( sw36, sw37 )
+        self.addLink( sw37, sw38 )
+        self.addLink( sw38, sw39 )
+
+        # connection between switches and peers
+        self.addLink( peer64514, sw32 )
+        self.addLink( peer64515, sw8 )
+        self.addLink( peer64516, sw28 )
+
+        # connection between BGP peer and hosts behind the BGP peer
+        self.addLink( peer64514, host64514 )
+        self.addLink( peer64515, host64515 )
+        self.addLink( peer64516, host64516 )
+
+        # Internal Connection To Hosts
+        self.addLink( swCtl100, peer64514 )
+        self.addLink( swCtl100, peer64515 )
+        self.addLink( swCtl100, peer64516 )
+        self.addLink( swCtl100, speaker1 )
+        self.addLink( swCtl100, speaker2 )
+
+
+        # add host64514 to control plane for ping test
+        self.addLink( swCtl100, host64514 )
+        self.addLink( swCtl100, root )
+        self.addLink( swCtl100, root )
+        self.addLink( swCtl100, root )
+
+
+def startsshd( host ):
+    "Start sshd on host"
+    info( '*** Starting sshd\n' )
+    name, intf, ip = host.name, host.defaultIntf(), host.IP()
+    banner = '/tmp/%s.banner' % name
+    host.cmd( 'echo "Welcome to %s at %s" >  %s' % ( name, ip, banner ) )
+    host.cmd( '/usr/sbin/sshd -o "Banner %s"' % banner, '-o "UseDNS no"' )
+    info( '***', host.name, 'is running sshd on', intf, 'at', ip, '\n' )
+
+def startsshds ( hosts ):
+    for h in hosts:
+        startsshd( h )
+
+def stopsshd():
+    "Stop *all* sshd processes with a custom banner"
+    info( '*** Shutting down stale sshd/Banner processes ',
+          quietRun( "pkill -9 -f Banner" ), '\n' )
+
+def startquagga( host, num, config_file ):
+    info( '*** Starting Quagga on %s\n' % host )
+    host.cmd( "cd %s" % QUAGGA_CONFIG_DIR )
+    zebra_cmd = \
+    '%s/zebra -d -f  ./zebra.conf -z %s/zserv%s.api -i %s/zebra%s.pid'\
+     % ( QUAGGA_DIR, QUAGGA_RUN_DIR, num, QUAGGA_RUN_DIR, num )
+    quagga_cmd = '%s/bgpd -d -f %s -z %s/zserv%s.api -i %s/bgpd%s.pid' \
+    % ( QUAGGA_DIR, config_file, QUAGGA_RUN_DIR, num, QUAGGA_RUN_DIR, num )
+
+    print zebra_cmd
+    print quagga_cmd
+
+    host.cmd( zebra_cmd )
+    host.cmd( quagga_cmd )
+
+'''
+def startQuaggaFromTeston( host, num, config_file ):
+    global net
+    h = net.get( str( host ) )
+    startquagga( h, num, config_file )
+'''
+
+def startquaggahost5( host, num ):
+    info( '*** Starting Quagga on %s\n' % host )
+    zebra_cmd = \
+    '%s/zebra -d -f  ./zebra.conf -z %s/zserv%s.api -i %s/zebra%s.pid' \
+    % ( QUAGGA_DIR, QUAGGA_RUN_DIR, num, QUAGGA_RUN_DIR, num )
+    quagga_cmd = \
+    '%s/bgpd -d -f ./as4quaggas/quagga%s.conf -z %s/zserv%s.api -i %s/bgpd%s.pid'\
+     % ( QUAGGA_DIR, num, QUAGGA_RUN_DIR, num, QUAGGA_RUN_DIR, num )
+
+    host.cmd( zebra_cmd )
+    host.cmd( quagga_cmd )
+
+
+def stopquagga():
+    quietRun( 'sudo pkill -9 -f bgpd' )
+    quietRun( 'sudo pkill -9 -f zebra' )
+
+def sdn1net():
+    topo = SDNTopo()
+    info( '*** Creating network\n' )
+
+    # global net
+    net = Mininet( topo = topo, controller = RemoteController )
+
+
+    speaker1, speaker2, peer64514, peer64515, peer64516 = \
+    net.get( 'speaker1', 'speaker2' ,
+             'peer64514', 'peer64515', 'peer64516' )
+
+    # Adding addresses to speakers' interface connected to sw24
+    # for BGP peering
+    speaker1.setMAC( '00:00:00:00:00:01', 'speaker1-eth0' )
+    speaker1.cmd( 'ip addr add 10.0.4.101/24 dev speaker1-eth0' )
+    speaker1.cmd( 'ip addr add 10.0.5.101/24 dev speaker1-eth0' )
+    speaker1.cmd( 'ip addr add 10.0.6.101/24 dev speaker1-eth0' )
+
+    speaker1.defaultIntf().setIP( '10.0.4.101/24' )
+    speaker1.defaultIntf().setMAC( '00:00:00:00:00:01' )
+
+    speaker2.setMAC( '00:00:00:00:00:02', 'speaker2-eth0' )
+    speaker2.cmd( 'ip addr add 10.0.14.101/24 dev speaker2-eth0' )
+    speaker2.cmd( 'ip addr add 10.0.15.101/24 dev speaker2-eth0' )
+    speaker2.cmd( 'ip addr add 10.0.16.101/24 dev speaker2-eth0' )
+
+    speaker2.defaultIntf().setIP( '10.0.14.101/24' )
+    speaker2.defaultIntf().setMAC( '00:00:00:00:00:02' )
+
+    # Net has to be start after adding the above link
+    net.start()
+
+    # setup configuration on the interface connected to switch
+    peer64514.cmd( "ifconfig  peer64514-eth0 10.0.4.1 up" )
+    peer64514.cmd( "ip addr add 10.0.14.1/24 dev peer64514-eth0" )
+    peer64514.setMAC( '00:00:00:00:00:04', 'peer64514-eth0' )
+    peer64515.cmd( "ifconfig  peer64515-eth0 10.0.5.1 up" )
+    peer64515.cmd( "ip addr add 10.0.15.1/24 dev peer64515-eth0" )
+    peer64515.setMAC( '00:00:00:00:00:05', 'peer64515-eth0' )
+    peer64516.cmd( "ifconfig  peer64516-eth0 10.0.6.1 up" )
+    peer64516.cmd( "ip addr add 10.0.16.1/24 dev peer64516-eth0" )
+    peer64516.setMAC( '00:00:00:00:00:06', 'peer64516-eth0' )
+
+    # setup configuration on the interface connected to hosts
+    peer64514.setIP( "4.0.0.254", 8, "peer64514-eth1" )
+    peer64514.setMAC( '00:00:00:00:00:44', 'peer64514-eth1' )
+    peer64515.setIP( "5.0.0.254", 8, "peer64515-eth1" )
+    peer64515.setMAC( '00:00:00:00:00:55', 'peer64515-eth1' )
+    peer64516.setIP( "6.0.0.254", 8, "peer64516-eth1" )
+    peer64516.setMAC( '00:00:00:00:00:66', 'peer64516-eth1' )
+
+    # enable forwarding on BGP peer hosts
+    peer64514.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
+    peer64515.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
+    peer64516.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
+
+    # config interface for control plane connectivity
+    peer64514.setIP( "192.168.0.4", 24, "peer64514-eth2" )
+    peer64515.setIP( "192.168.0.5", 24, "peer64515-eth2" )
+    peer64516.setIP( "192.168.0.6", 24, "peer64516-eth2" )
+
+    # Setup hosts in each non-SDN AS
+    host64514, host64515, host64516 = \
+    net.get( 'host64514', 'host64515', 'host64516' )
+    host64514.cmd( 'ifconfig host64514-eth0 4.0.0.1 up' )
+    host64514.cmd( 'ip route add default via 4.0.0.254' )
+    host64514.setIP( '192.168.0.44', 24, 'host64514-eth1' )  # for control plane
+    host64515.cmd( 'ifconfig host64515-eth0 5.0.0.1 up' )
+    host64515.cmd( 'ip route add default via 5.0.0.254' )
+    host64516.cmd( 'ifconfig host64516-eth0 6.0.0.1 up' )
+    host64516.cmd( 'ip route add default via 6.0.0.254' )
+
+
+    # set up swCtl100 as a learning
+    swCtl100 = net.get( 'swCtl100' )
+    swCtl100.cmd( 'ovs-vsctl set-controller swCtl100 none' )
+    swCtl100.cmd( 'ovs-vsctl set-fail-mode swCtl100 standalone' )
+
+    # connect all switches to controller
+    '''
+    onos1IP = "10.128.4.52"
+    onos2IP = "10.128.4.53"
+    onos3IP = "10.128.4.54"
+    for i in range ( 1, numSw + 1 ):
+        swX = net.get( 'sw%s' % ( i ) )
+        swX.cmd( 'ovs-vsctl set-controller sw%s tcp:%s:6653 tcp:%s:6653 tcp:%s:6653' % ( i, onos1IP, onos2IP, onos3IP) )
+    '''
+
+    # Start Quagga on border routers
+    startquagga( peer64514, 64514, 'quagga64514.conf' )
+    startquagga( peer64515, 64515, 'quagga64515.conf' )
+    startquagga( peer64516, 64516, 'quagga64516.conf' )
+
+    # start Quagga in SDN network
+    startquagga( speaker1, 64513, 'quagga-sdn.conf' )
+    startquagga( speaker2, 64512, 'quagga-sdn-speaker2.conf' )
+
+
+    root = net.get( 'root' )
+    root.intf( 'root-eth0' ).setIP( '1.1.1.2/24' )
+    root.cmd( 'ip addr add 192.168.0.100/24 dev root-eth0' )
+
+    root.intf( 'root-eth1' ).setIP( '1.1.1.4/24' )
+    root.cmd( 'ip addr add 192.168.0.101/24 dev root-eth1' )
+
+    root.intf( 'root-eth2' ).setIP( '1.1.1.6/24' )
+    root.cmd( 'ip addr add 192.168.0.102/24 dev root-eth2' )
+
+    speaker1.intf( 'speaker1-eth1' ).setIP( '1.1.1.1/24' )
+    speaker2.intf( 'speaker2-eth1' ).setIP( '1.1.1.3/24' )
+
+
+    stopsshd()
+
+    hosts = [ peer64514, peer64515, peer64516, host64514];
+    startsshds( hosts )
+
+
+    '''
+    forwarding1 = '%s:2000:%s:2000' % ( '1.1.1.2', onos1IP )
+    root.cmd( 'ssh -nNT -o "PasswordAuthentication no" \
+    -o "StrictHostKeyChecking no" -l sdn -L %s %s & ' % ( forwarding1, onos1IP ) )
+
+    forwarding2 = '%s:2000:%s:2000' % ( '1.1.1.4', onos2IP )
+    root.cmd( 'ssh -nNT -o "PasswordAuthentication no" \
+    -o "StrictHostKeyChecking no" -l sdn -L %s %s & ' % ( forwarding2, onos2IP ) )
+
+    forwarding3 = '%s:2000:%s:2000' % ( '1.1.1.6', onos3IP )
+    root.cmd( 'ssh -nNT -o "PasswordAuthentication no" \
+    -o "StrictHostKeyChecking no" -l sdn -L %s %s & ' % ( forwarding3, onos3IP ) )
+    '''
+    CLI( net )
+
+    stopsshd()
+    stopquagga()
+    net.stop()
+
+
+if __name__ == '__main__':
+    setLogLevel( 'debug' )
+    sdn1net()
diff --git a/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/quagga-sdn-speaker2.conf b/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/quagga-sdn-speaker2.conf
new file mode 100644
index 0000000..256e7e8
--- /dev/null
+++ b/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/quagga-sdn-speaker2.conf
@@ -0,0 +1,49 @@
+! -*- bgp -*-
+!
+! BGPd sample configuratin file
+!
+! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $
+!
+hostname bgpd
+password hello
+!enable password please-set-at-here
+!
+!bgp mulitple-instance
+!
+!
+router bgp 64513
+  bgp router-id 10.0.14.101
+  timers bgp 1 3
+  !timers bgp 3 9
+  neighbor 10.0.14.1 remote-as 64514
+  neighbor 10.0.14.1 ebgp-multihop
+  neighbor 10.0.14.1 timers connect 5
+  neighbor 10.0.15.1 remote-as 64515
+  neighbor 10.0.15.1 ebgp-multihop
+  neighbor 10.0.15.1 timers connect 5
+  neighbor 10.0.16.1 remote-as 64516
+  neighbor 10.0.16.1 ebgp-multihop
+  neighbor 10.0.16.1 timers connect 5
+
+  neighbor 1.1.1.2 remote-as 64513
+  neighbor 1.1.1.2 port 2000
+  neighbor 1.1.1.2 timers connect 5
+
+  neighbor 1.1.1.4 remote-as 64513
+  neighbor 1.1.1.4 port 2000
+  neighbor 1.1.1.4 timers connect 5
+
+  neighbor 1.1.1.6 remote-as 64513
+  neighbor 1.1.1.6 port 2000
+  neighbor 1.1.1.6 timers connect 5
+
+!
+! access-list all permit any
+!
+!route-map set-nexthop permit 10
+! match ip address all
+! set ip next-hop 10.0.0.1
+!
+!log file /usr/local/var/log/quagga/bgpd.log
+!
+log stdout
diff --git a/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/quagga-sdn.conf b/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/quagga-sdn.conf
new file mode 100644
index 0000000..3d2a455
--- /dev/null
+++ b/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/quagga-sdn.conf
@@ -0,0 +1,49 @@
+! -*- bgp -*-
+!
+! BGPd sample configuratin file
+!
+! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $
+!
+hostname bgpd
+password hello
+!enable password please-set-at-here
+!
+!bgp mulitple-instance
+!
+!
+router bgp 64513
+  bgp router-id 10.0.4.101
+  timers bgp 1 3
+  !timers bgp 3 9
+  neighbor 10.0.4.1 remote-as 64514
+  neighbor 10.0.4.1 ebgp-multihop
+  neighbor 10.0.4.1 timers connect 5
+  neighbor 10.0.5.1 remote-as 64515
+  neighbor 10.0.5.1 ebgp-multihop
+  neighbor 10.0.5.1 timers connect 5
+  neighbor 10.0.6.1 remote-as 64516
+  neighbor 10.0.6.1 ebgp-multihop
+  neighbor 10.0.6.1 timers connect 5
+
+  neighbor 1.1.1.2 remote-as 64513
+  neighbor 1.1.1.2 port 2000
+  neighbor 1.1.1.2 timers connect 5
+
+  neighbor 1.1.1.4 remote-as 64513
+  neighbor 1.1.1.4 port 2000
+  neighbor 1.1.1.4 timers connect 5
+
+  neighbor 1.1.1.6 remote-as 64513
+  neighbor 1.1.1.6 port 2000
+  neighbor 1.1.1.6 timers connect 5
+
+!
+! access-list all permit any
+!
+!route-map set-nexthop permit 10
+! match ip address all
+! set ip next-hop 10.0.0.1
+!
+!log file /usr/local/var/log/quagga/bgpd.log
+!
+log stdout
diff --git a/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/quagga64514.conf b/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/quagga64514.conf
new file mode 100644
index 0000000..cc056dd
--- /dev/null
+++ b/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/quagga64514.conf
@@ -0,0 +1,29 @@
+! -*- bgp -*-
+!
+! BGPd sample configuratin file
+!
+! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $
+!
+hostname bgpd
+password hello
+!enable password please-set-at-here
+!
+!bgp mulitple-instance
+!
+router bgp 64514
+  bgp router-id 10.0.4.1
+!  timers bgp 1 3
+ neighbor 10.0.4.101 remote-as 64513
+ neighbor 10.0.14.101 remote-as 64513
+ network 4.0.0.0/24
+
+!
+! access-list all permit any
+!
+!route-map set-nexthop permit 10
+! match ip address all
+! set ip next-hop 10.0.0.1
+!
+!log file /usr/local/var/log/quagga/bgpd.log
+!
+log stdout
\ No newline at end of file
diff --git a/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/quagga64515.conf b/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/quagga64515.conf
new file mode 100644
index 0000000..7b45d57
--- /dev/null
+++ b/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/quagga64515.conf
@@ -0,0 +1,29 @@
+! -*- bgp -*-
+!
+! BGPd sample configuratin file
+!
+! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $
+!
+hostname bgpd
+password hello
+!enable password please-set-at-here
+!
+!bgp mulitple-instance
+!
+router bgp 64515
+  bgp router-id 10.0.5.1
+!  timers bgp 1 3
+ neighbor 10.0.5.101 remote-as 64513
+ neighbor 10.0.15.101 remote-as 64513
+ network 5.0.0.0/24
+
+!
+! access-list all permit any
+!
+!route-map set-nexthop permit 10
+! match ip address all
+! set ip next-hop 10.0.0.1
+!
+!log file /usr/local/var/log/quagga/bgpd.log
+!
+log stdout
diff --git a/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/quagga64516.conf b/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/quagga64516.conf
new file mode 100644
index 0000000..20c104e
--- /dev/null
+++ b/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/quagga64516.conf
@@ -0,0 +1,32 @@
+! -*- bgp -*-
+!
+! BGPd sample configuratin file
+!
+! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $
+!
+hostname bgpd
+password hello
+!enable password please-set-at-here
+!
+!bgp mulitple-instance
+!
+router bgp 64516
+  bgp router-id 10.0.6.1
+!  timers bgp 1 3
+ neighbor 10.0.6.101 remote-as 64513
+ neighbor 10.0.16.101 remote-as 64513
+ network 6.0.0.0/24
+
+! neighbor 10.0.0.2 route-map set-nexthop out
+! neighbor 10.0.0.2 ebgp-multihop
+! neighbor 10.0.0.2 next-hop-self
+!
+! access-list all permit any
+!
+!route-map set-nexthop permit 10
+! match ip address all
+! set ip next-hop 10.0.0.1
+!
+!log file /usr/local/var/log/quagga/bgpd.log
+!
+log stdout
diff --git a/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/zebra.conf b/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/zebra.conf
new file mode 100644
index 0000000..517db94
--- /dev/null
+++ b/TestON/tests/USECASE_SdnipFunctionCluster/Dependency/zebra.conf
@@ -0,0 +1,26 @@
+! -*- zebra -*-
+!
+! zebra sample configuration file
+!
+! $Id: zebra.conf.sample,v 1.1 2002/12/13 20:15:30 paul Exp $
+!
+hostname zebra
+password hello
+enable password 0fw0rk
+log stdout
+!
+! Interfaces description.
+!
+!interface lo
+! description test of desc.
+!
+!interface sit0
+! multicast
+
+!
+! Static default route sample.
+!
+!ip route 0.0.0.0/0 203.181.89.241
+!
+
+!log file /usr/local/var/log/quagga/zebra.log
diff --git a/TestON/tests/USECASE_SdnipFunctionCluster/USECASE_SdnipFunctionCluster.params b/TestON/tests/USECASE_SdnipFunctionCluster/USECASE_SdnipFunctionCluster.params
new file mode 100644
index 0000000..c746f55
--- /dev/null
+++ b/TestON/tests/USECASE_SdnipFunctionCluster/USECASE_SdnipFunctionCluster.params
@@ -0,0 +1,51 @@
+<PARAMS>
+
+    <testcases>101, 100, 200, 102, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12</testcases>
+    #Environment variables
+    <ENV>
+        <cellName>sdnip_multiple_instance_BM</cellName>
+    </ENV>
+
+    <CTRL>
+        <numCtrl>1</numCtrl>
+        <ip1>OC1</ip1>
+        <ip2>OC2</ip2>
+        <ip3>OC3</ip3>
+        <port1>6653</port1>
+    </CTRL>
+
+    <GIT>
+        <branch1>master</branch1>
+        <branch2>onos-1.3</branch2>
+    </GIT>
+
+    <JSON>
+        <prefix>prefix</prefix>
+        <nextHop>nextHop</nextHop>
+    </JSON>
+
+    <DEPENDENCY>
+        <path>/USECASE_SdnipFunctionCluster/Dependency/</path>
+        <topology>USECASE_SdnipI2MN_Cluster.py</topology>
+        <wrapper1>Functions</wrapper1>
+        <wrapper2>USECASE_SdnipI2MN_Cluster</wrapper2>
+    </DEPENDENCY>
+
+    <config>
+        <peerNum> 3 </peerNum>
+        <switchNum> 39 </switchNum>
+        <peer64514> 10.0.14.1</peer64514>
+        <peer64515> 10.0.15.1</peer64515>
+        <peer64516> 10.0.16.1</peer64516>
+    </config>
+
+    <timers>
+        <SdnIpSetup>10</SdnIpSetup>
+        <TopoDiscovery>10</TopoDiscovery>
+        <PingTestWithRoutes>20</PingTestWithRoutes>
+        <PingTestWithoutRoutes>100</PingTestWithoutRoutes>
+        <RouteDelivery>30</RouteDelivery>
+        <PathAvailable>20</PathAvailable>
+    </timers>
+
+</PARAMS>
diff --git a/TestON/tests/USECASE_SdnipFunctionCluster/USECASE_SdnipFunctionCluster.py b/TestON/tests/USECASE_SdnipFunctionCluster/USECASE_SdnipFunctionCluster.py
new file mode 100644
index 0000000..0c0844d
--- /dev/null
+++ b/TestON/tests/USECASE_SdnipFunctionCluster/USECASE_SdnipFunctionCluster.py
@@ -0,0 +1,841 @@
+# Testing the functionality of SDN-IP with single ONOS instance
+class USECASE_SdnipFunctionCluster:
+
+    def __init__( self ):
+        self.default = ''
+        global branchName
+
+    def CASE100( self, main ):
+        """
+            Start mininet
+        """
+        import imp
+        main.log.case( "Setup the Mininet testbed" )
+        main.dependencyPath = main.testDir + \
+                              main.params[ 'DEPENDENCY' ][ 'path' ]
+        main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
+
+        main.step( "Starting Mininet Topology" )
+        topology = main.dependencyPath + main.topology
+        topoResult = main.Mininet.startNet( topoFile = topology )
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = topoResult,
+                                 onpass = "Successfully loaded topology",
+                                 onfail = "Failed to load topology" )
+        # Exit if topology did not load properly
+        if not topoResult:
+            main.cleanup()
+            main.exit()
+        main.step( "Connect switches to controllers" )
+
+        # connect all switches to controllers
+        swResult = main.TRUE
+        for i in range ( 1, int( main.params['config']['switchNum'] ) + 1 ):
+            sw = "sw%s" % ( i )
+            swResult = swResult and main.Mininet.assignSwController( sw,
+                                                 [ONOS1Ip, ONOS2Ip, ONOS3Ip] )
+
+        utilities.assert_equals( expect = main.TRUE,
+                             actual = swResult,
+                             onpass = "Successfully connect all switches to ONOS",
+                             onfail = "Failed to connect all switches to ONOS" )
+        if not swResult:
+            main.cleanup()
+            main.exit()
+
+
+    def CASE101( self, main ):
+        """
+           Package ONOS and install it
+           Startup sequence:
+           cell <name>
+           onos-verify-cell
+           onos-package
+           onos-install -f
+           onos-wait-for-start
+        """
+        import json
+        import time
+        import os
+        from operator import eq
+
+        main.case( "Setting up ONOS environment" )
+
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        global ONOS1Ip
+        global ONOS2Ip
+        global ONOS3Ip
+        ONOS1Ip = os.getenv( main.params[ 'CTRL' ][ 'ip1' ] )
+        ONOS2Ip = os.getenv( main.params[ 'CTRL' ][ 'ip2' ] )
+        ONOS3Ip = os.getenv( main.params[ 'CTRL' ][ 'ip3' ] )
+
+        global peer64514
+        global peer64515
+        global peer64516
+        peer64514 = main.params['config']['peer64514']
+        peer64515 = main.params['config']['peer64515']
+        peer64516 = main.params['config']['peer64516']
+
+        main.step( "Applying cell variable to environment" )
+        cellResult = main.ONOSbench.setCell( cellName )
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = cellResult,
+                                 onpass = "Set cell succeeded",
+                                 onfail = "Set cell failed" )
+
+        verifyResult = main.ONOSbench.verifyCell()
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = verifyResult,
+                                 onpass = "Verify cell succeeded",
+                                 onfail = "Verify cell failed" )
+
+        branchName = main.ONOSbench.getBranchName()
+        main.log.report( "ONOS is on branch: " + branchName )
+
+        main.log.step( "Uninstalling ONOS" )
+        uninstallResult = main.ONOSbench.onosUninstall( ONOS1Ip ) \
+                          and main.ONOSbench.onosUninstall( ONOS2Ip ) \
+                          and main.ONOSbench.onosUninstall( ONOS3Ip )
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = uninstallResult,
+                                 onpass = "Uninstall ONOS from nodes succeeded",
+                                 onfail = "Uninstall ONOS form nodes failed" )
+
+        main.ONOSbench.getVersion( report = True )
+
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.onosPackage( opTimeout = 500 )
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = packageResult,
+                                 onpass = "Package ONOS succeeded",
+                                 onfail = "Package ONOS failed" )
+
+        main.step( "Installing ONOS package" )
+        onos1InstallResult = main.ONOSbench.onosInstall( options = "-f",
+                                                         node = ONOS1Ip )
+        onos2InstallResult = main.ONOSbench.onosInstall( options = "-f",
+                                                         node = ONOS2Ip )
+        onos3InstallResult = main.ONOSbench.onosInstall( options = "-f",
+                                                         node = ONOS3Ip )
+        onosInstallResult = onos1InstallResult and onos2InstallResult \
+                            and onos3InstallResult
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = onosInstallResult,
+                                 onpass = "Install ONOS to nodes succeeded",
+                                 onfail = "Install ONOS to nodes failed" )
+
+        main.step( "Checking if ONOS is up yet" )
+        onos1UpResult = main.ONOSbench.isup( ONOS1Ip, timeout = 420 )
+        onos2UpResult = main.ONOSbench.isup( ONOS2Ip, timeout = 420 )
+        onos3UpResult = main.ONOSbench.isup( ONOS3Ip, timeout = 420 )
+        onosUpResult = onos1UpResult and onos2UpResult and onos3UpResult
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = onos1UpResult and onosUpResult,
+                                 onpass = "ONOS nodes are up",
+                                 onfail = "ONOS nodes are NOT up" )
+
+        main.step( "Checking if ONOS CLI is ready" )
+        cliResult1 = main.ONOScli1.startOnosCli( ONOS1Ip,
+                commandlineTimeout = 100, onosStartTimeout = 600 )
+        cliResult2 = main.ONOScli2.startOnosCli( ONOS2Ip,
+                commandlineTimeout = 100, onosStartTimeout = 600 )
+        cliResult = cliResult1 and cliResult2
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = cliResult,
+                                 onpass = "ONOS CLI (on node1) is ready",
+                                 onfail = "ONOS CLI (on node1) ready" )
+
+        caseResult = ( cellResult and verifyResult and
+                       packageResult and
+                       onosInstallResult and onosUpResult and cliResult )
+
+        utilities.assert_equals( expect = main.TRUE, actual = caseResult,
+                                 onpass = "ONOS startup successful",
+                                 onfail = "ONOS startup NOT successful" )
+
+        if caseResult == main.FALSE:
+            main.log.error( "ONOS startup failed!" )
+            main.cleanup()
+            main.exit()
+
+
+    def CASE200( self, main ):
+        main.case( "Activate sdn-ip application" )
+        main.log.info( "waiting link discovery......" )
+        time.sleep( int ( main.params['timers']['TopoDiscovery'] ) )
+
+        main.log.info( "Get links in the network" )
+        summaryResult = main.ONOScli1.summary()
+        linkNum = json.loads( summaryResult )[ "links" ]
+        listResult = main.ONOScli1.links( jsonFormat = False )
+        main.log.info( listResult )
+
+        if linkNum < 100:
+            main.log.error( "Link number is wrong!" )
+            main.cleanup()
+            main.exit()
+
+        main.step( "Activate sdn-ip application" )
+        activeSDNIPresult = main.ONOScli1.activateApp( "org.onosproject.sdnip" )
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = activeSDNIPresult,
+                                 onpass = "Activate SDN-IP succeeded",
+                                 onfail = "Activate SDN-IP failed" )
+        if not activeSDNIPresult:
+            main.cleanup()
+            main.exit()
+
+        # TODO should be deleted in the future after the SDN-IP bug is fixed
+        main.ONOScli1.deactivateApp( "org.onosproject.sdnip" )
+        main.ONOScli1.activateApp( "org.onosproject.sdnip" )
+
+
+    def CASE102( self, main ):
+        '''
+        This test case is to load the methods from other Python files, and create
+        tunnels from mininet host to onos nodes.
+        '''
+        import time
+        main.case( "Load methods from other Python file and create tunnels" )
+        # load the methods from other file
+        wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
+        main.Functions = imp.load_source( wrapperFile1,
+                                          main.dependencyPath +
+                                          wrapperFile1 +
+                                          ".py" )
+        # Create tunnels
+        main.Functions.setupTunnel( main, '1.1.1.2', 2000, ONOS1Ip, 2000 )
+        main.Functions.setupTunnel( main, '1.1.1.4', 2000, ONOS2Ip, 2000 )
+        main.Functions.setupTunnel( main, '1.1.1.6', 2000, ONOS3Ip, 2000 )
+
+        main.log.info( "Wait SDN-IP to finish installing connectivity intents \
+        and the BGP paths in data plane are ready..." )
+        time.sleep( int( main.params[ 'timers' ][ 'SdnIpSetup' ] ) )
+
+        main.log.info( "Wait Quagga to finish delivery all routes to each \
+        other and to sdn-ip, plus finish installing all intents..." )
+        time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+        # TODO
+        # time.sleep( int( main.params[ 'timers' ][ 'PathAvailable' ] ) )
+
+        '''
+        # TODO: use for together with wrapperFile1
+        wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
+        main.USECASE_SdnipI2MN_Cluster = imp.load_source( wrapperFile2,
+                                                         main.dependencyPath +
+                                                         wrapperFile2 +
+                                                         ".py" )
+        '''
+
+
+    def CASE1( self, main ):
+        '''
+        ping test from 3 bgp peers to BGP speaker
+        '''
+
+        main.case( "Ping tests between BGP peers and speakers" )
+        main.Functions.pingSpeakerToPeer( main, speakers = ["speaker1"],
+                       peers = ["peer64514", "peer64515", "peer64516"],
+                       expectAllSuccess = True )
+        main.Functions.pingSpeakerToPeer( main, speakers = ["speaker2"],
+                       peers = [peer64514, peer64515, peer64516],
+                       expectAllSuccess = True )
+
+
+    def CASE2( self, main ):
+        '''
+        point-to-point intents test for each BGP peer and BGP speaker pair
+        '''
+        main.case( "Check point-to-point intents" )
+        main.log.info( "There are %s BGP peers in total "
+                       % main.params[ 'config' ][ 'peerNum' ] )
+        main.step( "Check P2P intents number from ONOS CLI" )
+
+        getIntentsResult = main.ONOScli1.intents( jsonFormat = True )
+        bgpIntentsActualNum = \
+            main.QuaggaCliSpeaker1.extractActualBgpIntentNum( getIntentsResult )
+        bgpIntentsExpectedNum = int( main.params[ 'config' ][ 'peerNum' ] ) * 6 * 2
+        main.log.info( "bgpIntentsExpected num is:" )
+        main.log.info( bgpIntentsExpectedNum )
+        main.log.info( "bgpIntentsActual num is:" )
+        main.log.info( bgpIntentsActualNum )
+        utilities.assertEquals( \
+            expect = True,
+            actual = eq( bgpIntentsExpectedNum, bgpIntentsActualNum ),
+            onpass = "PointToPointIntent Intent Num is correct!",
+            onfail = "PointToPointIntent Intent Num is wrong!" )
+
+
+    def CASE3( self, main ):
+        '''
+        routes and intents check to all BGP peers
+        '''
+        main.case( "Check routes and M2S intents to all BGP peers" )
+
+        allRoutesExpected = []
+        allRoutesExpected.append( "4.0.0.0/24" + "/" + "10.0.4.1" )
+        allRoutesExpected.append( "5.0.0.0/24" + "/" + "10.0.5.1" )
+        allRoutesExpected.append( "6.0.0.0/24" + "/" + "10.0.6.1" )
+
+        getRoutesResult = main.ONOScli1.routes( jsonFormat = True )
+        allRoutesActual = \
+            main.QuaggaCliSpeaker1.extractActualRoutesMaster( getRoutesResult )
+        allRoutesStrExpected = str( sorted( allRoutesExpected ) )
+        allRoutesStrActual = str( allRoutesActual ).replace( 'u', "" )
+
+        main.step( "Check routes installed" )
+        main.log.info( "Routes expected:" )
+        main.log.info( allRoutesStrExpected )
+        main.log.info( "Routes get from ONOS CLI:" )
+        main.log.info( allRoutesStrActual )
+        utilities.assertEquals( \
+            expect = allRoutesStrExpected, actual = allRoutesStrActual,
+            onpass = "Routes are correct!",
+            onfail = "Routes are wrong!" )
+
+        main.step( "Check M2S intents installed" )
+        getIntentsResult = main.ONOScli1.intents( jsonFormat = True )
+        routeIntentsActualNum = \
+            main.QuaggaCliSpeaker1.extractActualRouteIntentNum( getIntentsResult )
+        routeIntentsExpectedNum = 3
+
+        main.log.info( "MultiPointToSinglePoint Intent Num expected is:" )
+        main.log.info( routeIntentsExpectedNum )
+        main.log.info( "MultiPointToSinglePoint Intent NUM Actual is:" )
+        main.log.info( routeIntentsActualNum )
+        utilities.assertEquals( \
+            expect = True,
+            actual = eq( routeIntentsExpectedNum, routeIntentsActualNum ),
+            onpass = "MultiPointToSinglePoint Intent Num is correct!",
+            onfail = "MultiPointToSinglePoint Intent Num is wrong!" )
+
+        main.step( "Check whether all flow status are ADDED" )
+        utilities.assertEquals( \
+            expect = main.TRUE,
+            actual = main.ONOScli1.checkFlowsState( isPENDING_ADD = False ),
+            onpass = "Flow status is correct!",
+            onfail = "Flow status is wrong!" )
+
+
+    def CASE4( self, main ):
+        '''
+        Ping test in data plane for each route
+        '''
+        main.case( "Ping test for each route, all hosts behind BGP peers" )
+        main.Functions.pingHostToHost( main,
+                        hosts = ["host64514", "host64515", "host64516"],
+                        expectAllSuccess = True )
+
+
+    def CASE5( self, main ):
+        '''
+        Cut links to peers one by one, check routes/intents
+        '''
+        import time
+        main.case( "Bring down links and check routes/intents" )
+        main.step( "Bring down the link between sw32 and peer64514" )
+        linkResult1 = main.Mininet.link( END1 = "sw32", END2 = "peer64514",
+                                         OPTION = "down" )
+        utilities.assertEquals( expect = main.TRUE,
+                                actual = linkResult1,
+                                onpass = "Bring down link succeeded!",
+                                onfail = "Bring down link failed!" )
+
+        if linkResult1 == main.TRUE:
+            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+            main.Functions.checkRouteNum( main, 2 )
+            main.Functions.checkM2SintentNum( main, 2 )
+        else:
+            main.log.error( "Bring down link failed!" )
+            main.cleanup()
+            main.exit()
+
+        main.step( "Bring down the link between sw8 and peer64515" )
+        linkResult2 = main.Mininet.link( END1 = "sw8", END2 = "peer64515",
+                                         OPTION = "down" )
+        utilities.assertEquals( expect = main.TRUE,
+                                actual = linkResult2,
+                                onpass = "Bring down link succeeded!",
+                                onfail = "Bring down link failed!" )
+        if linkResult2 == main.TRUE:
+            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+            main.Functions.checkRouteNum( main, 1 )
+            main.Functions.checkM2SintentNum( main, 1 )
+        else:
+            main.log.error( "Bring down link failed!" )
+            main.cleanup()
+            main.exit()
+
+        main.step( "Bring down the link between sw28 and peer64516" )
+        linkResult3 = main.Mininet.link( END1 = "sw28", END2 = "peer64516",
+                                         OPTION = "down" )
+        utilities.assertEquals( expect = main.TRUE,
+                                actual = linkResult3,
+                                onpass = "Bring down link succeeded!",
+                                onfail = "Bring down link failed!" )
+        if linkResult3 == main.TRUE:
+            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+            main.Functions.checkRouteNum( main, 0 )
+            main.Functions.checkM2SintentNum( main, 0 )
+        else:
+            main.log.error( "Bring down link failed!" )
+            main.cleanup()
+            main.exit()
+
+        main.step( "Check whether all flow status are ADDED" )
+        utilities.assertEquals( \
+            expect = main.TRUE,
+            actual = main.ONOScli1.checkFlowsState( isPENDING_ADD = False ),
+            onpass = "Flow status is correct!",
+            onfail = "Flow status is wrong!" )
+
+        # Ping test
+        main.Functions.pingSpeakerToPeer( main, speakers = ["speaker1"],
+                       peers = ["peer64514", "peer64515", "peer64516"],
+                       expectAllSuccess = False )
+        main.Functions.pingHostToHost( main,
+                        hosts = ["host64514", "host64515", "host64516"],
+                        expectAllSuccess = False )
+
+
+    def CASE6( self, main ):
+        '''
+        Recover links to peers one by one, check routes/intents
+        '''
+        import time
+        main.case( "Bring up links and check routes/intents" )
+        main.step( "Bring up the link between sw32 and peer64514" )
+        linkResult1 = main.Mininet.link( END1 = "sw32", END2 = "peer64514",
+                                         OPTION = "up" )
+        utilities.assertEquals( expect = main.TRUE,
+                                actual = linkResult1,
+                                onpass = "Bring up link succeeded!",
+                                onfail = "Bring up link failed!" )
+        if linkResult1 == main.TRUE:
+            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+            main.Functions.checkRouteNum( main, 1 )
+            main.Functions.checkM2SintentNum( main, 1 )
+        else:
+            main.log.error( "Bring up link failed!" )
+            main.cleanup()
+            main.exit()
+
+        main.step( "Bring up the link between sw8 and peer64515" )
+        linkResult2 = main.Mininet.link( END1 = "sw8", END2 = "peer64515",
+                                         OPTION = "up" )
+        utilities.assertEquals( expect = main.TRUE,
+                                actual = linkResult2,
+                                onpass = "Bring up link succeeded!",
+                                onfail = "Bring up link failed!" )
+        if linkResult2 == main.TRUE:
+            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+            main.Functions.checkRouteNum( main, 2 )
+            main.Functions.checkM2SintentNum( main, 2 )
+        else:
+            main.log.error( "Bring up link failed!" )
+            main.cleanup()
+            main.exit()
+
+        main.step( "Bring up the link between sw28 and peer64516" )
+        linkResult3 = main.Mininet.link( END1 = "sw28", END2 = "peer64516",
+                                         OPTION = "up" )
+        utilities.assertEquals( expect = main.TRUE,
+                                actual = linkResult3,
+                                onpass = "Bring up link succeeded!",
+                                onfail = "Bring up link failed!" )
+        if linkResult3 == main.TRUE:
+            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+            main.Functions.checkRouteNum( main, 3 )
+            main.Functions.checkM2SintentNum( main, 3 )
+        else:
+            main.log.error( "Bring up link failed!" )
+            main.cleanup()
+            main.exit()
+
+        main.step( "Check whether all flow status are ADDED" )
+        utilities.assertEquals( \
+            expect = main.TRUE,
+            actual = main.ONOScli1.checkFlowsState( isPENDING_ADD = False ),
+            onpass = "Flow status is correct!",
+            onfail = "Flow status is wrong!" )
+
+        # Ping test
+        main.Functions.pingSpeakerToPeer( main, speakers = ["speaker1"],
+                       peers = ["peer64514", "peer64515", "peer64516"],
+                       expectAllSuccess = True )
+        main.Functions.pingHostToHost( main,
+                        hosts = ["host64514", "host64515", "host64516"],
+                        expectAllSuccess = True )
+
+
+    def CASE7( self, main ):
+        '''
+        Shut down a edge switch, check P-2-P and M-2-S intents, ping test
+        '''
+        import time
+        main.case( "Stop edge sw32,check P-2-P and M-2-S intents, ping test" )
+        main.step( "Stop sw32" )
+        result = main.Mininet.switch( SW = "sw32", OPTION = "stop" )
+        utilities.assertEquals( expect = main.TRUE, actual = result,
+                                onpass = "Stopping switch succeeded!",
+                                onfail = "Stopping switch failed!" )
+
+        if result == main.TRUE:
+            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+            main.Functions.checkRouteNum( main, 2 )
+            main.Functions.checkM2SintentNum( main, 2 )
+            main.Functions.checkP2PintentNum( main, 12 * 2 )
+        else:
+            main.log.error( "Stopping switch failed!" )
+            main.cleanup()
+            main.exit()
+
+        main.step( "Check ping between hosts behind BGP peers" )
+        result1 = main.Mininet.pingHost( src = "host64514", target = "host64515" )
+        result2 = main.Mininet.pingHost( src = "host64515", target = "host64516" )
+        result3 = main.Mininet.pingHost( src = "host64514", target = "host64516" )
+
+        pingResult1 = ( result1 == main.FALSE ) and ( result2 == main.TRUE ) \
+                      and ( result3 == main.FALSE )
+        utilities.assert_equals( expect = True, actual = pingResult1,
+                                 onpass = "Ping test result is correct",
+                                 onfail = "Ping test result is wrong" )
+
+        if pingResult1 == False:
+            main.cleanup()
+            main.exit()
+
+        main.step( "Check ping between BGP peers and speaker1" )
+        result4 = main.Mininet.pingHost( src = "speaker1", target = "peer64514" )
+        result5 = main.Mininet.pingHost( src = "speaker1", target = "peer64515" )
+        result6 = main.Mininet.pingHost( src = "speaker1", target = "peer64516" )
+
+        pingResult2 = ( result4 == main.FALSE ) and ( result5 == main.TRUE ) \
+                      and ( result6 == main.TRUE )
+        utilities.assert_equals( expect = True, actual = pingResult2,
+                                 onpass = "Speaker1 ping peers successful",
+                                 onfail = "Speaker1 ping peers NOT successful" )
+
+        if pingResult2 == False:
+            main.cleanup()
+            main.exit()
+
+        main.step( "Check ping between BGP peers and speaker2" )
+        # TODO
+        result7 = main.Mininet.pingHost( src = "speaker2", target = peer64514 )
+        result8 = main.Mininet.pingHost( src = "speaker2", target = peer64515 )
+        result9 = main.Mininet.pingHost( src = "speaker2", target = peer64516 )
+
+        pingResult3 = ( result7 == main.FALSE ) and ( result8 == main.TRUE ) \
+                                                and ( result9 == main.TRUE )
+        utilities.assert_equals( expect = True, actual = pingResult2,
+                                 onpass = "Speaker2 ping peers successful",
+                                 onfail = "Speaker2 ping peers NOT successful" )
+
+        if pingResult3 == False:
+            main.cleanup()
+            main.exit()
+
+        main.step( "Check whether all flow status are ADDED" )
+        utilities.assertEquals( \
+            expect = main.TRUE,
+            actual = main.ONOScli1.checkFlowsState( isPENDING_ADD = False ),
+            onpass = "Flow status is correct!",
+            onfail = "Flow status is wrong!" )
+
+
+    def CASE8( self, main ):
+        '''
+        Bring up the edge switch (sw32) which was shut down in CASE7,
+        check P-2-P and M-2-S intents, ping test
+        '''
+        import time
+        main.case( "Start the edge sw32, check P-2-P and M-2-S intents, ping test" )
+        main.step( "Start sw32" )
+        result1 = main.Mininet.switch( SW = "sw32", OPTION = "start" )
+        utilities.assertEquals( \
+            expect = main.TRUE,
+            actual = result1,
+            onpass = "Starting switch succeeded!",
+            onfail = "Starting switch failed!" )
+
+        result2 = main.Mininet.assignSwController( "sw32", ONOS1Ip )
+        utilities.assertEquals( \
+            expect = main.TRUE,
+            actual = result2,
+            onpass = "Connect switch to ONOS succeeded!",
+            onfail = "Connect switch to ONOS failed!" )
+
+        if result1 and result2:
+            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+            main.Functions.checkRouteNum( main, 3 )
+            main.Functions.checkM2SintentNum( main, 3 )
+            main.Functions.checkP2PintentNum( main, 18 * 2 )
+        else:
+            main.log.error( "Starting switch failed!" )
+            main.cleanup()
+            main.exit()
+
+        main.step( "Check whether all flow status are ADDED" )
+        utilities.assertEquals( \
+            expect = main.TRUE,
+            actual = main.ONOScli1.checkFlowsState( isPENDING_ADD = False ),
+            onpass = "Flow status is correct!",
+            onfail = "Flow status is wrong!" )
+
+        # Ping test
+        main.Functions.pingSpeakerToPeer( main, speakers = ["speaker1"],
+                       peers = ["peer64514", "peer64515", "peer64516"],
+                       expectAllSuccess = True )
+        main.Functions.pingSpeakerToPeer( main, speakers = ["speaker2"],
+                       peers = [peer64514, peer64515, peer64516],
+                       expectAllSuccess = True )
+        main.Functions.pingHostToHost( main,
+                        hosts = ["host64514", "host64515", "host64516"],
+                        expectAllSuccess = True )
+
+
+    def CASE9( self, main ):
+        '''
+        Bring down a switch in best path, check:
+        route number, P2P intent number, M2S intent number, ping test
+        '''
+        main.case( "Stop sw11 located in best path, \
+        check route number, P2P intent number, M2S intent number, ping test" )
+
+        main.log.info( "Check the flow number correctness before stopping sw11" )
+        main.Functions.checkFlowNum( main, "sw11", 19 )
+        main.Functions.checkFlowNum( main, "sw1", 3 )
+        main.Functions.checkFlowNum( main, "sw7", 3 )
+        main.log.info( main.Mininet.checkFlows( "sw11" ) )
+        main.log.info( main.Mininet.checkFlows( "sw1" ) )
+        main.log.info( main.Mininet.checkFlows( "sw7" ) )
+
+        main.step( "Stop sw11" )
+        result = main.Mininet.switch( SW = "sw11", OPTION = "stop" )
+        utilities.assertEquals( expect = main.TRUE, actual = result,
+                                onpass = "Stopping switch succeeded!",
+                                onfail = "Stopping switch failed!" )
+        if result:
+            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+            main.Functions.checkRouteNum( main, 3 )
+            main.Functions.checkM2SintentNum( main, 3 )
+            main.Functions.checkP2PintentNum( main, 18 * 2 )
+        else:
+            main.log.error( "Stopping switch failed!" )
+            main.cleanup()
+            main.exit()
+
+        main.step( "Check whether all flow status are ADDED" )
+        utilities.assertEquals( \
+            expect = main.TRUE,
+            actual = main.ONOScli1.checkFlowsState( isPENDING_ADD = False ),
+            onpass = "Flow status is correct!",
+            onfail = "Flow status is wrong!" )
+        # Ping test
+        main.Functions.pingSpeakerToPeer( main, speakers = ["speaker1"],
+                       peers = ["peer64514", "peer64515", "peer64516"],
+                       expectAllSuccess = True )
+        main.Functions.pingSpeakerToPeer( main, speakers = ["speaker2"],
+                       peers = [peer64514, peer64515, peer64516],
+                       expectAllSuccess = True )
+        main.Functions.pingHostToHost( main,
+                        hosts = ["host64514", "host64515", "host64516"],
+                        expectAllSuccess = True )
+
+
+    def CASE10( self, main ):
+        '''
+        Bring up the switch which was stopped in CASE9, check:
+        route number, P2P intent number, M2S intent number, ping test
+        '''
+        main.case( "Start sw11 which was stopped in CASE9, \
+        check route number, P2P intent number, M2S intent number, ping test" )
+
+        main.log.info( "Check the flow status before starting sw11" )
+        main.Functions.checkFlowNum( main, "sw1", 17 )
+        main.Functions.checkFlowNum( main, "sw7", 5 )
+        main.log.info( main.Mininet.checkFlows( "sw1" ) )
+        main.log.info( main.Mininet.checkFlows( "sw7" ) )
+
+        main.step( "Start sw11" )
+        result1 = main.Mininet.switch( SW = "sw11", OPTION = "start" )
+        utilities.assertEquals( expect = main.TRUE, actual = result1,
+                                onpass = "Starting switch succeeded!",
+                                onfail = "Starting switch failed!" )
+        result2 = main.Mininet.assignSwController( "sw11", ONOS1Ip )
+        utilities.assertEquals( expect = main.TRUE, actual = result2,
+                                onpass = "Connect switch to ONOS succeeded!",
+                                onfail = "Connect switch to ONOS failed!" )
+        if result1 and result2:
+            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+            main.Functions.checkRouteNum( main, 3 )
+            main.Functions.checkM2SintentNum( main, 3 )
+            main.Functions.checkP2PintentNum( main, 18 * 2 )
+
+            main.log.debug( main.Mininet.checkFlows( "sw11" ) )
+            main.log.debug( main.Mininet.checkFlows( "sw1" ) )
+            main.log.debug( main.Mininet.checkFlows( "sw7" ) )
+        else:
+            main.log.error( "Starting switch failed!" )
+            main.cleanup()
+            main.exit()
+
+        main.step( "Check whether all flow status are ADDED" )
+        utilities.assertEquals( \
+            expect = main.TRUE,
+            actual = main.ONOScli1.checkFlowsState( isPENDING_ADD = False ),
+            onpass = "Flow status is correct!",
+            onfail = "Flow status is wrong!" )
+        # Ping test
+        main.Functions.pingSpeakerToPeer( main, speakers = ["speaker1"],
+                       peers = ["peer64514", "peer64515", "peer64516"],
+                       expectAllSuccess = True )
+        main.Functions.pingSpeakerToPeer( main, speakers = ["speaker2"],
+                       peers = [peer64514, peer64515, peer64516],
+                       expectAllSuccess = True )
+        main.Functions.pingHostToHost( main,
+                        hosts = ["host64514", "host64515", "host64516"],
+                        expectAllSuccess = True )
+
+
+    def CASE11(self, main):
+        import time
+        main.case( "Kill speaker1, check:\
+        route number, P2P intent number, M2S intent number, ping test" )
+        main.log.info( "Check network status before killing speaker1" )
+        main.Functions.checkRouteNum( main, 3 )
+        main.Functions.checkM2SintentNum( main, 3 )
+        main.Functions.checkP2PintentNum( main, 18 * 2 )
+        main.step( "Check whether all flow status are ADDED" )
+        utilities.assertEquals( \
+            expect = main.TRUE,
+            actual = main.ONOScli1.checkFlowsState( isPENDING_ADD = False ),
+            onpass = "Flow status is correct!",
+            onfail = "Flow status is wrong!" )
+
+        main.Functions.pingSpeakerToPeer( main, speakers = ["speaker1"],
+                       peers = ["peer64514", "peer64515", "peer64516"],
+                       expectAllSuccess = True )
+        main.Functions.pingSpeakerToPeer( main, speakers = ["speaker2"],
+                       peers = [peer64514, peer64515, peer64516],
+                       expectAllSuccess = True )
+        main.Functions.pingHostToHost( main,
+                        hosts = ["host64514", "host64515", "host64516"],
+                        expectAllSuccess = True )
+
+        main.step( "Kill speaker1" )
+        command1 = "ps -e | grep bgp -c"
+        result1 = main.Mininet.node( "root", command1 )
+
+        # The total BGP daemon number in this test environment is 5.
+        if "5" in result1:
+            main.log.debug( "Before kill speaker1, 5 BGP daemons - correct" )
+        else:
+            main.log.warn( "Before kill speaker1, number of BGP daemons is wrong" )
+            main.log.info( result1 )
+
+        command2 = "sudo kill -9 `ps -ef | grep quagga-sdn.conf | grep -v grep | awk '{print $2}'`"
+        result2 = main.Mininet.node( "root", command2 )
+
+        result3 = main.Mininet.node( "root", command1 )
+
+        utilities.assert_equals( expect = True,
+                                 actual = ( "4" in result3 ),
+                                 onpass = "Kill speaker1 succeeded",
+                                 onfail = "Kill speaker1 failed" )
+        if ( "4" not in result3 ) :
+            main.log.info( result3 )
+            main.cleanup()
+            main.exit()
+
+        time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+        main.Functions.checkRouteNum( main, 3 )
+        main.Functions.checkM2SintentNum( main, 3 )
+        main.Functions.checkP2PintentNum( main, 18 * 2 )
+
+        main.step( "Check whether all flow status are ADDED" )
+        utilities.assertEquals( \
+            expect = main.TRUE,
+            actual = main.ONOScli1.checkFlowsState( isPENDING_ADD = False ),
+            onpass = "Flow status is correct!",
+            onfail = "Flow status is wrong!" )
+
+        '''
+        main.Functions.pingSpeakerToPeer( main, speakers = ["speaker1"],
+                       peers = ["peer64514", "peer64515", "peer64516"],
+                       expectAllSuccess = False )
+        '''
+        main.Functions.pingSpeakerToPeer( main, speakers = ["speaker2"],
+                       peers = [peer64514, peer64515, peer64516],
+                       expectAllSuccess = True )
+        main.Functions.pingHostToHost( main,
+                        hosts = ["host64514", "host64515", "host64516"],
+                        expectAllSuccess = True )
+
+
+    def CASE12( self, main ):
+        import time
+        import json
+        main.case( "Bring down leader ONOS node, check: \
+        route number, P2P intent number, M2S intent number, ping test" )
+        main.step( "Find out ONOS leader node" )
+        result = main.ONOScli1.leaders()
+        jsonResult = json.loads( result )
+        leaderIP = ""
+        for entry in jsonResult:
+            if entry["topic"] == "org.onosproject.sdnip":
+                leaderIP = entry["leader"]
+                main.log.info( "leaderIP is: " )
+                main.log.info( leaderIP )
+
+        main.step( "Uninstall ONOS/SDN-IP leader node" )
+        if leaderIP == ONOS1Ip:
+            uninstallResult = main.ONOSbench.onosStop( ONOS1Ip )
+        elif leaderIP == ONOS2Ip:
+            uninstallResult = main.ONOSbench.onosStop( ONOS2Ip )
+        else:
+            uninstallResult = main.ONOSbench.onosStop( ONOS3Ip )
+
+        utilities.assert_equals( expect = main.TRUE,
+                                 actual = uninstallResult,
+                                 onpass = "Uninstall ONOS leader succeeded",
+                                 onfail = "Uninstall ONOS leader failed" )
+        if uninstallResult != main.TRUE:
+            main.cleanup()
+            main.exit()
+        time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+
+        if leaderIP == ONOS1Ip:
+            main.Functions.checkRouteNum( main, 3, ONOScli = "ONOScli2" )
+            main.Functions.checkM2SintentNum( main, 3, ONOScli = "ONOScli2" )
+            main.Functions.checkP2PintentNum( main, 18 * 2, ONOScli = "ONOScli2" )
+
+            main.step( "Check whether all flow status are ADDED" )
+            utilities.assertEquals( \
+                expect = main.TRUE,
+                actual = main.ONOScli2.checkFlowsState( isPENDING_ADD = False ),
+                onpass = "Flow status is correct!",
+                onfail = "Flow status is wrong!" )
+        else:
+            main.Functions.checkRouteNum( main, 3 )
+            main.Functions.checkM2SintentNum( main, 3 )
+            main.Functions.checkP2PintentNum( main, 18 * 2 )
+
+            main.step( "Check whether all flow status are ADDED" )
+            utilities.assertEquals( \
+                expect = main.TRUE,
+                actual = main.ONOScli1.checkFlowsState( isPENDING_ADD = False ),
+                onpass = "Flow status is correct!",
+                onfail = "Flow status is wrong!" )
+
+        main.Functions.pingSpeakerToPeer( main, speakers = ["speaker1"],
+                       peers = ["peer64514", "peer64515", "peer64516"],
+                       expectAllSuccess = True )
+        main.Functions.pingSpeakerToPeer( main, speakers = ["speaker2"],
+                       peers = [peer64514, peer64515, peer64516],
+                       expectAllSuccess = True )
+        main.Functions.pingHostToHost( main,
+                        hosts = ["host64514", "host64515", "host64516"],
+                        expectAllSuccess = True )
diff --git a/TestON/tests/USECASE_SdnipFunctionCluster/USECASE_SdnipFunctionCluster.topo b/TestON/tests/USECASE_SdnipFunctionCluster/USECASE_SdnipFunctionCluster.topo
new file mode 100644
index 0000000..f3c9b5f
--- /dev/null
+++ b/TestON/tests/USECASE_SdnipFunctionCluster/USECASE_SdnipFunctionCluster.topo
@@ -0,0 +1,52 @@
+<TOPOLOGY>
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>127.0.0.1</host>
+            <user>admin</user>
+            <password></password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOSbench>
+
+        <ONOScli1>
+            <host>127.0.0.1</host>
+            <user>admin</user>
+            <password></password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli1>
+        <ONOScli2>
+            <host>127.0.0.1</host>
+            <user>admin</user>
+            <password></password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli2>
+
+        <QuaggaCliSpeaker1>
+            <host>127.0.0.1</host>
+            <user>admin</user>
+            <password></password>
+            <type>QuaggaCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </QuaggaCliSpeaker1>
+
+        <Mininet>
+            <host>OCN</host>
+            <user>admin</user>
+            <password></password>
+            <type>MininetCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS>
+                <home>~/Mininet/mininet/custom/</home>
+            </COMPONENTS>
+        </Mininet>
+
+    </COMPONENT>
+</TOPOLOGY>
+
diff --git a/TestON/tests/USECASE_SdnipFunctionCluster/__init__.py b/TestON/tests/USECASE_SdnipFunctionCluster/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/USECASE_SdnipFunctionCluster/__init__.py
diff --git a/TestON/tests/USECASE_SdnipFunctionCluster/network-cfg.json b/TestON/tests/USECASE_SdnipFunctionCluster/network-cfg.json
new file mode 100644
index 0000000..602a72f
--- /dev/null
+++ b/TestON/tests/USECASE_SdnipFunctionCluster/network-cfg.json
@@ -0,0 +1,66 @@
+{
+    "ports" : {
+        "of:00000000000000a8/5" : {
+            "interfaces" : [
+                {
+                    "ips"  : [ "10.0.5.101/24" ],
+                    "mac"  : "00:00:00:00:00:01"
+                },
+                {
+                    "ips"  : [ "10.0.15.101/24" ],
+                    "mac"  : "00:00:00:00:00:02"
+                }
+            ]
+        },
+        "of:0000000000000a32/4" : {
+            "interfaces" : [
+                {
+                    "ips"  : [ "10.0.4.101/24" ],
+                    "mac"  : "00:00:00:00:00:01"
+                },
+                {
+                    "ips"  : [ "10.0.14.101/24" ],
+                    "mac"  : "00:00:00:00:00:02"
+                }
+            ]
+        },
+        "of:0000000000000a28/3" : {
+            "interfaces" : [
+                {
+                    "ips"  : [ "10.0.6.101/24" ],
+                    "mac"  : "00:00:00:00:00:01"
+                },
+                {
+                    "ips"  : [ "10.0.16.101/24" ],
+                    "mac"  : "00:00:00:00:00:02"
+                }
+            ]
+        }
+    },
+    "apps" : {
+        "org.onosproject.router" : {
+            "bgp" : {
+                "bgpSpeakers" : [
+                    {
+                        "name" : "speaker1",
+                        "connectPoint" : "of:0000000000000a24/1",
+                        "peers" : [
+                            "10.0.4.1",
+                            "10.0.5.1",
+                            "10.0.6.1"
+                        ]
+                    },
+                    {
+                        "name" : "speaker2",
+                        "connectPoint" : "of:0000000000000a24/2",
+                        "peers" : [
+                            "10.0.14.1",
+                            "10.0.15.1",
+                            "10.0.16.1"
+                        ]
+                    }
+                ]
+            }
+        }
+    }
+}
diff --git a/TestON/tests/USECASE_SdnipFunctionCluster/sdnip_multiple_instance b/TestON/tests/USECASE_SdnipFunctionCluster/sdnip_multiple_instance
new file mode 100644
index 0000000..ed0c7d7
--- /dev/null
+++ b/TestON/tests/USECASE_SdnipFunctionCluster/sdnip_multiple_instance
@@ -0,0 +1,14 @@
+export ONOS_CELL="sdnip_multiple_instance"
+
+export ONOS_INSTALL_DIR="/opt/onos"
+export ONOS_NIC=10.128.4.*
+export OC1="10.128.4.52"
+export OC2="10.128.4.53"
+export OC3="10.128.4.54"
+export OCN="127.0.0.1"
+export OCI="${OC1}"
+export ONOS_USER="sdn"                  # ONOS user on remote system
+export ONOS_PWD="rocks"
+
+export ONOS_APPS="drivers,openflow,proxyarp"
+
diff --git a/TestON/tests/USECASE_SdnipFunctionCluster/sdnip_multiple_instance_BM b/TestON/tests/USECASE_SdnipFunctionCluster/sdnip_multiple_instance_BM
new file mode 100644
index 0000000..1053083
--- /dev/null
+++ b/TestON/tests/USECASE_SdnipFunctionCluster/sdnip_multiple_instance_BM
@@ -0,0 +1,14 @@
+export ONOS_CELL="sdnip_multiple_instance_BM"
+
+export ONOS_INSTALL_DIR="/opt/onos"
+export ONOS_NIC=10.254.1.*
+export OC1="10.254.1.201"
+export OC2="10.254.1.202"
+export OC3="10.254.1.203"
+export OCN="127.0.0.1"
+export OCI="${OC1}"
+export ONOS_USER="sdn"                  # ONOS user on remote system
+export ONOS_PWD="rocks"
+
+export ONOS_APPS="drivers,openflow,proxyarp"
+