Merge pull request #97 from srikanthvavila/master

Merging BGPRouter tests
diff --git a/TestON/bin/cli.py b/TestON/bin/cli.py
index 47b027e..ed1c796 100755
--- a/TestON/bin/cli.py
+++ b/TestON/bin/cli.py
@@ -48,11 +48,12 @@
 dump = pprint.PrettyPrinter(indent=4)
 __builtin__.testthread = False
 introduction = "TestON is the testing framework \nDeveloped by Paxterra Solutions (www.paxterrasolutions.com)"
+__builtin__.COLORS = False
 
 path = re.sub("teston$", "", os.getcwd())
 sys.path.append(path+"/Core")
 sys.path.append("../")
-from core.teston import * 
+from core.teston import *
 
 class CLI( threading.Thread,Cmd,object ):
     "command-line interface to execute the test."
@@ -61,7 +62,7 @@
 
     def __init__( self, teston, stdin=sys.stdin ):
         self.teston = teston
-        
+
         self._mainevent = threading.Event()
         threading.Thread.__init__(self)
         self.main_stop = False
@@ -592,6 +593,8 @@
 
 if __name__ == '__main__':
     if len(sys.argv) > 1:
+        __builtin__.COLORS = True
         CLI("test").onecmd(' '.join(sys.argv[1:]))
     else:
+        __builtin__.COLORS = False
         CLI("test").cmdloop()
diff --git a/TestON/core/Thread.py b/TestON/core/Thread.py
new file mode 100644
index 0000000..da30339
--- /dev/null
+++ b/TestON/core/Thread.py
@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+import threading
+
+
+class Thread( threading.Thread ):
+    def __init__( self, target=None, threadID=None, name="", args=(),
+                  kwargs={} ):
+        super( Thread, self ).__init__()
+        self.threadID = threadID
+        self.name = name
+        self.target = target
+        self.args = args
+        self.kwargs = kwargs
+        self.result = None
+
+    def run( self ):
+        try:
+            if self.target is not None:
+                self.result = self.target( *self.args, **self.kwargs )
+        except Exception as e:
+            print "Thread-" + str( self.threadID ) + " '" + self.name + "'"\
+                  ":something went wrong with " + self.target + " method"
+            print e
diff --git a/TestON/core/iniparser.py b/TestON/core/iniparser.py
index b952f2d..c350a20 100644
--- a/TestON/core/iniparser.py
+++ b/TestON/core/iniparser.py
@@ -48,7 +48,7 @@
             try :
                 parsedInfo = ConfigObj(self.fileName)
                 return parsedInfo
-            except :
+            except Exception:
                 print "There is no such file to parse "+fileName
         else:
             return 0
diff --git a/TestON/core/jsonparser.py b/TestON/core/jsonparser.py
index 8726e87..fea797a 100644
--- a/TestON/core/jsonparser.py
+++ b/TestON/core/jsonparser.py
@@ -21,7 +21,6 @@
 
 '''
 
-import re
 import json
 class JsonParser:
     '''
@@ -37,7 +36,7 @@
         response_dict = {}
         try :
             response_dict = json.loads(json_response)
-        except :
+        except Exception:
             main.log.error("Json Parser is unable to parse the string")
         return response_dict         
     
@@ -50,7 +49,7 @@
         json_response = {}
         try :
             json_response = json.dumps(response_dict)
-        except :
+        except Exception:
             main.log.error("Json Parser is unable to parse the string")
         return json_response  
     '''
diff --git a/TestON/core/logger.py b/TestON/core/logger.py
index 80fe0de..1dfe6bf 100644
--- a/TestON/core/logger.py
+++ b/TestON/core/logger.py
@@ -115,8 +115,8 @@
         #### Add log-level - Report
         logging.addLevelName(9, "REPORT")
         logging.addLevelName(7, "EXACT")
-        logging.addLevelName(10, "CASE")
-        logging.addLevelName(11, "STEP")
+        logging.addLevelName(11, "CASE")
+        logging.addLevelName(12, "STEP")
         main.log = logging.getLogger(main.TEST)
         def report (msg):
             '''
@@ -183,13 +183,42 @@
 
         ### initializing logging module and settig log level
         main.log.setLevel(logging.INFO)
+        main.log.setLevel(logging.DEBUG) # Temporary
         main.LogFileHandler.setLevel(logging.INFO)
        
         # create console handler with a higher log level
         main.ConsoleHandler = logging.StreamHandler()
         main.ConsoleHandler.setLevel(logging.INFO)
+        main.ConsoleHandler.setLevel(logging.DEBUG) #Temporary
         # create formatter and add it to the handlers
-        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+        #formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+        class MyFormatter( logging.Formatter ):
+            colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
+                       'blue': '\033[94m', 'green': '\033[92m',
+                       'yellow': '\033[93m', 'red': '\033[91m',
+                       'end': '\033[0m' }
+
+            FORMATS = {'DEFAULT': '%(asctime)s - %(name)s - %(levelname)s - %(message)s'}
+            if COLORS:  # NOTE:colors will only be loaded if command is run from one line
+                        #      IE:   './cli.py run testname'
+                        #      This is to prevent issues with Jenkins parsing
+                        # TODO: Make colors configurable
+                levels = { logging.ERROR : colors['red'] +
+                                           FORMATS['DEFAULT'] +
+                                           colors['end'],
+                           logging.WARN : colors['yellow'] +
+                                          FORMATS['DEFAULT'] +
+                                          colors['end'],
+                           logging.DEBUG : colors['purple'] +
+                                          FORMATS['DEFAULT'] +
+                                          colors['end'] }
+                FORMATS.update( levels )
+
+            def format( self, record ):
+                self._fmt = self.FORMATS.get( record.levelno,
+                                              self.FORMATS[ 'DEFAULT' ] )
+                return logging.Formatter.format( self, record )
+        formatter = MyFormatter()
         main.ConsoleHandler.setFormatter(formatter)
         main.LogFileHandler.setFormatter(formatter)
 
diff --git a/TestON/core/teston.py b/TestON/core/teston.py
index 0925edd..edb763c 100644
--- a/TestON/core/teston.py
+++ b/TestON/core/teston.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 '''
 Created on 22-Oct-2012
-    
+
 @author: Anil Kumar (anilkumar.s@paxterrasolutions.com)
 
 
@@ -16,7 +16,7 @@
     GNU General Public License for more details.
 
     You should have received a copy of the GNU General Public License
-    along with TestON.  If not, see <http://www.gnu.org/licenses/>.		
+    along with TestON.  If not, see <http://www.gnu.org/licenses/>.
 
 
 
@@ -31,6 +31,7 @@
 import __builtin__
 import new
 import xmldict
+import importlib
 module = new.module("test")
 import openspeak
 global path, drivers_path, core_path, tests_path,logs_path
@@ -46,6 +47,7 @@
 sys.path.append(tests_path)
 
 from core.utilities import Utilities
+from core.Thread import Thread
 
 
 class TestON:
@@ -87,8 +89,8 @@
         self.loggerClass = "Logger"
         self.logs_path = logs_path
         self.driver = ''
-	
-        
+        self.Thread = Thread
+
         self.configparser()
         verifyOptions(options)
         load_logger()
@@ -97,17 +99,17 @@
         self.driversList=[]
         if type(self.componentDictionary) == str :
             self.componentDictionary = dict(self.componentDictionary)
-            
+
         for component in self.componentDictionary :
             self.driversList.append(self.componentDictionary[component]['type'])
-            
+
         self.driversList = list(set(self.driversList)) # Removing duplicates.
         # Checking the test_target option set for the component or not
         if type(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)
 
@@ -139,14 +141,13 @@
             try :
                 self.configDict = xmldict.xml_to_dict(xml)
                 return self.configDict
-            except :
+            except Exception:
                 print "There is no such file to parse " + self.configFile
                         
     def componentInit(self,component):
         '''
         This method will initialize specified component
         '''
-        import importlib
         global driver_options
         self.log.info("Creating component Handle: "+component)
         driver_options = {}
@@ -197,14 +198,14 @@
         test = testparser.TestParser(testFile)
         self.testscript = test.testscript
         self.code = test.getStepCode()
-	repeat= int(self.params['repeat']) if ('repeat' in self.params) else 1
-	main.TOTAL_TC_PLANNED = len(self.testcases_list)*repeat
+        repeat= int(self.params['repeat']) if ('repeat' in self.params) else 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
+            repeat-=1
         return result
     
     def runCase(self,testCaseNumber):
@@ -218,15 +219,15 @@
         try :
             self.stepList = self.code[self.testCaseNumber].keys()
         except KeyError:
-            main.log.error("There is no Test-Case "+ self.testCaseNumber)
-            return main.FALSE
+            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)
-            if result == main.FALSE:
+            if result == self.FALSE:
                 break
-            elif result == main.TRUE :
+            elif result == self.TRUE:
                 continue
             
         if not stopped :
@@ -241,10 +242,12 @@
                 exec code[testCaseNumber][step] in module.__dict__
                 self.stepCount = self.stepCount + 1
             except TypeError,e:
-                print "Exception in the following section of code:"
-                print code[testCaseNumber][step]
+                print "Exception in the following section of code: Test Step " +\
+                      str(testCaseNumber) + "." + str(step) + " ):"
+                #print code[testCaseNumber][step]
                 self.stepCount = self.stepCount + 1
                 self.log.exception(e)
+                return main.FALSE
             return main.TRUE
         
         if cli.stop:
@@ -434,7 +437,7 @@
         xml_match = re.search('^\s*\<', response)
         ini_match = re.search('^\s*\[', response)
         if json_match :
-            main.log.info(" Response is in 'JSON' format and Converting to '"+return_format+"' format")
+            self.log.info(" Response is in 'JSON' format and Converting to '"+return_format+"' format")
             # Formatting the json string
             
             response = re.sub(r"{\s*'?(\w)", r'{"\1', response)
@@ -446,12 +449,12 @@
                 import json
                 response_dict = json.loads(response)
             except Exception, e:
-                main.log.exception(e)
-                main.log.error("Json Parser is unable to parse the string")
+                self.log.exception( e )
+                self.log.error("Json Parser is unable to parse the string")
             return response_dict
         
         elif ini_match :
-            main.log.info(" Response is in 'INI' format and Converting to '"+return_format+"' format")
+            self.log.info(" Response is in 'INI' format and Converting to '"+return_format+"' format")
             from configobj import ConfigObj
             response_file = open("respnse_file.temp",'w')
             response_file.write(response)
@@ -460,11 +463,11 @@
             return response_dict
             
         elif xml_match :
-            main.log.info(" Response is in 'XML' format and Converting to '"+return_format+"' format")
+            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>")
             except Exception, e:
-                main.log.exception(e)
+                self.log.exception( e )
             return response_dict
         
     def dict_to_return_format(self,response,return_format,response_dict):
@@ -492,7 +495,7 @@
                 
 
                 
-            #response_table = response_table + '\t'.join(response_dict.values())
+            # response_table = response_table + '\t'.join(response_dict.values())
                 
             return response_table
         
@@ -536,7 +539,7 @@
     import pprint
     pp = pprint.PrettyPrinter(indent=4)
 
-    #pp.pprint(options)
+    # pp.pprint(options)
     verifyTest(options)
     verifyExample(options)
     verifyTestScript(options)
@@ -565,7 +568,7 @@
         main.classPath = "examples."+main.TEST+"."+main.TEST
                
 def verifyLogdir(options):
-    #Verifying Log directory option
+    # Verifying Log directory option
     if options.logdir:
         main.logdir = options.logdir
     else :
@@ -581,10 +584,10 @@
         main.mail = 'paxweb@paxterrasolutions.com'
 
 def verifyTestCases(options):
-    #Getting Test cases list
+    # Getting Test cases list
     if options.testcases:
-	testcases_list = options.testcases
-        #sys.exit()
+        testcases_list = options.testcases
+        # sys.exit()
         testcases_list = re.sub("(\[|\])", "", options.testcases)
         main.testcases_list = eval(testcases_list+",")
     else :
@@ -592,18 +595,18 @@
             temp = eval(main.params['testcases']+",")
             list1=[]
             if type(temp[0])==list:
-	        for test in temp:
-      	            for testcase in test:
-	                if type(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
+                for test in temp:
+                    for testcase in test:
+                        if type(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"
             sys.exit()
diff --git a/TestON/core/utilities.py b/TestON/core/utilities.py
index b6bed3e..671dba5 100644
--- a/TestON/core/utilities.py
+++ b/TestON/core/utilities.py
@@ -29,11 +29,9 @@
 '''
 import re
 from configobj import ConfigObj
-import pydoc
 from core import ast as ast
 import smtplib
 
-import mimetypes
 import email
 import os
 import email.mime.application
@@ -265,7 +263,7 @@
             try :
                 parsedInfo = ConfigObj(self.fileName)
                 return parsedInfo
-            except :
+            except Exception:
                 print "There is no such file to parse "+fileName 
         else:
             return 0   
diff --git a/TestON/core/xmldict.py b/TestON/core/xmldict.py
index 34e9cfc..f873014 100644
--- a/TestON/core/xmldict.py
+++ b/TestON/core/xmldict.py
@@ -37,7 +37,7 @@
         root = ElementTree.XML(root_or_str)
     try :
         return {root.tag: _from_xml(root, strict)}
-    except :
+    except Exception:
         return None
 
 def dict_to_xml(dict_xml):
diff --git a/TestON/core/xmlparser.py b/TestON/core/xmlparser.py
index 3cb4aee..a46750a 100644
--- a/TestON/core/xmlparser.py
+++ b/TestON/core/xmlparser.py
@@ -39,7 +39,7 @@
             try :
                 parsedInfo = xmldict.xml_to_dict(xml)
                 return parsedInfo
-            except :
+            except Exception:
                 print "There is no such file to parse " + fileName 
         else :
             print "file name is not correct"
diff --git a/TestON/dependencies/Jenkins_getresult_HA.py b/TestON/dependencies/Jenkins_getresult_HA.py
index 9cb3b8b..7b4fc09 100755
--- a/TestON/dependencies/Jenkins_getresult_HA.py
+++ b/TestON/dependencies/Jenkins_getresult_HA.py
@@ -70,7 +70,7 @@
 
     output +="<p></p>"
     #output +="   Date: %s, %s %s" % (name.split("_")[2], name.split("_")[1], name.split("_")[3]) + "<p>*******************<p>"
-    #Open the latest log folder 
+    #Open the latest log folder
     output += "<h2>Test "+str(test)+"</h2><p>************************************</p>"
 
     f = open(path + name + ".rpt")
@@ -102,8 +102,11 @@
     #https://wiki.onosproject.org/display/OST/Test+Results+-+HA#Test+Results+-+HA
     #Example anchor on new wiki:        #TestResults-HA-TestHATestSanity
     page_name = "Master-HA"
-    if "ONOS-HA-Maint" in job:
-        #NOTE if page name starts with number it prepends 'id-' to anchor links
+    if "ONOS-HA-1.1.X" in job:
+        page_name = "Blackbird-HA"
+    elif "ONOS-HA-Maint" in job:
+        # NOTE if page name starts with number confluence prepends 'id-'
+        #      to anchor links
         page_name = "id-1.0-HA"
 
     header += "<li><a href=\'#" + str(page_name) + "-Test" + str(test) + "\'> " + str(test) + " - Results: " + str(passes) + " Passed, " + str(fails) + " Failed</a></li>"
diff --git a/TestON/dependencies/rotate.sh b/TestON/dependencies/rotate.sh
index 0f879b6..42fec2d 100755
--- a/TestON/dependencies/rotate.sh
+++ b/TestON/dependencies/rotate.sh
@@ -51,4 +51,4 @@
 #Maybe this should be an argument? pack-and-rotate supports that
 nr_max=20
 
-pack-rotate-log ${root_dir}'/'${base_name} "${root_dir}/${base_name}*.pcap ${root_dir}/${base_name}*.log" ${nr_max}
+pack-rotate-log ${root_dir}'/'${base_name} "${root_dir}/${base_name}*.pcap ${root_dir}/${base_name}*.log*" ${nr_max}
diff --git a/TestON/dependencies/topo-HA.py b/TestON/dependencies/topo-HA.py
new file mode 100644
index 0000000..65613d6
--- /dev/null
+++ b/TestON/dependencies/topo-HA.py
@@ -0,0 +1,63 @@
+from mininet.topo import Topo
+class MyTopo( Topo ):
+    def __init__( self ):
+        Topo.__init__( self )
+        topSwitch = self.addSwitch('s1',dpid='1000'.zfill(16))
+        leftTopSwitch = self.addSwitch('s2',dpid='2000'.zfill(16))
+        rightTopSwitch = self.addSwitch('s5',dpid='5000'.zfill(16))
+        leftBotSwitch = self.addSwitch('s3',dpid='3000'.zfill(16))
+        rightBotSwitch = self.addSwitch('s6',dpid='6000'.zfill(16))	
+        midBotSwitch = self.addSwitch('s28',dpid='2800'.zfill(16))
+        
+        topHost = self.addHost( 'h1' )
+        leftTopHost = self.addHost('h2')
+        rightTopHost = self.addHost('h5')
+        leftBotHost = self.addHost('h3')
+        rightBotHost = self.addHost('h6')
+        midBotHost = self.addHost('h28')
+        self.addLink(topSwitch,topHost)
+        self.addLink(leftTopSwitch,leftTopHost)
+        self.addLink(rightTopSwitch,rightTopHost)
+        self.addLink(leftBotSwitch,leftBotHost)
+        self.addLink(rightBotSwitch,rightBotHost)
+        self.addLink(midBotSwitch,midBotHost)
+        self.addLink(leftTopSwitch,rightTopSwitch)
+        self.addLink(topSwitch,leftTopSwitch)
+        self.addLink(topSwitch,rightTopSwitch)
+        self.addLink(leftTopSwitch,leftBotSwitch)
+        self.addLink(rightTopSwitch,rightBotSwitch)
+        self.addLink(leftBotSwitch,midBotSwitch)
+        self.addLink(midBotSwitch,rightBotSwitch)
+
+        agg1Switch = self.addSwitch('s4',dpid = '3004'.zfill(16))
+        agg2Switch = self.addSwitch('s7',dpid = '6007'.zfill(16))
+        agg1Host = self.addHost('h4')
+        agg2Host = self.addHost('h7')
+        self.addLink(agg1Switch,agg1Host)
+        self.addLink(agg2Switch,agg2Host)
+        self.addLink(agg1Switch, leftBotSwitch)
+        self.addLink(agg2Switch, rightBotSwitch)
+
+        for i in range(10):
+            num = str(i+8)
+            switch = self.addSwitch('s'+num,dpid = ('30'+num.zfill(2)).zfill(16))
+            host = self.addHost('h'+num)
+            self.addLink(switch, host)
+            self.addLink(switch, agg1Switch)
+
+        for i in range(10):
+            num = str(i+18)
+            switch = self.addSwitch('s'+num,dpid = ('60'+num.zfill(2)).zfill(16))
+            host = self.addHost('h'+num)
+            self.addLink(switch, host)
+            self.addLink(switch, agg2Switch)
+
+topos = { 'mytopo': (lambda: MyTopo() ) }
+
+
+
+
+
+
+
+
diff --git a/TestON/drivers/common/cli/dpclidriver.py b/TestON/drivers/common/cli/dpclidriver.py
index 057a3f1..81743d3 100644
--- a/TestON/drivers/common/cli/dpclidriver.py
+++ b/TestON/drivers/common/cli/dpclidriver.py
@@ -1,16 +1,8 @@
 """
 Driver for blank dataplane VMs. Created for SDNIP test.
 """
-import time
 import pexpect
-import struct
-import fcntl
-import os
 import sys
-import signal
-import sys
-import re
-import json
 sys.path.append( "../" )
 from drivers.common.clidriver import CLI
 
@@ -26,9 +18,9 @@
 
         self.name = self.options[ 'name' ]
         self.handle = super( DPCliDriver, self ).connect( user_name=self.user_name,
-         		ip_address=self.ip_address,
-         		port=self.port,
-         		pwd=self.pwd )
+                        ip_address=self.ip_address,
+                        port=self.port,
+                        pwd=self.pwd )
 
         if self.handle:
             return self.handle
@@ -38,11 +30,17 @@
 
     def create_interfaces( self, net, number, start ):
         """
-        Creates a number,specified by 'number,' of subinterfaces on eth0. Ip addresses start at 'net'.'start'.1.1 with a 24 bit netmask. Addresses increment sequentially in the third quad,
-        therefore all interfaces are in different subnets on the same machine. When the third quad reaches 255, it is reset to 1 and the second quad is incremented.
-        Every single ip address is placed in a file in /tmp titled 'ip_table{net}.txt'
-        The file is used by 'pingall_interfaces()' as a fping argument
-        This method returns true if all interfaces are created without a hitch, and false if a single interface has issues
+        Creates a number,specified by 'number,' of subinterfaces on eth0.
+        Ip addresses start at 'net'.'start'.1.1 with a 24 bit netmask.
+        Addresses increment sequentially in the third quad, therefore all
+        interfaces are in different subnets on the same machine. When the
+        third quad reaches 255, it is reset to 1 and the second quad is
+        incremented. Every single ip address is placed in a file in /tmp
+        titled 'ip_table{net}.txt'. The file is used by 'pingall_interfaces()'
+        as a fping argument
+
+        This method returns true if all interfaces are created without a hitch,
+        and false if a single interface has issues
         """
         self.handle.sendline( "" )
         self.handle.expect( "\$" )
@@ -68,11 +66,11 @@
                     intf ) + " " + ip + " netmask 255.255.255.0" )
 
             i = self.handle.expect( [
-				    "\$",
+                                    "\$",
                                     "password",
                                     pexpect.TIMEOUT,
                                     pexpect.EOF ],
-                		    timeout=120 )
+                                    timeout=120 )
 
             if i == 0:
                 self.handle.sendline(
@@ -88,22 +86,27 @@
 
     def pingall_interfaces( self, netsrc, netstrt, netdst, destlogin, destip ):
         """
-        Copies the /tmp/ip_table{ net }.txt file from the machine you wish to ping, then runs fping with a source address of { netsrc }.{ netstrt }.1.1 on the copied file.
-        Check every single response for reachable or unreachable. If all are reachable, function returns true. If a SINGLE host is unreachable, then the function stops and returns false
-        If fping is not installed, this function will install fping then run the same command
+        Copies the /tmp/ip_table{ net }.txt file from the machine you wish to
+        ping, then runs fping with a source address of
+        { netsrc }.{ netstrt }.1.1 on the copied file.
+        Check every single response for reachable or unreachable. If all are
+        reachable, function returns true. If a SINGLE host is unreachable,
+        then the function stops and returns false. If fping is not installed,
+        this function will install fping then run the same command
         """
         self.handle.sendline( "" )
         self.handle.expect( "\$" )
 
-        self.handle.sendline( "scp " + str( destlogin ) + "@" + 
-			      str( destip ) + ":/tmp/local_ip.txt /tmp/ip_table" +
-			      str( net ) + ".txt" )
-        
-	i = self.handle.expect( [
-				"100%",
+        self.handle.sendline( "scp " + str( destlogin ) + "@" +
+                              str( destip ) +
+                              ":/tmp/local_ip.txt /tmp/ip_table" +
+                              str( netsrc ) + ".txt" )
+
+        i = self.handle.expect( [
+                                "100%",
                                 "password",
                                 pexpect.TIMEOUT ],
-		                timeout=30 )
+                                timeout=30 )
 
         if i == 0:
             main.log.info( "Copied ping file successfully" )
@@ -120,20 +123,20 @@
         self.handle.expect( "\$" )
 
         main.log.info( "Pinging interfaces on the " + str( netdst ) +
-		       " network from " + str( netsrc ) + "." + 
-		       str( netstrt ) + ".1.1" )
+                       " network from " + str( netsrc ) + "." +
+                       str( netstrt ) + ".1.1" )
         self.handle.sendline( "sudo fping -S " + str( netsrc ) + "." +
-			      str( netstrt ) + ".1.1 -f /tmp/ip_table" + 
-			      str( netdst ) + ".txt" )
+                              str( netstrt ) + ".1.1 -f /tmp/ip_table" +
+                              str( netdst ) + ".txt" )
         while 1:
             i = self.handle.expect( [
-				    "reachable",
+                                    "reachable",
                                     "unreachable",
                                     "\$",
                                     "password",
                                     pexpect.TIMEOUT,
                                     "not installed" ],
-				    timeout=45 )
+                                    timeout=45 )
             if i == 0:
                 result = main.TRUE
             elif i == 1:
@@ -142,6 +145,7 @@
                 return result
             elif i == 2:
                 main.log.info( "All interfaces reachable" )
+                result = main.FALSE
                 return result
             elif i == 3:
                 self.handle.sendline( self.pwd )
@@ -152,11 +156,10 @@
             elif i == 5:
                 main.log.info( "fping not installed, installing fping" )
                 self.handle.sendline( "sudo apt-get install fping" )
-                i = self.handle.expect(
-                    [ "password",
-                                      "\$",
-                                      pexpect.TIMEOUT ],
-                    timeout=60 )
+                i = self.handle.expect( [ "password",
+                                          "\$",
+                                          pexpect.TIMEOUT ],
+                                        timeout=60 )
                 if i == 0:
                     self.handle.sendline( self.pwd )
                     self.handle.expect( "\$", timeout=30 )
@@ -183,8 +186,8 @@
         try:
             self.handle.sendline( "exit" )
             self.handle.expect( "closed" )
-        except:
-            main.log.error( "Connection failed to the host" )
+        except pexpect.ExceptionPexpect:
+            main.log.exception( "Connection failed to the host" )
             response = main.FALSE
         return response
 
diff --git a/TestON/drivers/common/cli/emulator/flowvisordriver.py b/TestON/drivers/common/cli/emulator/flowvisordriver.py
index d0e6ea5..46c47a7 100644
--- a/TestON/drivers/common/cli/emulator/flowvisordriver.py
+++ b/TestON/drivers/common/cli/emulator/flowvisordriver.py
@@ -21,17 +21,10 @@
 
 FlowVisorDriver is the basic driver which will handle the Mininet functions
 """
-import pexpect
-import struct
-import fcntl
-import os
-import signal
 import re
 import sys
-import core.teston
 sys.path.append( "../" )
 from drivers.common.cli.emulatordriver import Emulator
-from drivers.common.clidriver import CLI
 
 
 class FlowVisorDriver( Emulator ):
@@ -147,15 +140,15 @@
         try :
             if self.dl_src and self.nw_dst:
                 flowspace = "any 100 dl_type=0x806,dl_src="+self.dl_src+",nw_dst="+self.nw_dst+" Slice:"+self.Slice+"=4"
-        except :
+        except Exception:
             try :
                 if self.nw_src and self.tp_dst:
                     flowspace = "any 100 dl_type=0x800,nw_proto=6,nw_src="+self.nw_src+",tp_dst="+self.tp_dst+" Slice:"+self.Slice+"=4"
-            except :
+            except Exception:
                 try :
                     if self.nw_src and self.tp_src:
                         flowspace = "any 100 dl_type=0x800,nw_proto=6,nw_src="+self.nw_src+",tp_src="+self.tp_dst+" Slice:"+self.Slice+"=4"
-                except :
+                except Exception:
                     main.log.error( "Please specify flowspace properly" )
         """
         # self.execute( cmd="clear",prompt="\$",timeout=10 )
diff --git a/TestON/drivers/common/cli/emulator/lincoedriver.py b/TestON/drivers/common/cli/emulator/lincoedriver.py
index 82179a5..b1bc05a 100644
--- a/TestON/drivers/common/cli/emulator/lincoedriver.py
+++ b/TestON/drivers/common/cli/emulator/lincoedriver.py
@@ -14,20 +14,11 @@
 
 OCT 20 2014
 """
-import traceback
+
 import pexpect
-import struct
-import fcntl
-import os
-import signal
-import re
 import sys
-import core.teston
-import time
 sys.path.append( "../" )
-from math import pow
 from drivers.common.cli.emulatordriver import Emulator
-from drivers.common.clidriver import CLI
 
 
 class LincOEDriver( Emulator ):
@@ -45,7 +36,6 @@
         """
         Create ssh handle for Linc-OE cli
         """
-        import time
 
         for key in connectargs:
             vars( self )[ key ] = connectargs[ key ]
@@ -127,10 +117,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " :::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " :::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -153,10 +141,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " :::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " :::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -175,10 +161,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " :::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " :::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -197,10 +181,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " :::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " :::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -220,10 +202,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " :::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " :::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -242,10 +222,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " :::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " :::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -265,10 +243,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " :::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " :::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -288,10 +264,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " :::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " :::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -339,10 +313,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " :::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " :::::::" )
+        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 fbd863e..a6436ca 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -35,7 +35,6 @@
 
     Note that you may need to run 'sudo make develop' if your mnexec.c file
 changed when switching branches."""
-import traceback
 import pexpect
 import re
 import sys
@@ -52,6 +51,7 @@
     def __init__( self ):
         super( Emulator, self ).__init__()
         self.handle = self
+        self.name = None
         self.wrapped = sys.modules[ __name__ ]
         self.flag = 0
 
@@ -73,35 +73,32 @@
                 pwd=self.pwd )
 
             if self.handle:
-                main.log.info("Connection successful to the host " +
-                        self.user_name +
-                        "@" +
-                        self.ip_address )
+                main.log.info( "Connection successful to the host " +
+                               self.user_name +
+                               "@" +
+                               self.ip_address )
                 return main.TRUE
             else:
                 main.log.error( "Connection failed to the host " +
-                        self.user_name +
-                        "@" +
-                        self.ip_address )
-                msin.log.error( "Failed to connect to the Mininet CLI" )
+                                self.user_name +
+                                "@" +
+                                self.ip_address )
+                main.log.error( "Failed to connect to the Mininet CLI" )
                 return main.FALSE
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":     " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + ":::::::::::::::::::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( ":::::::::::::::::::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
-
-    def startNet( self, topoFile = '', args = '', timeout = 120 ):
+    def startNet( self, topoFile='', args='', timeout=120 ):
         """
         Starts Mininet accepts a topology(.py) file and/or an optional
-        arguement ,to start the mininet, as a parameter.
+        argument ,to start the mininet, as a parameter.
         Returns main.TRUE if the mininet starts successfully and
                 main.FALSE otherwise
         """
@@ -118,7 +115,7 @@
             if i == 0:
                 main.log.info( self.name + ": Sending sudo password" )
                 self.handle.sendline( self.pwd )
-                i = self.handle.expect( [ '%s:' % ( self.user ),
+                i = self.handle.expect( [ '%s:' % self.user,
                                           '\$',
                                           pexpect.EOF,
                                           pexpect.TIMEOUT ],
@@ -131,7 +128,7 @@
                 main.log.error(
                     self.name +
                     ": Something while cleaning MN took too long... " )
-            if topoFile == ''  and  args ==  '':
+            if topoFile == '' and args == '':
                 main.log.info( self.name + ": building fresh mininet" )
                 # for reactive/PARP enabled tests
                 cmdString = "sudo mn " + self.options[ 'arg1' ] +\
@@ -180,15 +177,14 @@
                 return main.TRUE
             else:
                 main.log.info( "Starting topo file " + topoFile )
-                if args == None:
+                if args is None:
                     args = ''
                 else:
                     main.log.info( "args = " + args)
                 self.handle.sendline( 'sudo ' + topoFile + ' ' + args)
-                i = 1
                 i = self.handle.expect( [ 'mininet>',
-                                        pexpect.EOF ,
-                                        pexpect.TIMEOUT ],
+                                          pexpect.EOF,
+                                          pexpect.TIMEOUT ],
                                         timeout)
                 if i == 0:
                     main.log.info(self.name + ": Network started")
@@ -244,10 +240,8 @@
             numLinks = totalNumHosts + ( numSwitches - 1 )
             print "num_switches for %s(%d,%d) = %d and links=%d" %\
                 ( topoType, depth, fanout, numSwitches, numLinks )
-        topoDict = {}
-        topoDict = {
-            "num_switches": int( numSwitches ),
-            "num_corelinks": int( numLinks ) }
+        topoDict = { "num_switches": int( numSwitches ),
+                     "num_corelinks": int( numLinks ) }
         return topoDict
 
     def calculateSwAndLinks( self ):
@@ -332,7 +326,7 @@
         command = args[ "SRC" ] + " ping " + \
             args[ "TARGET" ] + " -c 1 -i 1 -W 8"
         try:
-            main.log.warn( "Sending: " + command )
+            main.log.info( "Sending: " + command )
             self.handle.sendline( command )
             i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
             if i == 1:
@@ -397,6 +391,7 @@
             main.log.error( self.name + ": Connection failed to the host" )
 
     def verifySSH( self, **connectargs ):
+        # FIXME: Who uses this and what is the purpose? seems very specific
         try:
             response = self.execute(
                 cmd="h1 /usr/sbin/sshd -D&",
@@ -437,17 +432,16 @@
         if self.handle:
             try:
                 # Bring link between oldSw-host down
-                cmd = "py net.configLinkStatus('" + oldSw + "'," + "'" + host + "'," +\
-                "'down')"
+                cmd = "py net.configLinkStatus('" + oldSw + "'," + "'"+ host +\
+                      "'," + "'down')"
                 print "cmd1= ", cmd
-                response = self.execute(
-                cmd=cmd,
-                prompt="mininet>",
-                timeout=10 )
+                response = self.execute( cmd=cmd,
+                                         prompt="mininet>",
+                                         timeout=10 )
      
                 # Determine hostintf and Oldswitchintf
                 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + oldSw +\
-                ")[0]"
+                      ")[0]"
                 print "cmd2= ", cmd
                 self.handle.sendline( cmd )
                 self.handle.expect( "mininet>" )
@@ -477,7 +471,7 @@
  
                 # Determine hostintf and Newswitchintf
                 cmd = "px hintf,sintf = " + host + ".connectionsTo(" + newSw +\
-                ")[0]"
+                      ")[0]"
                 print "cmd6= ", cmd
                 self.handle.sendline( cmd )
                 self.handle.expect( "mininet>" )                 
@@ -566,7 +560,7 @@
 
     def addStaticMACAddress( self, host, GW, macaddr ):
         """
-           Changes the mac address of a geateway host"""
+           Changes the mac address of a gateway host"""
         if self.handle:
             try:
                 # h1  arp -s 10.0.1.254 00:00:00:00:11:11
@@ -576,7 +570,7 @@
                 response = self.handle.before
                 main.log.info( "response = " + response )
                 main.log.info(
-                    "Mac adrress of gateway " +
+                    "Mac address of gateway " +
                     GW +
                     " changed to " +
                     macaddr )
@@ -805,7 +799,7 @@
             self.handle.expect( "mininet>" )
             response = self.handle.before
             if re.search( 'Results:', response ):
-                main.log.info( self.name + ": iperf test succssful" )
+                main.log.info( self.name + ": iperf test successful" )
                 return main.TRUE
             else:
                 main.log.error( self.name + ": iperf test failed" )
@@ -957,6 +951,8 @@
         return main.TRUE
 
     def getVersion( self ):
+        #FIXME: What uses this? This should be refactored to get
+        #       version from MN and not some other file
         fileInput = path + '/lib/Mininet/INSTALL'
         version = super( Mininet, self ).getVersion()
         pattern = 'Mininet\s\w\.\w\.\w\w*'
@@ -1032,10 +1028,8 @@
             main.log.error( self.name + ":     " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + ":" * 50 )
-            main.log.error( traceback.print_exc() )
-            main.log.info( ":" * 50 )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -1063,10 +1057,10 @@
             dynamic_topo branch
         NOTE: cannot currently specify what type of switch
         required params:
-            switchname = name of the new switch as a string
-        optional keyvalues:
+            sw = name of the new switch as a string
+        optional keywords:
             dpid = "dpid"
-        returns: main.FASLE on an error, else main.TRUE
+        returns: main.FALSE on an error, else main.TRUE
         """
         dpid = kwargs.get( 'dpid', '' )
         command = "addswitch " + str( sw ) + " " + str( dpid )
@@ -1098,8 +1092,8 @@
         NOTE: This uses a custom mn function. MN repo should be on
             dynamic_topo branch
         required params:
-            switchname = name of the switch as a string
-        returns: main.FASLE on an error, else main.TRUE"""
+            sw = name of the switch as a string
+        returns: main.FALSE on an error, else main.TRUE"""
         command = "delswitch " + str( sw )
         try:
             response = self.execute(
@@ -1132,7 +1126,7 @@
            required params:
            node1 = the string node name of the first endpoint of the link
            node2 = the string node name of the second endpoint of the link
-           returns: main.FASLE on an error, else main.TRUE"""
+           returns: main.FALSE on an error, else main.TRUE"""
         command = "addlink " + str( node1 ) + " " + str( node2 )
         try:
             response = self.execute(
@@ -1164,7 +1158,7 @@
            required params:
            node1 = the string node name of the first endpoint of the link
            node2 = the string node name of the second endpoint of the link
-           returns: main.FASLE on an error, else main.TRUE"""
+           returns: main.FALSE on an error, else main.TRUE"""
         command = "dellink " + str( node1 ) + " " + str( node2 )
         try:
             response = self.execute(
@@ -1198,7 +1192,7 @@
             hostname = the string hostname
         optional key-value params
             switch = "switch name"
-            returns: main.FASLE on an error, else main.TRUE
+            returns: main.FALSE on an error, else main.TRUE
         """
         switch = kwargs.get( 'switch', '' )
         command = "addhost " + str( hostname ) + " " + str( switch )
@@ -1235,7 +1229,7 @@
            NOTE: this uses a custom mn function
            required params:
            hostname = the string hostname
-           returns: main.FASLE on an error, else main.TRUE"""
+           returns: main.FALSE on an error, else main.TRUE"""
         command = "delhost " + str( hostname )
         try:
             response = self.execute(
@@ -1266,7 +1260,7 @@
         """
         self.handle.sendline('')
         i = self.handle.expect( [ 'mininet>', pexpect.EOF, pexpect.TIMEOUT ],
-                                timeout = 2)
+                                timeout=2)
         if i == 0:
             self.stopNet()
         elif i == 1:
@@ -1281,10 +1275,10 @@
             main.log.error( "Connection failed to the host" )
         return response
 
-    def stopNet( self , timeout = 5):
+    def stopNet( self, timeout=5):
         """
         Stops mininet.
-        Returns main.TRUE if the mininet succesfully stops and
+        Returns main.TRUE if the mininet successfully stops and
                 main.FALSE if the pexpect handle does not exist.
 
         Will cleanup and exit the test if mininet fails to stop
@@ -1330,8 +1324,6 @@
             response = main.FALSE
         return response
 
-
-
     def arping( self, src, dest, destmac ):
         self.handle.sendline( '' )
         self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
@@ -1342,7 +1334,7 @@
             main.log.info( self.name + ": ARP successful" )
             self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
             return main.TRUE
-        except:
+        except Exception:
             main.log.warn( self.name + ": ARP FAILURE" )
             self.handle.expect( [ "mininet", pexpect.EOF, pexpect.TIMEOUT ] )
             return main.FALSE
@@ -1393,12 +1385,10 @@
             main.log.error( self.name + ":     " + self.handle.before )
             main.cleanup()
             main.exit()
-        else:
-            main.log.info( response )
 
     def startTcpdump( self, filename, intf="eth0", port="port 6633" ):
         """
-           Runs tpdump on an intferface and saves the file
+           Runs tpdump on an interface and saves the file
            intf can be specified, or the default eth0 is used"""
         try:
             self.handle.sendline( "" )
@@ -1448,15 +1438,14 @@
             main.log.error( self.name + ":     " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + ":" * 50 )
-            main.log.error( traceback.print_exc() )
-            main.log.info( ":" * 50 )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
     def stopTcpdump( self ):
-        "pkills tcpdump"
+        """
+            pkills tcpdump"""
         try:
             self.handle.sendline( "sh sudo pkill tcpdump" )
             self.handle.expect( "mininet>" )
@@ -1467,10 +1456,8 @@
             main.log.error( self.name + ":     " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + ":" * 50 )
-            main.log.error( traceback.print_exc() )
-            main.log.info( ":" * 50 )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -1489,8 +1476,7 @@
             ports = []
             for port in switch.ports.values():
                 ports.append( { 'of_port': port.port_no,
-                                'mac': str( port.hw_addr ).replace( '\'',
-                                                                   '' ),
+                                'mac': str( port.hw_addr ).replace( '\'', '' ),
                                 'name': port.name } )
             output[ 'switches' ].append( {
                 "name": switch.name,
@@ -1499,12 +1485,12 @@
 
         # print "mn"
         # print json.dumps( output,
-        #                   sortKeys=True,
+        #                   sort_keys=True,
         #                   indent=4,
         #                   separators=( ',', ': ' ) )
         # print "onos"
         # print json.dumps( switchesJson,
-        #                   sortKeys=True,
+        #                   sort_keys=True,
         #                   indent=4,
         #                   separators=( ',', ': ' ) )
 
@@ -1571,17 +1557,15 @@
             ports = []
             for port in switch.ports.values():
                 # print port.hw_addr.toStr( separator='' )
-                tmpPort = {}
-                tmpPort[ 'of_port' ] = port.port_no
-                tmpPort[ 'mac' ] = str( port.hw_addr ).replace( '\'', '' )
-                tmpPort[ 'name' ] = port.name
-                tmpPort[ 'enabled' ] = port.enabled
+                tmpPort = { 'of_port': port.port_no,
+                            'mac': str( port.hw_addr ).replace( '\'', '' ),
+                            'name': port.name,
+                            'enabled': port.enabled }
 
                 ports.append( tmpPort )
-            tmpSwitch = {}
-            tmpSwitch[ 'name' ] = switch.name
-            tmpSwitch[ 'dpid' ] = str( switch.dpid ).zfill( 16 )
-            tmpSwitch[ 'ports' ] = ports
+            tmpSwitch = { 'name': switch.name,
+                          'dpid': str( switch.dpid ).zfill( 16 ),
+                          'ports': ports }
 
             output[ 'switches' ].append( tmpSwitch )
 
@@ -1662,8 +1646,7 @@
 
            This uses the sts TestONTopology object"""
         # FIXME: this does not look for extra links in ONOS, only checks that
-        # ONOS has what is in MN
-        linkResults = main.TRUE
+        #        ONOS has what is in MN
         output = { "switches": [] }
         onos = linksJson
         # iterate through the MN topology and pull out switches and and port
@@ -1675,8 +1658,7 @@
             for port in switch.ports.values():
                 # print port.hw_addr.toStr( separator='' )
                 ports.append( { 'of_port': port.port_no,
-                                'mac': str( port.hw_addr ).replace( '\'',
-                                                                   '' ),
+                                'mac': str( port.hw_addr ).replace( '\'', '' ),
                                 'name': port.name } )
             output[ 'switches' ].append( {
                 "name": switch.name,
@@ -1752,7 +1734,7 @@
                         main.log.warn(
                             'The port numbers do not match for ' +
                             str( link ) +
-                            ' between ONOS and MN. When cheking ONOS for ' +
+                            ' between ONOS and MN. When checking ONOS for ' +
                             'link %s/%s -> %s/%s' %
                             ( node1,
                               port1,
@@ -1774,7 +1756,7 @@
                         main.log.warn(
                             'The port numbers do not match for ' +
                             str( link ) +
-                            ' between ONOS and MN. When cheking ONOS for ' +
+                            ' between ONOS and MN. When checking ONOS for ' +
                             'link %s/%s -> %s/%s' %
                             ( node2,
                               port2,
@@ -1798,6 +1780,64 @@
             linkResults = linkResults and firstDir and secondDir
         return linkResults
 
+    def compareHosts( self, topo, hostsJson ):
+        """
+           Compare mn and onos Hosts.
+           Since Mininet hosts are quiet, ONOS will only know of them when they
+           speak. For this reason, we will only check that the hosts in ONOS
+           stores are in Mininet, and not vice versa.
+           topo: sts TestONTopology object
+           hostsJson: parsed json object from the onos hosts api
+
+           This uses the sts TestONTopology object"""
+        import json
+        hostResults = main.TRUE
+        hosts = []
+        # iterate through the MN topology and pull out hosts
+        for mnHost in topo.graph.hosts:
+            interfaces = []
+            for intf in mnHost.interfaces:
+                interfaces.append( {
+                    "name": intf.name,  # str
+                    "ips": [ str( ip ) for ip in intf.ips ],  # list of IPAddrs
+                    # hw_addr is of type EthAddr, Not JSON serializable
+                    "hw_addr": str( intf.hw_addr ) } )
+            hosts.append( {
+                "name": mnHost.name,  # str
+                "interfaces": interfaces  } )  # list
+        for onosHost in hostsJson:
+            onosMAC = onosHost[ 'mac' ].lower()
+            match = False
+            for mnHost in hosts:
+                for mnIntf in mnHost[ 'interfaces' ]:
+                    if onosMAC == mnIntf[ 'hw_addr' ].lower() :
+                        match = True
+                        for ip in mnIntf[ 'ips' ]:
+                            if ip in onosHost[ 'ips' ]:
+                                pass  # all is well
+                            else:
+                                # misssing ip
+                                main.log.error( "ONOS host " + onosHost[ 'id' ]
+                                                + " has a different IP than " +
+                                                "the Mininet host." )
+                                output = json.dumps(
+                                                    onosHost,
+                                                    sort_keys=True,
+                                                    indent=4,
+                                                    separators=( ',', ': ' ) )
+                                main.log.info( output )
+                                hostResults = main.FALSE
+            if not match:
+                hostResults = main.FALSE
+                main.log.error( "ONOS host " + onosHost[ 'id' ] + " has no " +
+                                "corresponding Mininet host." )
+                output = json.dumps( onosHost,
+                                     sort_keys=True,
+                                     indent=4,
+                                     separators=( ',', ': ' ) )
+                main.log.info( output )
+        return hostResults
+
     def getHosts( self ):
         """
            Returns a list of all hosts
@@ -1827,7 +1867,7 @@
            updates the port address and status information for
            each port in mn"""
         # TODO: Add error checking. currently the mininet command has no output
-        main.log.info( "Updateing MN port information" )
+        main.log.info( "Updating MN port information" )
         try:
             self.handle.sendline( "" )
             self.handle.expect( "mininet>" )
diff --git a/TestON/drivers/common/cli/emulator/remotemininetdriver.py b/TestON/drivers/common/cli/emulator/remotemininetdriver.py
index 9c9585a..e451335 100644
--- a/TestON/drivers/common/cli/emulator/remotemininetdriver.py
+++ b/TestON/drivers/common/cli/emulator/remotemininetdriver.py
@@ -21,7 +21,6 @@
 
 MininetCliDriver is the basic driver which will handle the Mininet functions
 """
-import traceback
 import pexpect
 import re
 import sys
@@ -40,6 +39,7 @@
     def __init__( self ):
         super( Emulator, self ).__init__()
         self.handle = self
+        self.name = None
         self.wrapped = sys.modules[ __name__ ]
         self.flag = 0
 
@@ -59,8 +59,6 @@
             port=None,
             pwd=self.pwd )
 
-        self.sshHandle = self.handle
-
         # Copying the readme file to process the
         if self.handle:
             return main.TRUE
@@ -99,7 +97,7 @@
 
     def pingLong( self, **pingParams ):
         """
-        Starts a continuous ping on the mininet host outputing
+        Starts a continuous ping on the mininet host outputting
         to a file in the /tmp dir.
         """
         self.handle.sendline( "" )
@@ -109,8 +107,9 @@
         precmd = "sudo rm /tmp/ping." + args[ "SRC" ]
         self.execute( cmd=precmd, prompt="(.*)", timeout=10 )
         command = "sudo mininet/util/m " + args[ "SRC" ] + " ping " +\
-                args[ "TARGET" ] + " -i .2 -w " + str( args[ 'PINGTIME' ] ) +\
-                " -D > /tmp/ping." + args[ "SRC" ] + " &"
+                  args[ "TARGET" ] + " -i .2 -w " +\
+                  str( args[ 'PINGTIME' ] ) + " -D > /tmp/ping." +\
+                  args[ "SRC" ] + " &"
         main.log.info( command )
         self.execute( cmd=command, prompt="(.*)", timeout=10 )
         self.handle.sendline( "" )
@@ -182,7 +181,7 @@
 
     def pingHostOptical( self, **pingParams ):
         """
-        This function is only for Packey Optical related ping
+        This function is only for Packet Optical related ping
         Use the next pingHost() function for all normal scenarios )
         Ping from one mininet host to another
         Currently the only supported Params: SRC and TARGET
@@ -281,7 +280,7 @@
             port="port 6633",
             user="admin" ):
         """
-        Runs tpdump on an intferface and saves the file
+        Runs tcpdump on an interface and saves the file
         intf can be specified, or the default eth0 is used
         """
         try:
@@ -300,7 +299,7 @@
             self.handle.sendline( "" )
             i = self.handle.expect( [ 'No\ssuch\device', 'listening\son',
                                     pexpect.TIMEOUT, "\$" ], timeout=10 )
-            main.log.warn( self.handle.before + self.handle.after )
+            main.log.info( self.handle.before + self.handle.after )
             if i == 0:
                 main.log.error( self.name + ": tcpdump - No such device exists.\
                         tcpdump attempted on: " + intf )
@@ -323,16 +322,14 @@
             main.log.error( self.name + ":     " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info(
-                    self.name + ":" * 60 )
-            main.log.error( traceback.print_exc() )
-            main.log.info( ":" * 80 )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
     def stopTcpdump( self ):
-        "pkills tcpdump"
+        """
+            pkills tcpdump"""
         try:
             self.handle.sendline( "sudo pkill tcpdump" )
             self.handle.sendline( "" )
@@ -342,11 +339,8 @@
             main.log.error( self.name + ":     " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info(
-                    self.name + ":" * 60 )
-            main.log.error( traceback.print_exc() )
-            main.log.info( ":" * 80 )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -376,9 +370,9 @@
         if self.handle:
             # Close the ssh connection
             self.handle.sendline( "" )
-            #self.handle.expect( "\$" )
+            # self.handle.expect( "\$" )
             i = self.handle.expect( [ '\$', 'mininet>', pexpect.TIMEOUT ],
-                                timeout = 2)
+                                    timeout=2)
             if i == 0:
                 self.handle.sendline( "exit" )
                 self.handle.expect( "closed" )
@@ -397,7 +391,7 @@
     def getFlowTable( self, protoVersion, sw ):
         """
          TODO document usage
-         TODO add option to look at cookies. ignoreing them for now
+         TODO add option to look at cookies. ignoring them for now
 
          print "get_flowTable(" + str( protoVersion ) +" " + str( sw ) +")"
          NOTE: Use format to force consistent flow table output across
@@ -570,7 +564,7 @@
                             str( rule ) )
 
                         infoString = "Rules added to " + str( self.name )
-                        infoString += "iptable rule added to block IP: " + \
+                        infoString += "iptables rule added to block IP: " + \
                             str( dstIp )
                         infoString += "Port: " + \
                             str( dstPort ) + " Rule: " + str( rule )
@@ -583,8 +577,9 @@
                         main.log.error(
                             self.name +
                             ": Timeout exception in setIpTables function" )
-                    except:
-                        main.log.error( traceback.print_exc() )
+                    except Exception:
+                        main.log.exception( self.name +
+                                            ": Uncaught exception!" )
                         main.cleanup()
                         main.exit()
                 else:
@@ -626,8 +621,9 @@
                         main.log.error(
                             self.name +
                             ": Timeout exception in setIpTables function" )
-                    except:
-                        main.log.error( traceback.print_exc() )
+                    except Exception:
+                        main.log.exception( self.name +
+                                            ": Uncaught exception!" )
                         main.cleanup()
                         main.exit()
                 else:
diff --git a/TestON/drivers/common/cli/emulatordriver.py b/TestON/drivers/common/cli/emulatordriver.py
index bb8da7c..778a32b 100644
--- a/TestON/drivers/common/cli/emulatordriver.py
+++ b/TestON/drivers/common/cli/emulatordriver.py
@@ -19,12 +19,6 @@
 
 
 """
-import pexpect
-import struct
-import fcntl
-import os
-import sys
-import signal
 import sys
 sys.path.append( "../" )
 from drivers.common.clidriver import CLI
diff --git a/TestON/drivers/common/cli/onosclidriver.py b/TestON/drivers/common/cli/onosclidriver.py
index e88aab2..baed719 100644
--- a/TestON/drivers/common/cli/onosclidriver.py
+++ b/TestON/drivers/common/cli/onosclidriver.py
@@ -19,6 +19,8 @@
 import sys
 import pexpect
 import re
+import json
+import types
 sys.path.append( "../" )
 from drivers.common.clidriver import CLI
 
@@ -29,6 +31,9 @@
         """
         Initialize client
         """
+        self.name = None
+        self.home = None
+        self.handle = None
         super( CLI, self ).__init__()
 
     def connect( self, **connectargs ):
@@ -38,14 +43,14 @@
         try:
             for key in connectargs:
                 vars( self )[ key ] = connectargs[ key ]
-            self.home = "~/ONOS"
+            self.home = "~/onos"
             for key in self.options:
                 if key == "home":
                     self.home = self.options[ 'home' ]
                     break
-            if self.home == None or self.home == "":
-                self.home = "~/ONOS"
-            
+            if self.home is None or self.home == "":
+                self.home = "~/onos"
+
             self.name = self.options[ 'name' ]
             self.handle = super( OnosCliDriver, self ).connect(
                 user_name=self.user_name,
@@ -69,7 +74,7 @@
             main.log.error( self.name + ":     " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -80,25 +85,23 @@
         """
         response = main.TRUE
         try:
-            self.handle.sendline( "" )
-            i = self.handle.expect( [ "onos>", "\$" ] )
-            if i == 0:
-                self.handle.sendline( "system:shutdown" )
-                self.handle.expect( "Confirm" )
-                self.handle.sendline( "yes" )
-                self.handle.expect( "\$" )
-            self.handle.sendline( "" )
-            self.handle.expect( "\$" )
-            self.handle.sendline( "exit" )
-            self.handle.expect( "closed" )
-
+            if self.handle:
+                i = self.logout()
+                if i == main.TRUE:
+                    self.handle.sendline( "" )
+                    self.handle.expect( "\$" )
+                    self.handle.sendline( "exit" )
+                    self.handle.expect( "closed" )
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             response = main.FALSE
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":     " + self.handle.before )
-        except:
+        except ValueError:
+            main.log.exception( "Exception in discconect of " + self.name )
+            response = main.TRUE
+        except Exception:
             main.log.exception( self.name + ": Connection failed to the host" )
             response = main.FALSE
         return response
@@ -106,28 +109,38 @@
     def logout( self ):
         """
         Sends 'logout' command to ONOS cli
+        Returns main.TRUE if exited CLI and
+                main.FALSE on timeout (not guranteed you are disconnected)
+                None on TypeError
+                Exits test on unknown error or pexpect exits unexpectedly
         """
         try:
-            self.handle.sendline( "" )
-            i = self.handle.expect( [
-                "onos>",
-                "\$" ], timeout=10 )
-            if i == 0:
-                self.handle.sendline( "logout" )
-                self.handle.expect( "\$" )
-            elif i == 1:
+            if self.handle:
+                self.handle.sendline( "" )
+                i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
+                                        timeout=10 )
+                if i == 0:  # In ONOS CLI
+                    self.handle.sendline( "logout" )
+                    self.handle.expect( "\$" )
+                    return main.TRUE
+                elif i == 1:  # not in CLI
+                    return main.TRUE
+                elif i == 3:  # Timeout
+                    return main.FALSE
+            else:
                 return main.TRUE
-
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
         except pexpect.EOF:
             main.log.error( self.name + ": eof exception found" )
-            main.log.error( self.name + ":    " +
-                            self.handle.before )
+            main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except ValueError:
+            main.log.error( self.name +
+                            "ValueError exception in logout method" )
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -148,12 +161,12 @@
                 # 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( "ONOS_CELL" )
+                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.sendline("")
+                self.handle.expect("\$")
                 handleMore = self.handle.before
 
                 main.log.info( "Cell call returned: " + handleBefore +
@@ -169,14 +182,14 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
     def startOnosCli( self, ONOSIp, karafTimeout="" ):
         """
-        karafTimeout is an optional arugument. karafTimeout value passed
+        karafTimeout is an optional argument. karafTimeout value passed
         by user would be used to set the current karaf shell idle timeout.
         Note that when ever this property is modified the shell will exit and
         the subsequent login would reflect new idle timeout.
@@ -247,16 +260,16 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
-    def log( self, cmdStr , level = "" ):
+    def log( self, cmdStr, level="" ):
         """
             log  the commands in the onos CLI.
             returns main.TRUE on success
-            returns main.FALSE if Error occured
+            returns main.FALSE if Error occurred
             Available level: DEBUG, TRACE, INFO, WARN, ERROR
             Level defaults to INFO
         """
@@ -269,7 +282,7 @@
             self.handle.expect( "onos>" )
             self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
             self.handle.expect( "onos>" )
-            
+
             response = self.handle.before
             if re.search( "Error", response ):
                 return main.FALSE
@@ -280,10 +293,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -297,25 +308,31 @@
         sent using this method.
         """
         try:
-            
             logStr = "\"Sending CLI command: '" + cmdStr + "'\""
             self.log( logStr )
             self.handle.sendline( cmdStr )
-            self.handle.expect( "onos>" )
+            i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
+            response = self.handle.before
+            if i == 2:
+                self.handle.sendline()
+                self.handle.expect( "\$" )
+                response += self.handle.before
+                print response
+                try:
+                    print self.handle.after
+                except:
+                    pass
+            # TODO: do something with i
             main.log.info( "Command '" + str( cmdStr ) + "' sent to "
                            + self.name + "." )
-
-            handle = self.handle.before
             # Remove control strings from output
             ansiEscape = re.compile( r'\x1b[^m]*m' )
-            handle = ansiEscape.sub( '', handle )
-            #Remove extra return chars that get added
-            handle = re.sub(  r"\s\r", "", handle )
-            handle = handle.strip()
-            # parse for just the output, remove the cmd from handle
-            output = handle.split( cmdStr, 1 )[1]
-
-
+            response = ansiEscape.sub( '', response )
+            # Remove extra return chars that get added
+            response = re.sub(  r"\s\r", "", response )
+            response = response.strip()
+            # parse for just the output, remove the cmd from response
+            output = response.split( cmdStr, 1 )[1]
             return output
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -325,7 +342,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -365,7 +382,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -393,21 +410,29 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
-    def nodes( self ):
+    def nodes( self, jsonFormat=True):
         """
         List the nodes currently visible
         Issues command: 'nodes'
-        Returns: entire handle of list of nodes
+        Optional argument:
+            * jsonFormat - boolean indicating if you want output in json
         """
         try:
-            cmdStr = "nodes"
-            handle = self.sendline( cmdStr )
-            return handle
+            if jsonFormat:
+                cmdStr = "nodes -j"
+                output = self.sendline( cmdStr )
+                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
+                parsedOutput = ansiEscape.sub( '', output )
+                return parsedOutput
+            else:
+                cmdStr = "nodes"
+                output = self.sendline( cmdStr )
+                return output
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -416,21 +441,24 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
     def topology( self ):
         """
-        Shows the current state of the topology
-        by issusing command: 'onos> onos:topology'
+        Definition:
+            Returns the ouput of topology command.
+        Return:
+            topology = current ONOS topology
         """
+        import json
         try:
             # either onos:topology or 'topology' will work in CLI
-            cmdStr = "onos:topology"
+            cmdStr = "topology -j"
             handle = self.sendline( cmdStr )
-            main.log.info( "onos:topology returned: " + str( handle ) )
+            main.log.info( "topology -j returned: " + str( handle ) )
             return handle
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -440,7 +468,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -465,7 +493,7 @@
             main.log.report( "Exiting test" )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.log.report( "Failed to install feature" )
             main.log.report( "Exiting test" )
@@ -478,9 +506,15 @@
         by issuing command: 'onos> feature:uninstall <feature_str>'
         """
         try:
-            cmdStr = "feature:uninstall " + str( featureStr )
-            self.sendline( cmdStr )
-            # TODO: Check for possible error responses from karaf
+            cmdStr = 'feature:list -i | grep "' + featureStr + '"'
+            handle = self.sendline( cmdStr )
+            if handle != '':
+                cmdStr = "feature:uninstall " + str( featureStr )
+                self.sendline( cmdStr )
+                # TODO: Check for possible error responses from karaf
+            else:
+                main.log.info( "Feature needs to be installed before " +
+                               "uninstalling it" )
             return main.TRUE
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -490,11 +524,36 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
+    def deviceRemove( self, deviceId ):
+        """
+        Removes particular device from storage
+
+        TODO: refactor this function
+        """
+        try:
+            cmdStr = "device-remove "+str(deviceId)
+            handle = self.sendline( cmdStr )
+            return main.TRUE
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+        
+
+
     def devices( self, jsonFormat=True ):
         """
         Lists all infrastructure devices or switches
@@ -533,7 +592,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -557,7 +616,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -600,7 +659,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -623,7 +682,7 @@
                 escape sequences. In json.loads( somestring ), this somestring
                 variable is actually repr( somestring ) and json.loads would
                 fail with the escape sequence. So we take off that escape
-                sequence using the following commads:
+                sequence using the following commands:
 
                 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
                 handle1 = ansiEscape.sub( '', handle )
@@ -644,7 +703,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -690,7 +749,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -707,7 +766,6 @@
         None if no match
         """
         try:
-            import json
             if deviceId is None:
                 return None
             else:
@@ -727,7 +785,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -739,7 +797,6 @@
                  main.FALSE any device has no master
         """
         try:
-            import json
             rawRoles = self.roles()
             rolesJson = json.loads( rawRoles )
             # search json for the device with id then return the device
@@ -758,7 +815,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -786,7 +843,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -829,7 +886,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -838,12 +895,11 @@
         """
         Return the first host from the hosts api whose 'id' contains 'mac'
 
-        Note: mac must be a colon seperated mac address, but could be a
+        Note: mac must be a colon separated mac address, but could be a
               partial mac address
 
         Return None if there is no match
         """
-        import json
         try:
             if mac is None:
                 return None
@@ -867,7 +923,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -909,7 +965,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -920,8 +976,10 @@
             * hostIdOne: ONOS host id for host1
             * hostIdTwo: ONOS host id for host2
         Description:
-            Adds a host-to-host intent ( bidrectional ) by
+            Adds a host-to-host intent ( bidirectional ) by
             specifying the two hosts.
+        Returns:
+            A string of the intent id or None on Error
         """
         try:
             cmdStr = "add-host-intent " + str( hostIdOne ) +\
@@ -929,22 +987,28 @@
             handle = self.sendline( cmdStr )
             if re.search( "Error", handle ):
                 main.log.error( "Error in adding Host intent" )
-                return handle
+                main.log.debug( "Response from ONOS was: " + repr( handle ) )
+                return None
             else:
                 main.log.info( "Host intent installed between " +
-                           str( hostIdOne ) + " and " + str( hostIdTwo ) )
-                return main.TRUE
-
+                               str( hostIdOne ) + " and " + str( hostIdTwo ) )
+                match = re.search('id=0x([\da-f]+),', handle)
+                if match:
+                    return match.group()[3:-1]
+                else:
+                    main.log.error( "Error, intent ID not found" )
+                    main.log.debug( "Response from ONOS was: " +
+                                    repr( handle ) )
+                    return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
-
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -956,6 +1020,10 @@
             * egressDevice: device id of egress device
         Optional:
             TODO: Still needs to be implemented via dev side
+        Description:
+            Adds an optical intent by specifying an ingress and egress device
+        Returns:
+            A string of the intent id or None on error
         """
         try:
             cmdStr = "add-optical-intent " + str( ingressDevice ) +\
@@ -963,9 +1031,18 @@
             handle = self.sendline( cmdStr )
             # If error, return error message
             if re.search( "Error", handle ):
-                return handle
+                main.log.error( "Error in adding Optical intent" )
+                return None
             else:
-                return main.TRUE
+                main.log.info( "Optical intent installed between " +
+                               str( ingressDevice ) + " and " +
+                               str( egressDevice ) )
+                match = re.search('id=0x([\da-f]+),', handle)
+                if match:
+                    return match.group()[3:-1]
+                else:
+                    main.log.error( "Error, intent ID not found" )
+                    return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -974,7 +1051,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -1014,14 +1091,14 @@
         Description:
             Adds a point-to-point intent ( uni-directional ) by
             specifying device id's and optional fields
+        Returns:
+            A string of the intent id or None on error
 
         NOTE: This function may change depending on the
               options developers provide for point-to-point
               intent via cli
         """
         try:
-            cmd = ""
-
             # If there are no optional arguments
             if not ethType and not ethSrc and not ethDst\
                     and not bandwidth and not lambdaAlloc \
@@ -1059,10 +1136,11 @@
                 cmd += " " + str( ingressDevice )
             else:
                 if not portIngress:
-                    main.log.error( "You must specify " +
-                                    "the ingress port" )
+                    main.log.error( "You must specify the ingress port" )
                     # TODO: perhaps more meaningful return
-                    return main.FALSE
+                    #       Would it make sense to throw an exception and exit
+                    #       the test?
+                    return None
 
                 cmd += " " + \
                     str( ingressDevice ) + "/" +\
@@ -1072,20 +1150,29 @@
                 cmd += " " + str( egressDevice )
             else:
                 if not portEgress:
-                    main.log.error( "You must specify " +
-                                    "the egress port" )
-                    return main.FALSE
+                    main.log.error( "You must specify the egress port" )
+                    return None
 
                 cmd += " " +\
                     str( egressDevice ) + "/" +\
                     str( portEgress )
 
             handle = self.sendline( cmd )
+            # If error, return error message
             if re.search( "Error", handle ):
                 main.log.error( "Error in adding point-to-point intent" )
-                return main.FALSE
+                return None
             else:
-                return main.TRUE
+                # TODO: print out all the options in this message?
+                main.log.info( "Point-to-point intent installed between " +
+                               str( ingressDevice ) + " and " +
+                               str( egressDevice ) )
+                match = re.search('id=0x([\da-f]+),', handle)
+                if match:
+                    return match.group()[3:-1]
+                else:
+                    main.log.error( "Error, intent ID not found" )
+                    return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -1094,17 +1181,16 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
     def addMultipointToSinglepointIntent(
             self,
-            ingressDevice1,
-            ingressDevice2,
+            ingressDeviceList,
             egressDevice,
-            portIngress="",
+            portIngressList=None,
             portEgress="",
             ethType="",
             ethSrc="",
@@ -1120,12 +1206,13 @@
             setEthDst="" ):
         """
         Note:
-            This function assumes that there would be 2 ingress devices and
-            one egress device. For more number of ingress devices, this
-            function needs to be modified
+            This function assumes the format of all ingress devices
+            is same. That is, all ingress devices include port nos 
+            with a "/" or all ingress devices could specify device 
+            ids and port nos seperately.
         Required:
-            * ingressDevice1: device id of ingress device1
-            * ingressDevice2: device id of ingress device2
+            * ingressDeviceList: List of device ids of ingress device 
+                ( Atleast 2 ingress devices required in the list )
             * egressDevice: device id of egress device
         Optional:
             * ethType: specify ethType
@@ -1144,14 +1231,14 @@
         Description:
             Adds a multipoint-to-singlepoint intent ( uni-directional ) by
             specifying device id's and optional fields
+        Returns:
+            A string of the intent id or None on error
 
         NOTE: This function may change depending on the
-              options developers provide for multipointpoint-to-singlepoint
+              options developers provide for multipoint-to-singlepoint
               intent via cli
         """
         try:
-            cmd = ""
-
             # If there are no optional arguments
             if not ethType and not ethSrc and not ethDst\
                     and not bandwidth and not lambdaAlloc\
@@ -1190,31 +1277,22 @@
 
             # Check whether the user appended the port
             # or provided it as an input
-            if "/" in ingressDevice1:
-                cmd += " " + str( ingressDevice1 )
+
+            if portIngressList is None:
+                for ingressDevice in ingressDeviceList:
+                    if "/" in ingressDevice:
+                        cmd += " " + str( ingressDevice )
+                    else:
+                        main.log.error( "You must specify " +
+                                    "the ingress port" )
+                        # TODO: perhaps more meaningful return
+                        return main.FALSE
             else:
-                if not portIngress1:
-                    main.log.error( "You must specify " +
-                                    "the ingress port1" )
-                    # TODO: perhaps more meaningful return
-                    return main.FALSE
-
-                cmd += " " + \
-                    str( ingressDevice1 ) + "/" +\
-                    str( portIngress1 ) + " "
-
-            if "/" in ingressDevice2:
-                cmd += " " + str( ingressDevice2 )
-            else:
-                if not portIngress2:
-                    main.log.error( "You must specify " +
-                                    "the ingress port2" )
-                    # TODO: perhaps more meaningful return
-                    return main.FALSE
-
-                cmd += " " + \
-                    str( ingressDevice2 ) + "/" +\
-                    str( portIngress2 ) + " "
+                if len( ingressDeviceList ) == len( portIngressList ):
+                    for ingressDevice,portIngress in zip( ingressDeviceList,portIngressList ):
+                        cmd += " " + \
+                            str( ingressDevice ) + "/" +\
+                            str( portIngress ) + " "
 
             if "/" in egressDevice:
                 cmd += " " + str( egressDevice )
@@ -1227,13 +1305,25 @@
                 cmd += " " +\
                     str( egressDevice ) + "/" +\
                     str( portEgress )
+
             print "cmd= ", cmd
             handle = self.sendline( cmd )
+            # If error, return error message
             if re.search( "Error", handle ):
-                main.log.error( "Error in adding point-to-point intent" )
-                return self.handle
+                main.log.error( "Error in adding multipoint-to-singlepoint " +
+                                "intent" )
+                return None
             else:
-                return main.TRUE
+                # TODO: print out all the options in this message?
+                main.log.info( "Multipoint-to-singlepoint intent installed" +
+                               " failed " )
+                return None
+                #match = re.search('id=0x([\da-f]+),', handle)
+                #if match:
+                    #return match.group()[3:-1]
+                #else:
+                    #main.log.error( "Error, intent ID not found" )
+                    #return None
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -1242,21 +1332,31 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
-    def removeIntent( self, intentId ):
+    def removeIntent( self, intentId, app='org.onosproject.cli',
+                      purge=False, sync=False ):
         """
-        Remove intent for specified intent id
+        Remove intent for specified application id and intent id
+        Optional args:-
+        -s or --sync: Waits for the removal before returning
+        -p or --purge: Purge the intent from the store after removal
 
         Returns:
             main.False on error and
             cli output otherwise
         """
         try:
-            cmdStr = "remove-intent org.onosproject.cli " + str( intentId )
+            cmdStr = "remove-intent "
+            if purge:
+                cmdStr += " -p"
+            if sync:
+                cmdStr += " -s"
+
+            cmdStr += " " + app + " " + str( intentId )
             handle = self.sendline( cmdStr )
             if re.search( "Error", handle ):
                 main.log.error( "Error in removing intent" )
@@ -1272,7 +1372,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -1304,7 +1404,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -1334,7 +1434,66 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def getIntentState(self, intentsId, intentsJson=None):
+        """
+            Check intent state.
+            Accepts a single intent ID (string type) or a list of intent IDs.
+            Returns the state(string type) of the id if a single intent ID is
+            accepted.
+            Returns a dictionary with intent IDs as the key and its
+            corresponding states as the values
+            Parameters:
+            intentId: intent ID (string type)
+            intentsJson: parsed json object from the onos:intents api
+            Returns:
+            state = An intent's state- INSTALL,WITHDRAWN etc.
+            stateDict = Dictionary of intent's state. intent ID as the keys and
+            state as the values.
+        """
+        try:
+            state = "State is Undefined"
+            if not intentsJson:
+                intentsJsonTemp = json.loads( self.intents() )
+            else:
+                intentsJsonTemp = json.loads( intentsJson )
+            if isinstance( intentsId, types.StringType ):
+                for intent in intentsJsonTemp:
+                    if intentsId == intent['id']:
+                        state = intent['state']
+                        return state
+                main.log.info( "Cannot find intent ID" + str( intentsId ) +
+                               " on the list" )
+                return state
+            elif isinstance( intentsId, types.ListType ):
+                dictList = []
+                for ID in intentsId:
+                    stateDict = {}
+                    for intents in intentsJsonTemp:
+                        if ID == intents['id']:
+                            stateDict['state'] = intents['state']
+                            stateDict['id'] = ID
+                            dictList.append( stateDict )
+                            break
+                if len( intentsId ) != len( dictList ):
+                    main.log.info( "Cannot find some of the intent ID state" )
+                return dictList
+            else:
+                main.log.info("Invalid intents ID entry")
+                return None
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -1355,7 +1514,7 @@
             else:
                 cmdStr = "flows"
                 handle = self.sendline( cmdStr )
-            if re.search( "Error\sexecuting\scommand:", handle ):
+            if re.search( "Error:", handle ):
                 main.log.error( self.name + ".flows() response: " +
                                 str( handle ) )
             return handle
@@ -1367,13 +1526,13 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
     def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
-                          numMult="", appId="", report=True ):
+                         numMult="", appId="", report=True ):
         """
         Description:
             Push a number of intents in a batch format to
@@ -1426,7 +1585,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -1456,7 +1615,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -1477,7 +1636,11 @@
             else:
                 cmdStr = "topology-events-metrics"
                 handle = self.sendline( cmdStr )
-            return handle
+            if handle:
+                return handle
+            else:
+                # Return empty json 
+                return '{}'
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -1486,7 +1649,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -1505,29 +1668,16 @@
         """
         try:
             # Obtain output of intents function
-            intentsStr = self.intents()
-            allIntentList = []
+            intentsStr = self.intents(jsonFormat=False)
             intentIdList = []
 
             # Parse the intents output for ID's
             intentsList = [ s.strip() for s in intentsStr.splitlines() ]
             for intents in intentsList:
-                if "onos>" in intents:
-                    continue
-                elif "intents" in intents:
-                    continue
-                else:
-                    lineList = intents.split( " " )
-                    allIntentList.append( lineList[ 0 ] )
-
-            allIntentList = allIntentList[ 1:-2 ]
-
-            for intents in allIntentList:
-                if not intents:
-                    continue
-                else:
-                    intentIdList.append( intents )
-
+                match = re.search('id=0x([\da-f]+),', intents)
+                if match:
+                    tmpId = match.group()[3:-1]
+                    intentIdList.append( tmpId )
             return intentIdList
 
         except TypeError:
@@ -1538,7 +1688,27 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def FlowAddedCount( self, deviceId ):
+        """
+        Determine the number of flow rules for the given device id that are
+        in the added state
+        """
+        try:
+            cmdStr = "flows any " + str( deviceId ) + " | " +\
+                     "grep 'state=ADDED' | wc -l"
+            handle = self.sendline( cmdStr )
+            return handle
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -1584,7 +1754,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -1598,22 +1768,15 @@
             list of node id's
         """
         try:
-            nodesStr = self.nodes()
+            nodesStr = self.nodes( jsonFormat=True )
             idList = []
-
+            # Sample nodesStr output
+            # id=local, address=127.0.0.1:9876, state=ACTIVE *
             if not nodesStr:
                 main.log.info( "There are no nodes to get id from" )
                 return idList
-
-            # Sample nodesStr output
-            # id=local, address=127.0.0.1:9876, state=ACTIVE *
-
-            # Split the string into list by comma
-            nodesList = nodesStr.split( "," )
-            tempList = [ node for node in nodesList if "id=" in node ]
-            for arg in tempList:
-                idList.append( arg.split( "id=" )[ 1 ] )
-
+            nodesJson = json.loads( nodesStr )
+            idList = [ node.get('id') for node in nodesJson ]
             return idList
 
         except TypeError:
@@ -1624,7 +1787,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -1634,7 +1797,6 @@
         Return the first device from the devices api whose 'id' contains 'dpid'
         Return None if there is no match
         """
-        import json
         try:
             if dpid is None:
                 return None
@@ -1656,28 +1818,28 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
     def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
         """
-        Checks the number of swithes & links that ONOS sees against the
+        Checks the number of switches & links that ONOS sees against the
         supplied values. By default this will report to main.log, but the
-        log level can be specifid.
+        log level can be specified.
 
         Params: ip = ip used for the onos cli
                 numoswitch = expected number of switches
-                numlink = expected number of links
+                numolink = expected number of links
                 logLevel = level to log to. Currently accepts
                 'info', 'warn' and 'report'
 
 
         logLevel can
 
-        Returns: main.TRUE if the number of switchs and links are correct,
-                 main.FALSE if the numer of switches and links is incorrect,
+        Returns: main.TRUE if the number of switches and links are correct,
+                 main.FALSE if the number of switches and links is incorrect,
                  and main.ERROR otherwise
         """
         try:
@@ -1688,20 +1850,19 @@
             # Is the number of switches is what we expected
             devices = topology.get( 'devices', False )
             links = topology.get( 'links', False )
-            if devices == False or links == False:
+            if devices is False or links is False:
                 return main.ERROR
             switchCheck = ( int( devices ) == int( numoswitch ) )
             # Is the number of links is what we expected
             linkCheck = ( int( links ) == int( numolink ) )
             if ( switchCheck and linkCheck ):
                 # We expected the correct numbers
-                output = output + "The number of links and switches match "\
-                    + "what was expected"
+                output += "The number of links and switches match " +\
+                          "what was expected"
                 result = main.TRUE
             else:
-                output = output + \
-                    "The number of links and switches does not matc\
-                    h what was expected"
+                output += "The number of links and switches does not match " +\
+                          "what was expected"
                 result = main.FALSE
             output = output + "\n ONOS sees %i devices (%i expected) \
                     and %i links (%i expected)" % (
@@ -1722,7 +1883,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -1765,7 +1926,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -1808,7 +1969,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -1860,7 +2021,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -1901,7 +2062,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -1942,7 +2103,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -1968,7 +2129,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -1994,7 +2155,7 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
@@ -2019,19 +2180,61 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
+        except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
-    def testExceptions( self, obj ):
+    def intentSummary( self ):
         """
-        Test exception logging
+        Returns a dictionary containing the current intent states and the count
         """
-        # FIXME: Remove this before you commit
-
         try:
-            return obj[ 'dedf' ]
+            intents = self.intents( )
+            intentStates = []
+            for intent in json.loads( intents ):
+                intentStates.append( intent.get( 'state', None ) )
+            out = [ (i, intentStates.count( i ) ) for i in set( intentStates ) ]
+            main.log.info( dict( out ) )
+            return dict( out )
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def leaders( self, jsonFormat=True ):
+        """
+        Returns the output of the leaders command.
+        Optional argument:
+            * jsonFormat - boolean indicating if you want output in json
+        """
+        # FIXME: add json output
+        # Sample JSON
+        # {
+        #     "electedTime": "13m ago",
+        #     "epoch": 4,
+        #     "leader": "10.128.30.17",
+        #     "topic": "intent-partition-3"
+        #  },
+        try:
+            if jsonFormat:
+                cmdStr = "onos:leaders -j"
+                output = self.sendline( cmdStr )
+                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
+                cleanedOutput = ansiEscape.sub( '', output )
+                return cleanedOutput
+            else:
+                cmdStr = "onos:leaders"
+                output = self.sendline( cmdStr )
+                return output
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
             return None
@@ -2044,3 +2247,71 @@
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
+
+    def pendingMap( self, jsonFormat=True ):
+        """
+        Returns the output of the intent Pending map.
+        """
+        try:
+            if jsonFormat:
+                cmdStr = "onos:intents -p -j"
+                output = self.sendline( cmdStr )
+                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
+                cleanedOutput = ansiEscape.sub( '', output )
+                return cleanedOutput
+            else:
+                cmdStr = "onos:intents -p"
+                output = self.sendline( cmdStr )
+                return output
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def partitions( self, jsonFormat=True ):
+        """
+        Returns the output of the raft partitions command for ONOS.
+        """
+        # Sample JSON
+        # {
+        #     "leader": "tcp://10.128.30.11:7238",
+        #     "members": [
+        #         "tcp://10.128.30.11:7238",
+        #         "tcp://10.128.30.17:7238",
+        #         "tcp://10.128.30.13:7238",
+        #     ],
+        #     "name": "p1",
+        #     "term": 3
+        # },
+        try:
+            if jsonFormat:
+                cmdStr = "onos:partitions -j"
+                output = self.sendline( cmdStr )
+                ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
+                cleanedOutput = ansiEscape.sub( '', output )
+                return cleanedOutput
+            else:
+                cmdStr = "onos:partitions"
+                output = self.sendline( cmdStr )
+                return output
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
diff --git a/TestON/drivers/common/cli/onosdriver.py b/TestON/drivers/common/cli/onosdriver.py
index 328ac0e..14562e7 100644
--- a/TestON/drivers/common/cli/onosdriver.py
+++ b/TestON/drivers/common/cli/onosdriver.py
@@ -19,7 +19,6 @@
 import sys
 import time
 import pexpect
-import traceback
 import os.path
 sys.path.append( "../" )
 from drivers.common.clidriver import CLI
@@ -31,6 +30,9 @@
         """
         Initialize client
         """
+        self.name = None
+        self.home = None
+        self.handle = None
         super( CLI, self ).__init__()
 
     def connect( self, **connectargs ):
@@ -40,13 +42,13 @@
         try:
             for key in connectargs:
                 vars( self )[ key ] = connectargs[ key ]
-            self.home = "~/ONOS"
+            self.home = "~/onos"
             for key in self.options:
                 if key == "home":
                     self.home = self.options[ 'home' ]
                     break
             if self.home is None or self.home == "":
-                self.home = "~/ONOS"
+                self.home = "~/onos"
 
             self.name = self.options[ 'name' ]
             self.handle = super( OnosDriver, self ).connect(
@@ -68,10 +70,8 @@
             main.log.error( self.name + ":     " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + ":" * 30 )
-            main.log.error( traceback.print_exc() )
-            main.log.info( ":" * 30 )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -81,15 +81,19 @@
         """
         response = main.TRUE
         try:
-            self.handle.sendline( "" )
-            self.handle.expect( "\$" )
-            self.handle.sendline( "exit" )
-            self.handle.expect( "closed" )
+            if self.handle:
+                self.handle.sendline( "" )
+                self.handle.expect( "\$" )
+                self.handle.sendline( "exit" )
+                self.handle.expect( "closed" )
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":     " + self.handle.before )
-        except:
-            main.log.error( self.name + ": Connection failed to the host" )
+        except ValueError:
+            main.log.exception( "Exception in discconect of " + self.name )
+            response = main.TRUE
+        except Exception:
+            main.log.exception( self.name + ": Connection failed to the host" )
             response = main.FALSE
         return response
 
@@ -113,8 +117,8 @@
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
-        except:
-            main.log.error( "Failed to package ONOS" )
+        except Exception:
+            main.log.exception( "Failed to package ONOS" )
             main.cleanup()
             main.exit()
 
@@ -143,8 +147,8 @@
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
-        except:
-            main.log.error( "Failed to build ONOS" )
+        except Exception:
+            main.log.exception( "Failed to build ONOS" )
             main.cleanup()
             main.exit()
 
@@ -170,9 +174,10 @@
             while True:
                 i = self.handle.expect( [
                     'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
-                        'Runtime\sEnvironment\sto\scontinue',
+                    'Runtime\sEnvironment\sto\scontinue',
                     'BUILD\sFAILURE',
                     'BUILD\sSUCCESS',
+                    'onos\$',  #TODO: fix this to be more generic?
                     'ONOS\$',
                     pexpect.TIMEOUT ], timeout=600 )
                 if i == 0:
@@ -188,7 +193,7 @@
                     main.exit()
                 elif i == 2:
                     main.log.info( self.name + ": Build success!" )
-                elif i == 3:
+                elif i == 3 or i == 4:
                     main.log.info( self.name + ": Build complete" )
                     # Print the build time
                     for line in self.handle.before.splitlines():
@@ -197,7 +202,7 @@
                     self.handle.sendline( "" )
                     self.handle.expect( "\$", timeout=60 )
                     return main.TRUE
-                elif i == 4:
+                elif i == 5:
                     main.log.error(
                         self.name +
                         ": mvn clean install TIMEOUT!" )
@@ -206,7 +211,7 @@
                     main.exit()
                 else:
                     main.log.error( self.name + ": unexpected response from " +
-                            "mvn clean install" )
+                                    "mvn clean install" )
                     # return main.FALSE
                     main.cleanup()
                     main.exit()
@@ -215,17 +220,19 @@
             main.log.error( self.name + ":     " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + ":" * 60 )
-            main.log.error( traceback.print_exc() )
-            main.log.info( ":" * 60 )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
-    def gitPull( self, comp1="" ):
+    def gitPull( self, comp1="", fastForward=True ):
         """
         Assumes that "git pull" works without login
 
+        If the fastForward boolean is set to true, only git pulls that can
+        be fast forwarded will be performed. IE if you have not local commits
+        in your branch.
+
         This function will perform a git pull on the ONOS instance.
         If used as gitPull( "NODE" ) it will do git pull + NODE. This is
         for the purpose of pulling from other nodes if necessary.
@@ -241,11 +248,12 @@
             # self.stop()
             self.handle.sendline( "cd " + self.home )
             self.handle.expect( self.home + "\$" )
-            if comp1 == "":
-                self.handle.sendline( "git pull" )
-            else:
-                self.handle.sendline( "git pull " + comp1 )
-
+            cmd = "git pull"
+            if comp1 != "":
+                cmd += ' ' +  comp1
+            if fastForward:
+                cmd += ' ' + " --ff-only"
+            self.handle.sendline( cmd )
             i = self.handle.expect(
                 [
                     'fatal',
@@ -256,6 +264,9 @@
                     'You\sare\snot\scurrently\son\sa\sbranch',
                     'You asked me to pull without telling me which branch you',
                     'Pull is not possible because you have unmerged files',
+                    'Please enter a commit message to explain why this merge',
+                    'Found a swap file by the name',
+                    'Please, commit your changes before you can merge.',
                     pexpect.TIMEOUT ],
                 timeout=300 )
             # debug
@@ -263,7 +274,11 @@
             # "git pull response: " +
             # str( self.handle.before ) + str( self.handle.after ) )
             if i == 0:
-                main.log.error( self.name + ": Git pull had some issue..." )
+                main.log.error( self.name + ": Git pull had some issue" )
+                output = self.handle.after
+                self.handle.expect( '\$' )
+                output += self.handle.before
+                main.log.warn( output )
                 return main.ERROR
             elif i == 1:
                 main.log.error(
@@ -305,6 +320,29 @@
                     "you have unmerged files." )
                 return main.ERROR
             elif i == 8:
+                # NOTE: abandoning test since we can't reliably handle this
+                #       there could be different default text editors and we
+                #       also don't know if we actually want to make the commit
+                main.log.error( "Git pull resulted in a merge commit message" +
+                                ". Exiting test!" )
+                main.cleanup()
+                main.exit()
+            elif i == 9:  # Merge commit message but swap file exists
+                main.log.error( "Git pull resulted in a merge commit message" +
+                                " but a swap file exists." )
+                try:
+                    self.handle.send( 'A' )  # Abort
+                    self.handle.expect( "\$" )
+                    return main.ERROR
+                except Exception:
+                    main.log.exception( "Couldn't exit editor prompt!")
+                    main.cleanup()
+                    main.exit()
+            elif i == 10:  # In the middle of a merge commit
+                main.log.error( "Git branch is in the middle of a merge. " )
+                main.log.warn( self.handle.before + self.handle.after )
+                return main.ERROR
+            elif i == 11:
                 main.log.error( self.name + ": Git Pull - TIMEOUT" )
                 main.log.error(
                     self.name + " Response was: " + str(
@@ -320,10 +358,8 @@
             main.log.error( self.name + ":     " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + ":" * 60 )
-            main.log.error( traceback.print_exc() )
-            main.log.info( ":" * 80 )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -352,12 +388,12 @@
             self.handle.expect( cmd )
             i = self.handle.expect(
                 [ 'fatal',
-                  'Username\sfor\s(.*):\s',
-                  'Already\son\s\'',
-                  'Switched\sto\sbranch\s\'' + str( branch ),
+                  'Username for (.*): ',
+                  'Already on \'',
+                  'Switched to branch \'' + str( branch ),
                   pexpect.TIMEOUT,
                   'error: Your local changes to the following files' +
-                          'would be overwritten by checkout:',
+                  'would be overwritten by checkout:',
                   'error: you need to resolve your current index first',
                   "You are in 'detached HEAD' state.",
                   "HEAD is now at " ],
@@ -442,17 +478,15 @@
             main.log.error( self.name + ":     " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + ":" * 60 )
-            main.log.error( traceback.print_exc() )
-            main.log.info( ":" * 80 )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
     def getVersion( self, report=False ):
         """
         Writes the COMMIT number to the report to be parsed
-                by Jenkins data collecter.
+                by Jenkins data collector.
         """
         try:
             self.handle.sendline( "" )
@@ -492,15 +526,13 @@
             main.log.error( self.name + ":     " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + ":" * 60 )
-            main.log.error( traceback.print_exc() )
-            main.log.info( ":" * 80 )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
     def createCellFile( self, benchIp, fileName, mnIpAddrs,
-                         extraFeatureString, *onosIpAddrs ):
+                        extraFeatureString, *onosIpAddrs ):
         """
         Creates a cell file based on arguments
         Required:
@@ -576,10 +608,8 @@
             main.log.error( self.name + ":     " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + ":::::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( ":::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -597,12 +627,12 @@
                 # 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( "ONOS_CELL" )
+                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.sendline("")
+                self.handle.expect("\$")
                 handleMore = self.handle.before
 
                 main.log.info( "Cell call returned: " + handleBefore +
@@ -615,10 +645,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -645,15 +673,15 @@
                            handleAfter + handleMore )
 
             return main.TRUE
-        except pexpect.EOF:
-            main.log.error( self.name + ": EOF exception found" )
+        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.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -711,10 +739,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -766,10 +792,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -804,10 +828,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -823,6 +845,7 @@
                                   " stop" )
             i = self.handle.expect( [
                 "stop/waiting",
+                "Could not resolve hostname",
                 "Unknown\sinstance",
                 pexpect.TIMEOUT ], timeout=60 )
 
@@ -830,9 +853,12 @@
                 main.log.info( "ONOS service stopped" )
                 return main.TRUE
             elif i == 1:
-                main.log.info( "Unknown ONOS instance specified: " +
+                main.log.info( "onosStop() Unknown ONOS instance specified: " +
                                str( nodeIp ) )
                 return main.FALSE
+            elif i == 2:
+                main.log.warn( "ONOS wasn't running" )
+                return main.TRUE
             else:
                 main.log.error( "ONOS service failed to stop" )
                 return main.FALSE
@@ -842,10 +868,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -871,10 +895,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -904,10 +926,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -942,7 +962,7 @@
                     " not configured" )
                 return main.FALSE
             else:
-                main.log.info( "ONOS instasnce was not killed" )
+                main.log.info( "ONOS instance was not killed" )
                 return main.FALSE
 
         except pexpect.EOF:
@@ -950,10 +970,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -987,10 +1005,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -1026,25 +1042,23 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
-    def isup( self, node="" ):
+    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 )
+        level 100(ready for use)
 
         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=120 )
+            i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
             if i == 0:
                 main.log.info( self.name + ": " + node + " is up" )
                 return main.TRUE
@@ -1060,10 +1074,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -1124,58 +1136,31 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
     def getTopology( self, topologyOutput ):
         """
-        parses the onos:topology output
-        Returns: a topology dict populated by the key values found in
-                 the cli command.
+        Definition:
+            Loads a json topology output
+        Return:
+            topology = current ONOS topology
         """
+        import json
         try:
-            # call the cli to get the topology summary
-            # cmdstr = "onos:topology"
-            # cliResult = self.onosCli( ip, cmdstr )
-            # print "cli_result = ", cliResult
-
-            # Parse the output
-            topology = {}
-            # for line in cliResult.split( "\n" ):
-            for line in topologyOutput.splitlines():
-                if not line.startswith( "time=" ):
-                    continue
-                # else
-                # print line
-                for var in line.split( "," ):
-                    # print "'"+var+"'"
-                    # print "'"+var.strip()+"'"
-                    key, value = var.strip().split( "=" )
-                    topology[ key ] = value
-            # print "topology = ", topology
-            # devices = topology.get( 'devices', False )
-            # print "devices = ", devices
-            # links = topology.get( 'links', False )
-            # print "links = ", links
-            # SCCs = topology.get( 'SCC(s)', False )
-            # print "SCCs = ", SCCs
-            # paths = topology.get( 'paths', False )
-            # print "paths = ", paths
-
+            # either onos:topology or 'topology' will work in CLI
+            topology = json.loads(topologyOutput)
+            print topology
             return topology
         except pexpect.EOF:
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -1186,21 +1171,21 @@
             numolink,
             logLevel="info" ):
         """
-        Checks the number of swithes & links that ONOS sees against the
+        Checks the number of switches & links that ONOS sees against the
         supplied values. By default this will report to main.log, but the
-        log level can be specifid.
+        log level can be specific.
 
         Params: ip = ip used for the onos cli
                 numoswitch = expected number of switches
-                numlink = expected number of links
+                numolink = expected number of links
                 logLevel = level to log to.
                 Currently accepts 'info', 'warn' and 'report'
 
 
         logLevel can
 
-        Returns: main.TRUE if the number of switchs and links are correct,
-                 main.FALSE if the numer of switches and links is incorrect,
+        Returns: main.TRUE if the number of switches and links are correct,
+                 main.FALSE if the number of switches and links is incorrect,
                  and main.ERROR otherwise
         """
         try:
@@ -1209,14 +1194,14 @@
                 return main.ERROR
             output = ""
             # Is the number of switches is what we expected
-            devices = topology.get( 'devices', False )
-            links = topology.get( 'links', False )
+            devices = topology.get( 'deviceCount', False )
+            links = topology.get( 'linkCount', False )
             if not devices or not links:
                 return main.ERROR
             switchCheck = ( int( devices ) == int( numoswitch ) )
             # Is the number of links is what we expected
             linkCheck = ( int( links ) == int( numolink ) )
-            if ( switchCheck and linkCheck ):
+            if switchCheck and linkCheck:
                 # We expected the correct numbers
                 output = output + "The number of links and switches match "\
                     + "what was expected"
@@ -1226,8 +1211,8 @@
                     "The number of links and switches does not match " + \
                     "what was expected"
                 result = main.FALSE
-            output = output + "\n ONOS sees %i devices" % int ( devices )
-            output = output + " (%i expected) " %  int( numoswitch )
+            output = output + "\n ONOS sees %i devices" % int( devices )
+            output = output + " (%i expected) " % int( numoswitch )
             output = output + "and %i links " % int( links )
             output = output + "(%i expected)" % int( numolink )
             if logLevel == "report":
@@ -1242,10 +1227,8 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
@@ -1258,31 +1241,41 @@
             * interface: interface to capture
             * dir: directory/filename to store pcap
         """
-        self.handle.sendline( "" )
-        self.handle.expect( "\$" )
+        try:
+            self.handle.sendline( "" )
+            self.handle.expect( "\$" )
 
-        self.handle.sendline( "tshark -i " + str( interface ) +
-                              " -t e -w " + str( dirFile ) + " &" )
-        self.handle.sendline( "\r" )
-        self.handle.expect( "Capturing on" )
-        self.handle.sendline( "\r" )
-        self.handle.expect( "\$" )
+            self.handle.sendline( "tshark -i " + str( interface ) +
+                                  " -t e -w " + str( dirFile ) + " &" )
+            self.handle.sendline( "\r" )
+            self.handle.expect( "Capturing on" )
+            self.handle.sendline( "\r" )
+            self.handle.expect( "\$" )
 
-        main.log.info( "Tshark started capturing files on " +
-                       str( interface ) + " and saving to directory: " +
-                       str( dirFile ) )
+            main.log.info( "Tshark started capturing files on " +
+                           str( interface ) + " and saving to directory: " +
+                           str( dirFile ) )
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def runOnosTopoCfg( self, instanceName, jsonFile ):
         """
          On ONOS bench, run this command:
-         ./~/ONOS/tools/test/bin/onos-topo-cfg $OC1 filename
+         {ONOS_HOME}/tools/test/bin/onos-topo-cfg $OC1 filename
          which starts the rest and copies
          the json file to the onos instance
         """
         try:
             self.handle.sendline( "" )
             self.handle.expect( "\$" )
-            self.handle.sendline( "cd ~/ONOS/tools/test/bin" )
+            self.handle.sendline( "cd " + self.home + "/tools/test/bin" )
             self.handle.expect( "/bin$" )
             cmd = "./onos-topo-cfg " + instanceName + " " + jsonFile
             print "cmd = ", cmd
@@ -1291,8 +1284,15 @@
             self.handle.sendline( "cd ~" )
             self.handle.expect( "\$" )
             return main.TRUE
-        except:
-            return main.FALSE
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def tsharkGrep( self, grep, directory, interface='eth0' ):
         """
@@ -1306,33 +1306,53 @@
             and stores the results to specified directory.
             The timestamp is hardcoded to be in epoch
         """
-        self.handle.sendline( "" )
-        self.handle.expect( "\$" )
-        self.handle.sendline( "" )
-        self.handle.sendline(
-            "tshark -i " +
-            str( interface ) +
-            " -t e | grep --line-buffered \"" +
-            str(grep) +
-            "\" >" +
-            directory +
-            " &" )
-        self.handle.sendline( "\r" )
-        self.handle.expect( "Capturing on" )
-        self.handle.sendline( "\r" )
-        self.handle.expect( "\$" )
+        try:
+            self.handle.sendline( "" )
+            self.handle.expect( "\$" )
+            self.handle.sendline( "" )
+            self.handle.sendline(
+                "tshark -i " +
+                str( interface ) +
+                " -t e | grep --line-buffered \"" +
+                str(grep) +
+                "\" >" +
+                directory +
+                " &" )
+            self.handle.sendline( "\r" )
+            self.handle.expect( "Capturing on" )
+            self.handle.sendline( "\r" )
+            self.handle.expect( "\$" )
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def tsharkStop( self ):
         """
         Removes wireshark files from /tmp and kills all tshark processes
         """
         # Remove all pcap from previous captures
-        self.execute( cmd="sudo rm /tmp/wireshark*" )
-        self.handle.sendline( "" )
-        self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\" |" +
-                              " grep -v grep | awk '{print $2}'`" )
-        self.handle.sendline( "" )
-        main.log.info( "Tshark stopped" )
+        try:
+            self.execute( cmd="sudo rm /tmp/wireshark*" )
+            self.handle.sendline( "" )
+            self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
+                                  " | grep -v grep | awk '{print $2}'`" )
+            self.handle.sendline( "" )
+            main.log.info( "Tshark stopped" )
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def ptpd( self, args ):
         """
@@ -1367,15 +1387,13 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
     def cpLogsToDir( self, logToCopy,
-                       destDir, copyFileName="" ):
+                     destDir, copyFileName="" ):
         """
         Copies logs to a desired directory.
         Current implementation of ONOS deletes its karaf
@@ -1407,13 +1425,9 @@
                 destDir += "/"
 
             if copyFileName:
-                self.handle.sendline(
-                    "cp " +
-                    str( logToCopy ) +
-                    " " +
-                    str( destDir ) +
-                    str( copyFileName ) +
-                    localtime )
+                self.handle.sendline( "cp " + str( logToCopy ) + " " +
+                                      str( destDir ) + str( copyFileName ) +
+                                      localtime )
                 self.handle.expect( "cp" )
                 self.handle.expect( "\$" )
             else:
@@ -1428,11 +1442,8 @@
             main.log.error( "Copying files failed" )
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
-        except:
-            main.log.error( "Copying files failed" )
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( "Copying files failed" )
 
     def checkLogs( self, onosIp ):
         """
@@ -1450,11 +1461,10 @@
             main.log.error( "Lost ssh connection" )
             main.log.error( self.name + ": EOF exception found" )
             main.log.error( self.name + ":    " + self.handle.before )
-        except:
-            main.log.error( "Some error in check_logs:" )
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
 
     def onosStatus( self, node="" ):
         """
@@ -1475,8 +1485,6 @@
                 return main.TRUE
             elif i == 1:
                 main.log.info( "ONOS is stopped" )
-                return main.FALSE
-            else:
                 main.log.error( "ONOS service failed to check the status" )
                 main.cleanup()
                 main.exit()
@@ -1485,16 +1493,14 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.info( self.name + " ::::::" )
-            main.log.error( traceback.print_exc() )
-            main.log.info( self.name + " ::::::" )
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
-    def setIpTables( self, ip, port='', action='add', packet_type='tcp',
-                     direction='INPUT', rule='DROP' ):
-        '''
+    def setIpTables( self, ip, port='', action='add', packet_type='',
+                     direction='INPUT', rule='DROP', states=True ):
+        """
         Description:
             add or remove iptables rule to DROP (default) packets from
             specific IP and PORT
@@ -1507,6 +1513,8 @@
         * optional packet type to block (default tcp)
         * optional iptables rule (default DROP)
         * optional direction to block (default 'INPUT')
+        * States boolean toggles adding all supported tcp states to the
+          firewall rule
         Returns:
             main.TRUE on success or
             main.FALSE if given invalid input or
@@ -1514,7 +1522,7 @@
         WARNING:
         * This function uses root privilege iptables command which may result
           in unwanted network errors. USE WITH CAUTION
-        '''
+        """
         import time
 
         # NOTE*********
@@ -1527,7 +1535,7 @@
         #       registered to the instance. If you are calling this function
         #       multiple times this sleep will prevent any errors.
         #       DO NOT REMOVE
-        time.sleep( 5 )
+        # time.sleep( 5 )
         try:
             # input validation
             action_type = action.lower()
@@ -1557,10 +1565,16 @@
             self.handle.expect( "\$" )
             cmd = "sudo iptables " + actionFlag + " " +\
                   direction +\
-                  " -p " + str( packet_type ) +\
                   " -s " + str( ip )
+                  # " -p " + str( packet_type ) +\
+            if packet_type:
+                cmd += " -p " + str( packet_type )
             if port:
                 cmd += " --dport " + str( port )
+            if states:
+                cmd += " -m state --state="
+                #FIXME- Allow user to configure which states to block
+                cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
             cmd += " -j " + str( rule )
 
             self.handle.sendline( cmd )
@@ -1585,16 +1599,16 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.exception( "Unknown error:")
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
     def detailed_status(self, log_filename):
-        '''
+        """
         This method is used by STS to check the status of the controller
         Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
-        '''
+        """
         import re
         try:
             self.handle.sendline( "" )
@@ -1619,7 +1633,7 @@
             #      return 'FROZEN'
             else:
                 main.log.warn( self.name +
-                               " WARNING: status recieved unknown response" )
+                               " WARNING: status received unknown response" )
                 main.log.warn( response )
                 return 'ERROR', "Unknown response: %s" % response
         except pexpect.TIMEOUT:
@@ -1631,8 +1645,178 @@
             main.log.error( self.name + ":    " + self.handle.before )
             main.cleanup()
             main.exit()
-        except:
-            main.log.exception( "Unknown error:")
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
 
+    def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
+        '''
+            Create/formats the LinkGraph.cfg file based on arguments 
+                -only creates a linear topology and connects islands 
+                -evenly distributes devices 
+                -must be called by ONOSbench
+
+                ONOSIpList - list of all of the node IPs to be used 
+                
+                deviceCount - number of switches to be assigned 
+        '''
+        main.log.step("Creating link graph configuration file." )
+        linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
+        tempFile = "/tmp/linkGraph.cfg"        
+
+        linkGraph = open(tempFile, 'w+')
+        linkGraph.write("# NullLinkProvider topology description (config file).\n")
+        linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
+        linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
+        
+        clusterCount = len(ONOSIpList)
+        
+        if type(deviceCount) is int or type(deviceCount) is str: 
+            deviceCount = int(deviceCount)
+            switchList = [0]*(clusterCount+1)
+            baselineSwitchCount = deviceCount/clusterCount
+        
+            for node in range(1, clusterCount + 1):
+                switchList[node] = baselineSwitchCount
+
+            for node in range(1, (deviceCount%clusterCount)+1):
+                switchList[node] += 1
+        
+        if type(deviceCount) is list:
+            main.log.info("Using provided device distribution")
+            switchList = [0]
+            for i in deviceCount:
+                switchList.append(int(i))
+
+        tempList = ['0']
+        tempList.extend(ONOSIpList)
+        ONOSIpList = tempList
+
+        myPort = 6
+        lastSwitch = 0
+        for node in range(1, clusterCount+1):
+            if switchList[node] == 0:
+                continue
+
+            linkGraph.write("graph " + ONOSIpList[node] + " {\n")
+            
+            if node > 1:
+                #connect to last device on previous node
+                line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n")     #ONOSIpList[node-1]  
+                linkGraph.write(line)            
+               
+            lastSwitch = 0 
+            for switch in range (0, switchList[node]-1):    
+                line = ""
+                line = ("\t" + str(switch) + ":" + str(myPort))
+                line += " -- "
+                line += (str(switch+1) + ":" + str(myPort-1) + "\n")
+                linkGraph.write(line)
+                lastSwitch = switch+1 
+            lastIp = ONOSIpList[node]
+                
+            #lastSwitch += 1
+            if node < (clusterCount): 
+                #connect to first device on the next node
+                line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")             
+                linkGraph.write(line)
+                
+            linkGraph.write("}\n")
+        linkGraph.close()
+
+        #SCP
+        os.system( "scp " + tempFile + " admin@" + benchIp + ":" + linkGraphPath)        
+        main.log.info("linkGraph.cfg creation complete")
+
+    def createNullDevProviderFile( self, benchIp, ONOSIpList, deviceCount, numPorts=10):
+        
+        '''
+            benchIp = Ip address of the test bench 
+            ONOSIpList = list of Ip addresses of nodes switches will be devided amongst 
+            deviceCount = number of switches to distribute 
+            numPorts = number of ports per device, when not specified in file it defaults to 10, optional arg
+        '''
+
+        main.log.step("Creating null device provider configuration file." )
+        nullDevicePath = self.home + "/tools/package/etc/org.onosproject.provider.nil.device.impl.NullDeviceProvider.cfg"
+        tempFile = "/tmp/org.onosproject.provider.nil.device.impl.NullDeviceProvider.cfg"
+        configFile = open(tempFile, 'w+')
+        clusterCount = len(ONOSIpList)
+
+        if type(deviceCount) is int or type(deviceCount) is str:
+            main.log.info("Creating device distribution")
+            deviceCount = int(deviceCount)
+            switchList = [0]*(clusterCount+1)
+            baselineSwitchCount = deviceCount/clusterCount
+
+            for node in range(1, clusterCount + 1):
+                switchList[node] = baselineSwitchCount
+
+            for node in range(1, (deviceCount%clusterCount)+1):
+                switchList[node] += 1
+
+        if type(deviceCount) is list: 
+            main.log.info("Using provided device distribution") 
+            switchList = ['0']
+            switchList.extend(deviceCount)
+
+        ONOSIp = [0]
+        ONOSIp.extend(ONOSIpList)
+ 
+        devicesString  = "devConfigs = "
+        for node in range(1, len(ONOSIp)):
+            devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
+            if node < clusterCount:
+                devicesString += (",")
+
+        configFile.write(devicesString + "\n")
+        if numPorts == 10:
+            configFile.write("#numPorts = 10")
+        else: 
+            configFile.write("numPorts = " + str(numPorts))
+
+        configFile.close()        
+        os.system( "scp " + tempFile + " admin@" + benchIp + ":" + nullDevicePath)
+
+    def createNullLinkProviderFile( self, benchIp, neighborIpList=0, eventRate=0, onNode=False): 
+        '''
+                neighbor list is an optional list of neighbors to be written directly to the file
+                onNode - bool, if true, alternate file path will be used to scp, inteneded
+                        for use on cell
+        '''
+
+        main.log.step("Creating Null Link Provider config file")
+        nullLinkPath = self.home + "/tools/package/etc/org.onosproject.provider.nil.link.impl.NullLinkProvider.cfg"
+        if onNode == True: 
+            nullLinkPath = "/opt/onos/apache-karaf-3.0.2/etc/org.onosproject.provider.nil.link.impl.NullLinkProvider.cfg"
+        tempFile = "/tmp/org.onosproject.provider.nil.link.impl.NullLinkProvider.cfg"
+        configFile = open(tempFile, 'w+')
+    
+        eventRate = int(eventRate)
+
+        if eventRate == 0: 
+            configFile.write("#eventRate = \n")
+        else: 
+            configFile.write("eventRate = " + str(eventRate) + "\n") 
+
+        configFile.write("#cfgFile = /tmp/foo.cfg        #If enabled, points to the full path to the topology file.\n") 
+        
+        if neighborIpList != 0:
+            configFile.write("neighbors = ")
+            for n in range (0, len(neighborIpList)):
+                configFile.write(neighborIpList[n])
+                if n < (len(neighborIpList) - 1):
+                    configFile.write(",")            
+        else: 
+            configFile.write("#neighbors = ") 
+        
+        configFile.close()
+        if onNode == False:
+            os.system( "scp " + tempFile + " admin@" + benchIp + ":" + nullLinkPath)
+        if onNode == True:
+            os.system( "scp " + tempFile + " sdn@" + benchIp + ":" + nullLinkPath)
+        
+
+
+
diff --git a/TestON/drivers/common/cli/quaggaclidriver.py b/TestON/drivers/common/cli/quaggaclidriver.py
index c565ae0..bcd83f6 100644
--- a/TestON/drivers/common/cli/quaggaclidriver.py
+++ b/TestON/drivers/common/cli/quaggaclidriver.py
@@ -2,13 +2,7 @@
 
 import time
 import pexpect
-import struct
-import fcntl
-import os
 import sys
-import signal
-import sys
-import re
 import json
 sys.path.append( "../" )
 from drivers.common.clidriver import CLI
@@ -100,7 +94,7 @@
         try:
             self.handle.sendline( "" )
             self.handle.expect( "bgpd#" )
-        except:
+        except Exception:
             main.log.warn( "Probably not currently in enable mode!" )
             self.disconnect()
             return main.FALSE
@@ -111,7 +105,7 @@
             self.handle.sendline( routerAS )
             self.handle.expect( "config-router", timeout=5 )
             return main.TRUE
-        except:
+        except Exception:
             return main.FALSE
 
     def generatePrefixes( self, net, numRoutes ):
@@ -349,7 +343,7 @@
             self.handle.sendline( "" )
             # self.handle.expect( "config-router" )
             self.handle.expect( "config-router", timeout=5 )
-        except:
+        except Exception:
             main.log.warn( "Probably not in config-router mode!" )
             self.disconnect()
         main.log.info( "Start to add routes" )
@@ -376,7 +370,7 @@
             try:
                 self.handle.sendline( routeCmd )
                 self.handle.expect( "bgpd", timeout=5 )
-            except:
+            except Exception:
                 main.log.warn( "Failed to add route" )
                 self.disconnect()
             
@@ -396,7 +390,7 @@
             self.handle.sendline( "" )
             # self.handle.expect( "config-router" )
             self.handle.expect( "config-router", timeout=5 )
-        except:
+        except Exception:
             main.log.warn( "Probably not in config-router mode!" )
             self.disconnect()
         main.log.info( "Start to delete routes" )
@@ -406,7 +400,7 @@
             try:
                 self.handle.sendline( routeCmd )
                 self.handle.expect( "bgpd", timeout=5 )
-            except:
+            except Exception:
                 main.log.warn( "Failed to delete route" )
                 self.disconnect()
             # waitTimer = 1.00 / routeRate
@@ -451,7 +445,7 @@
         try:
             self.handle.sendline( "" )
             self.handle.expect( "config-router" )
-        except:
+        except Exception:
             main.log.warn( "Probably not in config-router mode!" )
             self.disconnect()
         main.log.info( "Adding Routes" )
@@ -472,7 +466,7 @@
                 try:
                     self.handle.sendline( routeCmd )
                     self.handle.expect( "bgpd" )
-                except:
+                except Exception:
                     main.log.warn( "failed to add route" )
                     self.disconnect()
                 waitTimer = 1.00 / routeRate
@@ -486,9 +480,9 @@
                 try:
                     self.handle.sendline( routeCmd )
                     self.handle.expect( "bgpd" )
-                except:
+                except Exception:
                     main.log.warn( "failed to add route" )
-                    self.disconnect
+                    self.disconnect()
                 waitTimer = 1.00 / routeRate
                 time.sleep( waitTimer )
                 routesAdded = routesAdded + 1
@@ -501,7 +495,7 @@
         try:
             self.handle.sendline( "" )
             self.handle.expect( "config-router" )
-        except:
+        except Exception:
             main.log.warn( "Probably not in config-router mode!" )
             self.disconnect()
         main.log.info( "Deleting Routes" )
@@ -522,7 +516,7 @@
                 try:
                     self.handle.sendline( routeCmd )
                     self.handle.expect( "bgpd" )
-                except:
+                except Exception:
                     main.log.warn( "Failed to delete route" )
                     self.disconnect()
                 waitTimer = 1.00 / routeRate
@@ -536,7 +530,7 @@
                 try:
                     self.handle.sendline( routeCmd )
                     self.handle.expect( "bgpd" )
-                except:
+                except Exception:
                     main.log.warn( "Failed to delete route" )
                     self.disconnect()
                 waitTimer = 1.00 / routeRate
@@ -652,7 +646,7 @@
         response = ''
         try:
             self.handle.close()
-        except:
+        except Exception:
             main.log.error( "Connection failed to the host" )
             response = main.FALSE
         return response
diff --git a/TestON/drivers/common/clidriver.py b/TestON/drivers/common/clidriver.py
index 6d7fb2a..44552ae 100644
--- a/TestON/drivers/common/clidriver.py
+++ b/TestON/drivers/common/clidriver.py
@@ -94,10 +94,17 @@
                 i = self.handle.expect(
                     [ ssh_newkey, 'password:', pexpect.EOF ] )
             if i == 1:
-                main.log.info(
-                    "ssh connection asked for password, gave password" )
-                self.handle.sendline( self.pwd )
-                self.handle.expect( '>|#|\$' )
+                if self.pwd:
+                    main.log.info(
+                        "ssh connection asked for password, gave password" )
+                    self.handle.sendline( self.pwd )
+                    self.handle.expect( '>|#|\$' )
+                else:
+                    # FIXME: TestON does not support a username having no
+                    #        password
+                    main.log.error( "Server asked for password, but none was "
+                                    "given in the .topo file" )
+                    main.exit()
             elif i == 2:
                 main.log.error( "Connection timeout" )
                 return main.FALSE
diff --git a/TestON/tests/HATestClusterRestart/HATestClusterRestart.py b/TestON/tests/HATestClusterRestart/HATestClusterRestart.py
index e9beb0c..0bd05ad 100644
--- a/TestON/tests/HATestClusterRestart/HATestClusterRestart.py
+++ b/TestON/tests/HATestClusterRestart/HATestClusterRestart.py
@@ -31,21 +31,25 @@
         CASE1 is to compile ONOS and push it to the test machines
 
         Startup sequence:
-        git pull
-        mvn clean install
-        onos-package
         cell <name>
         onos-verify-cell
         NOTE: temporary - onos-remove-raft-logs
+        onos-uninstall
+        start mininet
+        git pull
+        mvn clean install
+        onos-package
         onos-install -f
         onos-wait-for-start
+        start cli sessions
+        start tcpdump
         """
         main.log.report( "ONOS HA test: Restart all ONOS nodes - " +
                          "initialization" )
         main.case( "Setting up test environment" )
         # TODO: save all the timers and output them for plotting
 
-        # load some vairables from the params file
+        # load some variables from the params file
         PULLCODE = False
         if main.params[ 'Git' ] == 'True':
             PULLCODE = True
@@ -53,38 +57,34 @@
         cellName = main.params[ 'ENV' ][ 'cellName' ]
 
         # set global variables
-        global ONOS1Ip
         global ONOS1Port
-        global ONOS2Ip
         global ONOS2Port
-        global ONOS3Ip
         global ONOS3Port
-        global ONOS4Ip
         global ONOS4Port
-        global ONOS5Ip
         global ONOS5Port
-        global ONOS6Ip
         global ONOS6Port
-        global ONOS7Ip
         global ONOS7Port
         global numControllers
-
-        ONOS1Ip = main.params[ 'CTRL' ][ 'ip1' ]
-        ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
-        ONOS2Ip = main.params[ 'CTRL' ][ 'ip2' ]
-        ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
-        ONOS3Ip = main.params[ 'CTRL' ][ 'ip3' ]
-        ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
-        ONOS4Ip = main.params[ 'CTRL' ][ 'ip4' ]
-        ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
-        ONOS5Ip = main.params[ 'CTRL' ][ 'ip5' ]
-        ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
-        ONOS6Ip = main.params[ 'CTRL' ][ 'ip6' ]
-        ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
-        ONOS7Ip = main.params[ 'CTRL' ][ 'ip7' ]
-        ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
         numControllers = int( main.params[ 'num_controllers' ] )
 
+        # FIXME: just get controller port from params?
+        # TODO: do we really need all these?
+        ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
+        ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
+        ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
+        ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
+        ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
+        ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
+        ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
+
+        global CLIs
+        CLIs = []
+        global nodes
+        nodes = []
+        for i in range( 1, numControllers + 1 ):
+            CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
+            nodes.append( getattr( main, 'ONOS' + str( i ) ) )
+
         main.step( "Applying cell variable to environment" )
         cellResult = main.ONOSbench.setCell( cellName )
         verifyResult = main.ONOSbench.verifyCell()
@@ -92,14 +92,10 @@
         # FIXME:this is short term fix
         main.log.report( "Removing raft logs" )
         main.ONOSbench.onosRemoveRaftLogs()
+
         main.log.report( "Uninstalling ONOS" )
-        main.ONOSbench.onosUninstall( ONOS1Ip )
-        main.ONOSbench.onosUninstall( ONOS2Ip )
-        main.ONOSbench.onosUninstall( ONOS3Ip )
-        main.ONOSbench.onosUninstall( ONOS4Ip )
-        main.ONOSbench.onosUninstall( ONOS5Ip )
-        main.ONOSbench.onosUninstall( ONOS6Ip )
-        main.ONOSbench.onosUninstall( ONOS7Ip )
+        for node in nodes:
+            main.ONOSbench.onosUninstall( node.ip_address )
 
         cleanInstallResult = main.TRUE
         gitPullResult = main.TRUE
@@ -109,10 +105,11 @@
 
         main.step( "Compiling the latest version of ONOS" )
         if PULLCODE:
-            # TODO Configure branch in params
-            main.step( "Git checkout and pull master" )
+            main.step( "Git checkout and pull " + gitBranch )
             main.ONOSbench.gitCheckout( gitBranch )
             gitPullResult = main.ONOSbench.gitPull()
+            if gitPullResult == main.ERROR:
+                main.log.error( "Error pulling git branch" )
 
             main.step( "Using mvn clean & install" )
             cleanInstallResult = main.ONOSbench.cleanInstall()
@@ -125,77 +122,38 @@
         packageResult = main.ONOSbench.onosPackage()
 
         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 )
-        onos4InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                           node=ONOS4Ip )
-        onos5InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                           node=ONOS5Ip )
-        onos6InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                           node=ONOS6Ip )
-        onos7InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                           node=ONOS7Ip )
-        onosInstallResult = onos1InstallResult and onos2InstallResult\
-            and onos3InstallResult and onos4InstallResult\
-            and onos5InstallResult and onos6InstallResult\
-            and onos7InstallResult
+        onosInstallResult = main.TRUE
+        for node in nodes:
+            tmpResult = main.ONOSbench.onosInstall( options="-f",
+                                                    node=node.ip_address )
+            onosInstallResult = onosInstallResult and tmpResult
 
         main.step( "Checking if ONOS is up yet" )
-        # TODO check bundle:list?
         for i in range( 2 ):
-            onos1Isup = main.ONOSbench.isup( ONOS1Ip )
-            if not onos1Isup:
-                main.log.report( "ONOS1 didn't start!" )
-                main.ONOSbench.onosStop( ONOS1Ip )
-                main.ONOSbench.onosStart( ONOS1Ip )
-            onos2Isup = main.ONOSbench.isup( ONOS2Ip )
-            if not onos2Isup:
-                main.log.report( "ONOS2 didn't start!" )
-                main.ONOSbench.onosStop( ONOS2Ip )
-                main.ONOSbench.onosStart( ONOS2Ip )
-            onos3Isup = main.ONOSbench.isup( ONOS3Ip )
-            if not onos3Isup:
-                main.log.report( "ONOS3 didn't start!" )
-                main.ONOSbench.onosStop( ONOS3Ip )
-                main.ONOSbench.onosStart( ONOS3Ip )
-            onos4Isup = main.ONOSbench.isup( ONOS4Ip )
-            if not onos4Isup:
-                main.log.report( "ONOS4 didn't start!" )
-                main.ONOSbench.onosStop( ONOS4Ip )
-                main.ONOSbench.onosStart( ONOS4Ip )
-            onos5Isup = main.ONOSbench.isup( ONOS5Ip )
-            if not onos5Isup:
-                main.log.report( "ONOS5 didn't start!" )
-                main.ONOSbench.onosStop( ONOS5Ip )
-                main.ONOSbench.onosStart( ONOS5Ip )
-            onos6Isup = main.ONOSbench.isup( ONOS6Ip )
-            if not onos6Isup:
-                main.log.report( "ONOS6 didn't start!" )
-                main.ONOSbench.onosStop( ONOS6Ip )
-                main.ONOSbench.onosStart( ONOS6Ip )
-            onos7Isup = main.ONOSbench.isup( ONOS7Ip )
-            if not onos7Isup:
-                main.log.report( "ONOS7 didn't start!" )
-                main.ONOSbench.onosStop( ONOS7Ip )
-                main.ONOSbench.onosStart( ONOS7Ip )
-            onosIsupResult = onos1Isup and onos2Isup and onos3Isup\
-                and onos4Isup and onos5Isup and onos6Isup and onos7Isup
+            onosIsupResult = main.TRUE
+            for node in nodes:
+                started = main.ONOSbench.isup( node.ip_address )
+                if not started:
+                    main.log.report( node.name + " didn't start!" )
+                    main.ONOSbench.onosStop( node.ip_address )
+                    main.ONOSbench.onosStart( node.ip_address )
+                onosIsupResult = onosIsupResult and started
             if onosIsupResult == main.TRUE:
                 break
 
-        cliResult1 = main.ONOScli1.startOnosCli( ONOS1Ip )
-        cliResult2 = main.ONOScli2.startOnosCli( ONOS2Ip )
-        cliResult3 = main.ONOScli3.startOnosCli( ONOS3Ip )
-        cliResult4 = main.ONOScli4.startOnosCli( ONOS4Ip )
-        cliResult5 = main.ONOScli5.startOnosCli( ONOS5Ip )
-        cliResult6 = main.ONOScli6.startOnosCli( ONOS6Ip )
-        cliResult7 = main.ONOScli7.startOnosCli( ONOS7Ip )
-        cliResults = cliResult1 and cliResult2 and cliResult3 and\
-            cliResult4 and cliResult5 and cliResult6 and cliResult7
+        main.log.step( "Starting ONOS CLI sessions" )
+        cliResults = main.TRUE
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].startOnosCli,
+                             name="startOnosCli-" + str( i ),
+                             args=[nodes[i].ip_address] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            cliResults = cliResults and t.result
 
         main.step( "Start Packet Capture MN" )
         main.Mininet2.startTcpdump(
@@ -209,8 +167,8 @@
                         and onosIsupResult and cliResults )
 
         utilities.assert_equals( expect=main.TRUE, actual=case1Result,
-                                onpass="Test startup successful",
-                                onfail="Test startup NOT successful" )
+                                 onpass="Test startup successful",
+                                 onfail="Test startup NOT successful" )
 
         if case1Result == main.FALSE:
             main.cleanup()
@@ -221,40 +179,49 @@
         Assign mastership to controllers
         """
         import re
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
+        assert ONOS1Port, "ONOS1Port not defined"
+        assert ONOS2Port, "ONOS2Port not defined"
+        assert ONOS3Port, "ONOS3Port not defined"
+        assert ONOS4Port, "ONOS4Port not defined"
+        assert ONOS5Port, "ONOS5Port not defined"
+        assert ONOS6Port, "ONOS6Port not defined"
+        assert ONOS7Port, "ONOS7Port not defined"
 
         main.log.report( "Assigning switches to controllers" )
         main.case( "Assigning Controllers" )
         main.step( "Assign switches to controllers" )
 
+        # TODO: rewrite this function to take lists of ips and ports?
+        #       or list of tuples?
         for i in range( 1, 29 ):
             main.Mininet1.assignSwController(
                 sw=str( i ),
                 count=numControllers,
-                ip1=ONOS1Ip, port1=ONOS1Port,
-                ip2=ONOS2Ip, port2=ONOS2Port,
-                ip3=ONOS3Ip, port3=ONOS3Port,
-                ip4=ONOS4Ip, port4=ONOS4Port,
-                ip5=ONOS5Ip, port5=ONOS5Port,
-                ip6=ONOS6Ip, port6=ONOS6Port,
-                ip7=ONOS7Ip, port7=ONOS7Port )
+                ip1=nodes[ 0 ].ip_address, port1=ONOS1Port,
+                ip2=nodes[ 1 ].ip_address, port2=ONOS2Port,
+                ip3=nodes[ 2 ].ip_address, port3=ONOS3Port,
+                ip4=nodes[ 3 ].ip_address, port4=ONOS4Port,
+                ip5=nodes[ 4 ].ip_address, port5=ONOS5Port,
+                ip6=nodes[ 5 ].ip_address, port6=ONOS6Port,
+                ip7=nodes[ 6 ].ip_address, port7=ONOS7Port )
 
         mastershipCheck = main.TRUE
         for i in range( 1, 29 ):
             response = main.Mininet1.getSwController( "s" + str( i ) )
             try:
                 main.log.info( str( response ) )
-            except:
+            except Exception:
                 main.log.info( repr( response ) )
-            if re.search( "tcp:" + ONOS1Ip, response )\
-                    and re.search( "tcp:" + ONOS2Ip, response )\
-                    and re.search( "tcp:" + ONOS3Ip, response )\
-                    and re.search( "tcp:" + ONOS4Ip, response )\
-                    and re.search( "tcp:" + ONOS5Ip, response )\
-                    and re.search( "tcp:" + ONOS6Ip, response )\
-                    and re.search( "tcp:" + ONOS7Ip, response ):
-                mastershipCheck = mastershipCheck and main.TRUE
-            else:
-                mastershipCheck = main.FALSE
+            for node in nodes:
+                if re.search( "tcp:" + node.ip_address, response ):
+                    mastershipCheck = mastershipCheck and main.TRUE
+                else:
+                    mastershipCheck = main.FALSE
         if mastershipCheck == main.TRUE:
             main.log.report( "Switch mastership assigned correctly" )
         utilities.assert_equals(
@@ -262,122 +229,141 @@
             actual=mastershipCheck,
             onpass="Switch mastership assigned correctly",
             onfail="Switches not assigned correctly to controllers" )
-
+        #FIXME: turning off because of ONOS-1286
         # Manually assign mastership to the controller we want
         roleCall = main.TRUE
         roleCheck = main.TRUE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS1Ip )
-        # Check assignment
-        if ONOS1Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS1Ip )
-        # Check assignment
-        if ONOS1Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS2Ip )
-        # Check assignment
-        if ONOS2Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS2Ip )
-        # Check assignment
-        if ONOS2Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS3Ip )
-        # Check assignment
-        if ONOS3Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS3Ip )
-        # Check assignment
-        if ONOS3Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS4Ip )
-        # Check assignment
-        if ONOS4Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        for i in range( 8, 18 ):
-            dpid = '3' + str( i ).zfill( 3 )
-            deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+        try:
+            # Assign switch
+            ip = nodes[ 0 ].ip_address  # ONOS1
+            deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
+            assert deviceId, "No device id for s1 in ONOS"
             roleCall = roleCall and main.ONOScli1.deviceRole(
                 deviceId,
-                ONOS5Ip )
+                ip )
             # Check assignment
-            if ONOS5Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
                 roleCheck = roleCheck and main.TRUE
             else:
                 roleCheck = roleCheck and main.FALSE
 
-        deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS6Ip )
-        # Check assignment
-        if ONOS6Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        for i in range( 18, 28 ):
-            dpid = '6' + str( i ).zfill( 3 )
-            deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
+            assert deviceId, "No device id for s28 in ONOS"
             roleCall = roleCall and main.ONOScli1.deviceRole(
                 deviceId,
-                ONOS7Ip )
+                ip )
             # Check assignment
-            if ONOS7Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
                 roleCheck = roleCheck and main.TRUE
             else:
                 roleCheck = roleCheck and main.FALSE
 
+            ip = nodes[ 1 ].ip_address  # ONOS2
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
+            assert deviceId, "No device id for s2 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
+            assert deviceId, "No device id for s3 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            ip = nodes[ 2 ].ip_address  # ONOS3
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
+            assert deviceId, "No device id for s5 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
+            assert deviceId, "No device id for s6 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            ip = nodes[ 3 ].ip_address  # ONOS4
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
+            assert deviceId, "No device id for s4 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            ip = nodes[ 4 ].ip_address  # ONOS5
+            for i in range( 8, 18 ):
+                dpid = '3' + str( i ).zfill( 3 )
+                deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                assert deviceId, "No device id for s%i in ONOS" % i
+                roleCall = roleCall and main.ONOScli1.deviceRole(
+                    deviceId,
+                    ip )
+                # Check assignment
+                if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                    roleCheck = roleCheck and main.TRUE
+                else:
+                    roleCheck = roleCheck and main.FALSE
+
+            ip = nodes[ 5 ].ip_address  # ONOS6
+            deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
+            assert deviceId, "No device id for s7 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            ip = nodes[ 6 ].ip_address  # ONOS7
+            for i in range( 18, 28 ):
+                dpid = '6' + str( i ).zfill( 3 )
+                deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                assert deviceId, "No device id for s%i in ONOS" % i
+                roleCall = roleCall and main.ONOScli1.deviceRole(
+                    deviceId,
+                    ip )
+                # Check assignment
+                if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                    roleCheck = roleCheck and main.TRUE
+                else:
+                    roleCheck = roleCheck and main.FALSE
+        except ( AttributeError, AssertionError ):
+            main.log.exception( "Something is wrong with ONOS device view" )
+            main.log.info( main.ONOScli1.devices() )
         utilities.assert_equals(
             expect=main.TRUE,
             actual=roleCall,
@@ -403,6 +389,12 @@
         # FIXME: we must reinstall intents until we have a persistant
         # datastore!
         import time
+        import json
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         main.log.report( "Adding host intents" )
         main.case( "Adding host Intents" )
 
@@ -411,41 +403,55 @@
 
         # install onos-app-fwd
         main.log.info( "Install reactive forwarding app" )
-        main.ONOScli1.featureInstall( "onos-app-fwd" )
-        main.ONOScli2.featureInstall( "onos-app-fwd" )
-        main.ONOScli3.featureInstall( "onos-app-fwd" )
-        main.ONOScli4.featureInstall( "onos-app-fwd" )
-        main.ONOScli5.featureInstall( "onos-app-fwd" )
-        main.ONOScli6.featureInstall( "onos-app-fwd" )
-        main.ONOScli7.featureInstall( "onos-app-fwd" )
+        appResults = main.TRUE
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].featureInstall,
+                             name="featureInstall-" + str( i ),
+                             args=["onos-app-fwd"] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            appResults = appResults and t.result
 
         # REACTIVE FWD test
         pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall()
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=pingResult,
-            onpass="Reactive Pingall test passed",
-            onfail="Reactive Pingall failed, one or more ping pairs failed" )
-        time2 = time.time()
-        main.log.info( "Time for pingall: %2f seconds" % ( time2 - time1 ) )
+        for i in range(2):  # Retry if pingall fails first time
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall()
+            utilities.assert_equals(
+                expect=main.TRUE,
+                actual=pingResult,
+                onpass="Reactive Pingall test passed",
+                onfail="Reactive Pingall failed, one or more ping pairs failed" )
+            time2 = time.time()
+            main.log.info( "Time for pingall: %2f seconds" % ( time2 - time1 ) )
 
         # uninstall onos-app-fwd
         main.log.info( "Uninstall reactive forwarding app" )
-        main.ONOScli1.featureUninstall( "onos-app-fwd" )
-        main.ONOScli2.featureUninstall( "onos-app-fwd" )
-        main.ONOScli3.featureUninstall( "onos-app-fwd" )
-        main.ONOScli4.featureUninstall( "onos-app-fwd" )
-        main.ONOScli5.featureUninstall( "onos-app-fwd" )
-        main.ONOScli6.featureUninstall( "onos-app-fwd" )
-        main.ONOScli7.featureUninstall( "onos-app-fwd" )
-        # timeout for fwd flows
-        time.sleep( 10 )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].featureUninstall,
+                             name="featureUninstall-" + str( i ),
+                             args=["onos-app-fwd"] )
+            threads.append( t )
+            t.start()
 
-        main.step( "Add  host intents" )
+        for t in threads:
+            t.join()
+            appResults = appResults and t.result
+
+        # timeout for fwd flows
+        time.sleep( 11 )
+
+        main.step( "Add host intents" )
+        intentIds = []
         # TODO:  move the host numbers to params
+        #        Maybe look at all the paths we ping?
         intentAddResult = True
+        hostResult = main.TRUE
         for i in range( 8, 18 ):
             main.log.info( "Adding host intent between h" + str( i ) +
                            " and h" + str( i + 10 ) )
@@ -462,46 +468,233 @@
                 host1Id = host1Dict.get( 'id', None )
                 host2Id = host2Dict.get( 'id', None )
             if host1Id and host2Id:
-
-                tmpResult = main.ONOScli1.addHostIntent(
-                    host1Id,
-                    host2Id )
+                nodeNum = ( i % 7 )
+                tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
+                if tmpId:
+                    main.log.info( "Added intent with id: " + tmpId )
+                    intentIds.append( tmpId )
+                else:
+                    main.log.error( "addHostIntent returned: " +
+                                     repr( tmpId ) )
             else:
-                main.log.error( "Error, getHost() failed" )
-                main.log.warn( json.dumps( json.loads( main.ONOScli1.hosts() ),
+                main.log.error( "Error, getHost() failed for h" + str( i ) +
+                                " and/or h" + str( i + 10 ) )
+                hosts = CLIs[ 0 ].hosts()
+                main.log.warn( "Hosts output: " )
+                try:
+                    main.log.warn( json.dumps( json.loads( hosts ),
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                except ( ValueError, TypeError ):
+                    main.log.warn( repr( hosts ) )
+                hostResult = main.FALSE
+        onosIds = main.ONOScli1.getAllIntentsId()
+        main.log.info( "Submitted intents: " + str( intentIds ) )
+        main.log.info( "Intents in ONOS: " + str( onosIds ) )
+        for intent in intentIds:
+            if intent in onosIds:
+                pass  # intent submitted is in onos
+            else:
+                intentAddResult = False
+        # Print the intent states
+        intents = main.ONOScli1.intents()
+        intentStates = []
+        installedCheck = True
+        main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
+        count = 0
+        try:
+            for intent in json.loads( intents ):
+                state = intent.get( 'state', None )
+                if "INSTALLED" not in state:
+                    installedCheck = False
+                intentId = intent.get( 'id', None )
+                intentStates.append( ( intentId, state ) )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing intents" )
+        # add submitted intents not in the store
+        tmplist = [ i for i, s in intentStates ]
+        missingIntents = False
+        for i in intentIds:
+            if i not in tmplist:
+                intentStates.append( ( i, " - " ) )
+                missingIntents = True
+        intentStates.sort()
+        for i, s in intentStates:
+            count += 1
+            main.log.info( "%-6s%-15s%-15s" %
+                           ( str( count ), str( i ), str( s ) ) )
+        leaders = main.ONOScli1.leaders()
+        try:
+            if leaders:
+                parsedLeaders = json.loads( leaders )
+                main.log.warn( json.dumps( parsedLeaders,
                                            sort_keys=True,
                                            indent=4,
                                            separators=( ',', ': ' ) ) )
-                tmpResult = main.FALSE
-            intentAddResult = bool( pingResult and intentAddResult
-                                     and tmpResult )
-            # TODO Check that intents were added?
-        # Print the intent states
-        intents = main.ONOScli1.intents( )
-        intentStates = []
-        for intent in json.loads( intents ):  # Iter through intents of a node
-            intentStates.append( intent.get( 'state', None ) )
-        out = [ (i, intentStates.count( i ) ) for i in set( intentStates ) ]
-        main.log.info( dict( out ) )
+                # check for all intent partitions
+                # check for election
+                topics = []
+                for i in range( 14 ):
+                    topics.append( "intent-partition-" + str( i ) )
+                # FIXME: this should only be after we start the app
+                topics.append( "org.onosproject.election" )
+                main.log.debug( topics )
+                ONOStopics = [ j['topic'] for j in parsedLeaders ]
+                for topic in topics:
+                    if topic not in ONOStopics:
+                        main.log.error( "Error: " + topic +
+                                        " not in leaders" )
+            else:
+                main.log.error( "leaders() returned None" )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing leaders" )
+            main.log.error( repr( leaders ) )
+        partitions = main.ONOScli1.partitions()
+        try:
+            if partitions :
+                parsedPartitions = json.loads( partitions )
+                main.log.warn( json.dumps( parsedPartitions,
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+                # TODO check for a leader in all paritions
+                # TODO check for consistency among nodes
+            else:
+                main.log.error( "partitions() returned None" )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing partitions" )
+            main.log.error( repr( partitions ) )
+        pendingMap = main.ONOScli1.pendingMap()
+        try:
+            if pendingMap :
+                parsedPending = json.loads( pendingMap )
+                main.log.warn( json.dumps( parsedPending,
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+                # TODO check something here?
+            else:
+                main.log.error( "pendingMap() returned None" )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing pending map" )
+            main.log.error( repr( pendingMap ) )
 
+        intentAddResult = bool( pingResult and hostResult and intentAddResult
+                                and not missingIntents and installedCheck )
         utilities.assert_equals(
             expect=True,
             actual=intentAddResult,
             onpass="Pushed host intents to ONOS",
             onfail="Error in pushing host intents to ONOS" )
-        # TODO Check if intents all exist in datastore
+
+        if not intentAddResult or "key" in pendingMap:
+            import time
+            installedCheck = True
+            main.log.info( "Sleeping 60 seconds to see if intents are found" )
+            time.sleep( 60 )
+            onosIds = main.ONOScli1.getAllIntentsId()
+            main.log.info( "Submitted intents: " + str( intentIds ) )
+            main.log.info( "Intents in ONOS: " + str( onosIds ) )
+            # Print the intent states
+            intents = main.ONOScli1.intents()
+            intentStates = []
+            main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
+            count = 0
+            try:
+                for intent in json.loads( intents ):
+                    # Iter through intents of a node
+                    state = intent.get( 'state', None )
+                    if "INSTALLED" not in state:
+                        installedCheck = False
+                    intentId = intent.get( 'id', None )
+                    intentStates.append( ( intentId, state ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing intents" )
+            # add submitted intents not in the store
+            tmplist = [ i for i, s in intentStates ]
+            for i in intentIds:
+                if i not in tmplist:
+                    intentStates.append( ( i, " - " ) )
+            intentStates.sort()
+            for i, s in intentStates:
+                count += 1
+                main.log.info( "%-6s%-15s%-15s" %
+                               ( str( count ), str( i ), str( s ) ) )
+            leaders = main.ONOScli1.leaders()
+            try:
+                if leaders:
+                    parsedLeaders = json.loads( leaders )
+                    main.log.warn( json.dumps( parsedLeaders,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # check for all intent partitions
+                    # check for election
+                    topics = []
+                    for i in range( 14 ):
+                        topics.append( "intent-partition-" + str( i ) )
+                    # FIXME: this should only be after we start the app
+                    topics.append( "org.onosproject.election" )
+                    main.log.debug( topics )
+                    ONOStopics = [ j['topic'] for j in parsedLeaders ]
+                    for topic in topics:
+                        if topic not in ONOStopics:
+                            main.log.error( "Error: " + topic +
+                                            " not in leaders" )
+                else:
+                    main.log.error( "leaders() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing leaders" )
+                main.log.error( repr( leaders ) )
+            partitions = main.ONOScli1.partitions()
+            try:
+                if partitions :
+                    parsedPartitions = json.loads( partitions )
+                    main.log.warn( json.dumps( parsedPartitions,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check for a leader in all paritions
+                    # TODO check for consistency among nodes
+                else:
+                    main.log.error( "partitions() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing partitions" )
+                main.log.error( repr( partitions ) )
+            pendingMap = main.ONOScli1.pendingMap()
+            try:
+                if pendingMap :
+                    parsedPending = json.loads( pendingMap )
+                    main.log.warn( json.dumps( parsedPending,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check something here?
+                else:
+                    main.log.error( "pendingMap() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing pending map" )
+                main.log.error( repr( pendingMap ) )
 
     def CASE4( self, main ):
         """
         Ping across added host intents
         """
+        import json
+        import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         description = " Ping across added host intents"
         main.log.report( description )
         main.case( description )
         PingResult = main.TRUE
         for i in range( 8, 18 ):
-            ping = main.Mininet1.pingHost(
-                src="h" + str( i ), target="h" + str( i + 10 ) )
+            ping = main.Mininet1.pingHost( src="h" + str( i ),
+                                           target="h" + str( i + 10 ) )
             PingResult = PingResult and ping
             if ping == main.FALSE:
                 main.log.warn( "Ping failed between h" + str( i ) +
@@ -512,12 +705,16 @@
         if PingResult == main.FALSE:
             main.log.report(
                 "Intents have not been installed correctly, pings failed." )
-            #TODO: pretty print
-            main.log.warn( "ONSO1 intents: " )
-            main.log.warn( json.dumps( json.loads( main.ONOScli1.intents() ),
-                                       sort_keys=True,
-                                       indent=4,
-                                       separators=( ',', ': ' ) ) )
+            # TODO: pretty print
+            main.log.warn( "ONOS1 intents: " )
+            try:
+                tmpIntents = main.ONOScli1.intents()
+                main.log.warn( json.dumps( json.loads( tmpIntents ),
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+            except ( ValueError, TypeError ):
+                main.log.warn( repr( tmpIntents ) )
         if PingResult == main.TRUE:
             main.log.report(
                 "Intents have been installed correctly and verified by pings" )
@@ -527,11 +724,175 @@
             onpass="Intents have been installed correctly and pings work",
             onfail="Intents have not been installed correctly, pings failed." )
 
+        installedCheck = True
+        if PingResult is not main.TRUE:
+            # Print the intent states
+            intents = main.ONOScli1.intents()
+            intentStates = []
+            main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
+            count = 0
+            # Iter through intents of a node
+            try:
+                for intent in json.loads( intents ):
+                    state = intent.get( 'state', None )
+                    if "INSTALLED" not in state:
+                        installedCheck = False
+                    intentId = intent.get( 'id', None )
+                    intentStates.append( ( intentId, state ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing intents." )
+            intentStates.sort()
+            for i, s in intentStates:
+                count += 1
+                main.log.info( "%-6s%-15s%-15s" %
+                               ( str( count ), str( i ), str( s ) ) )
+            leaders = main.ONOScli1.leaders()
+            try:
+                if leaders:
+                    parsedLeaders = json.loads( leaders )
+                    main.log.warn( json.dumps( parsedLeaders,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # check for all intent partitions
+                    # check for election
+                    topics = []
+                    for i in range( 14 ):
+                        topics.append( "intent-partition-" + str( i ) )
+                    # FIXME: this should only be after we start the app
+                    topics.append( "org.onosproject.election" )
+                    main.log.debug( topics )
+                    ONOStopics = [ j['topic'] for j in parsedLeaders ]
+                    for topic in topics:
+                        if topic not in ONOStopics:
+                            main.log.error( "Error: " + topic +
+                                            " not in leaders" )
+                else:
+                    main.log.error( "leaders() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing leaders" )
+                main.log.error( repr( leaders ) )
+            partitions = main.ONOScli1.partitions()
+            try:
+                if partitions :
+                    parsedPartitions = json.loads( partitions )
+                    main.log.warn( json.dumps( parsedPartitions,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check for a leader in all paritions
+                    # TODO check for consistency among nodes
+                else:
+                    main.log.error( "partitions() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing partitions" )
+                main.log.error( repr( partitions ) )
+            pendingMap = main.ONOScli1.pendingMap()
+            try:
+                if pendingMap :
+                    parsedPending = json.loads( pendingMap )
+                    main.log.warn( json.dumps( parsedPending,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check something here?
+                else:
+                    main.log.error( "pendingMap() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing pending map" )
+                main.log.error( repr( pendingMap ) )
+
+        if not installedCheck:
+            main.log.info( "Waiting 60 seconds to see if the state of " +
+                           "intents change" )
+            time.sleep( 60 )
+            # Print the intent states
+            intents = main.ONOScli1.intents()
+            intentStates = []
+            main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
+            count = 0
+            # Iter through intents of a node
+            try:
+                for intent in json.loads( intents ):
+                    state = intent.get( 'state', None )
+                    if "INSTALLED" not in state:
+                        installedCheck = False
+                    intentId = intent.get( 'id', None )
+                    intentStates.append( ( intentId, state ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing intents." )
+            intentStates.sort()
+            for i, s in intentStates:
+                count += 1
+                main.log.info( "%-6s%-15s%-15s" %
+                               ( str( count ), str( i ), str( s ) ) )
+            leaders = main.ONOScli1.leaders()
+            try:
+                if leaders:
+                    parsedLeaders = json.loads( leaders )
+                    main.log.warn( json.dumps( parsedLeaders,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # check for all intent partitions
+                    # check for election
+                    topics = []
+                    for i in range( 14 ):
+                        topics.append( "intent-partition-" + str( i ) )
+                    # FIXME: this should only be after we start the app
+                    topics.append( "org.onosproject.election" )
+                    main.log.debug( topics )
+                    ONOStopics = [ j['topic'] for j in parsedLeaders ]
+                    for topic in topics:
+                        if topic not in ONOStopics:
+                            main.log.error( "Error: " + topic +
+                                            " not in leaders" )
+                else:
+                    main.log.error( "leaders() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing leaders" )
+                main.log.error( repr( leaders ) )
+            partitions = main.ONOScli1.partitions()
+            try:
+                if partitions :
+                    parsedPartitions = json.loads( partitions )
+                    main.log.warn( json.dumps( parsedPartitions,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check for a leader in all paritions
+                    # TODO check for consistency among nodes
+                else:
+                    main.log.error( "partitions() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing partitions" )
+                main.log.error( repr( partitions ) )
+            pendingMap = main.ONOScli1.pendingMap()
+            try:
+                if pendingMap :
+                    parsedPending = json.loads( pendingMap )
+                    main.log.warn( json.dumps( parsedPending,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check something here?
+                else:
+                    main.log.error( "pendingMap() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing pending map" )
+                main.log.error( repr( pendingMap ) )
+
     def CASE5( self, main ):
         """
         Reading state of ONOS
         """
         import json
+        import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         # assumes that sts is already in you PYTHONPATH
         from sts.topology.teston_topology import TestONTopology
 
@@ -539,330 +900,239 @@
         main.case( "Setting up and gathering data for current state" )
         # The general idea for this test case is to pull the state of
         # ( intents,flows, topology,... ) from each ONOS node
-        # We can then compare them with eachother and also with past states
+        # We can then compare them with each other and also with past states
 
-        main.step( "Get the Mastership of each switch from each controller" )
+        main.step( "Check that each switch has a master" )
         global mastershipState
-        mastershipState = []
+        mastershipState = '[]'
 
         # Assert that each device has a master
-        ONOS1MasterNotNull = main.ONOScli1.rolesNotNull()
-        ONOS2MasterNotNull = main.ONOScli2.rolesNotNull()
-        ONOS3MasterNotNull = main.ONOScli3.rolesNotNull()
-        ONOS4MasterNotNull = main.ONOScli4.rolesNotNull()
-        ONOS5MasterNotNull = main.ONOScli5.rolesNotNull()
-        ONOS6MasterNotNull = main.ONOScli6.rolesNotNull()
-        ONOS7MasterNotNull = main.ONOScli7.rolesNotNull()
-        rolesNotNull = ONOS1MasterNotNull and ONOS2MasterNotNull and\
-            ONOS3MasterNotNull and ONOS4MasterNotNull and\
-            ONOS5MasterNotNull and ONOS6MasterNotNull and\
-            ONOS7MasterNotNull
+        rolesNotNull = main.TRUE
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].rolesNotNull,
+                             name="rolesNotNull-" + str( i ),
+                             args=[] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            rolesNotNull = rolesNotNull and t.result
         utilities.assert_equals(
             expect=main.TRUE,
             actual=rolesNotNull,
             onpass="Each device has a master",
             onfail="Some devices don't have a master assigned" )
 
-        ONOS1Mastership = main.ONOScli1.roles()
-        ONOS2Mastership = main.ONOScli2.roles()
-        ONOS3Mastership = main.ONOScli3.roles()
-        ONOS4Mastership = main.ONOScli4.roles()
-        ONOS5Mastership = main.ONOScli5.roles()
-        ONOS6Mastership = main.ONOScli6.roles()
-        ONOS7Mastership = main.ONOScli7.roles()
-        if "Error" in ONOS1Mastership or not ONOS1Mastership\
-                or "Error" in ONOS2Mastership or not ONOS2Mastership\
-                or "Error" in ONOS3Mastership or not ONOS3Mastership\
-                or "Error" in ONOS4Mastership or not ONOS4Mastership\
-                or "Error" in ONOS5Mastership or not ONOS5Mastership\
-                or "Error" in ONOS6Mastership or not ONOS6Mastership\
-                or "Error" in ONOS7Mastership or not ONOS7Mastership:
-            main.log.report( "Error in getting ONOS roles" )
-            main.log.warn(
-                "ONOS1 mastership response: " +
-                repr( ONOS1Mastership ) )
-            main.log.warn(
-                "ONOS2 mastership response: " +
-                repr( ONOS2Mastership ) )
-            main.log.warn(
-                "ONOS3 mastership response: " +
-                repr( ONOS3Mastership ) )
-            main.log.warn(
-                "ONOS4 mastership response: " +
-                repr( ONOS4Mastership ) )
-            main.log.warn(
-                "ONOS5 mastership response: " +
-                repr( ONOS5Mastership ) )
-            main.log.warn(
-                "ONOS6 mastership response: " +
-                repr( ONOS6Mastership ) )
-            main.log.warn(
-                "ONOS7 mastership response: " +
-                repr( ONOS7Mastership ) )
-            consistentMastership = main.FALSE
-        elif ONOS1Mastership == ONOS2Mastership\
-                and ONOS1Mastership == ONOS3Mastership\
-                and ONOS1Mastership == ONOS4Mastership\
-                and ONOS1Mastership == ONOS5Mastership\
-                and ONOS1Mastership == ONOS6Mastership\
-                and ONOS1Mastership == ONOS7Mastership:
-            mastershipState = ONOS1Mastership
-            consistentMastership = main.TRUE
+        main.step( "Get the Mastership of each switch from each controller" )
+        ONOSMastership = []
+        mastershipCheck = main.FALSE
+        consistentMastership = True
+        rolesResults = True
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].roles,
+                             name="roles-" + str( i ),
+                             args=[] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            ONOSMastership.append( t.result )
+
+        for i in range( numControllers ):
+            if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
+                main.log.report( "Error in getting ONOS" + str( i + 1 ) +
+                                 " roles" )
+                main.log.warn(
+                    "ONOS" + str( i + 1 ) + " mastership response: " +
+                    repr( ONOSMastership[i] ) )
+                rolesResults = False
+        utilities.assert_equals(
+            expect=True,
+            actual=rolesResults,
+            onpass="No error in reading roles output",
+            onfail="Error in reading roles from ONOS" )
+
+        main.step( "Check for consistency in roles from each controller" )
+        if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
             main.log.report(
                 "Switch roles are consistent across all ONOS nodes" )
         else:
-            main.log.warn(
-                "ONOS1 roles: ",
-                json.dumps(
-                    json.loads( ONOS1Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS2 roles: ",
-                json.dumps(
-                    json.loads( ONOS2Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS3 roles: ",
-                json.dumps(
-                    json.loads( ONOS3Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS4 roles: ",
-                json.dumps(
-                    json.loads( ONOS4Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS5 roles: ",
-                json.dumps(
-                    json.loads( ONOS5Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS6 roles: ",
-                json.dumps(
-                    json.loads( ONOS6Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS7 roles: ",
-                json.dumps(
-                    json.loads( ONOS7Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            consistentMastership = main.FALSE
+            consistentMastership = False
         utilities.assert_equals(
-            expect=main.TRUE,
+            expect=True,
             actual=consistentMastership,
             onpass="Switch roles are consistent across all ONOS nodes",
             onfail="ONOS nodes have different views of switch roles" )
 
+        if rolesResults and not consistentMastership:
+            for i in range( numControllers ):
+                try:
+                    main.log.warn(
+                        "ONOS" + str( i + 1 ) + " roles: ",
+                        json.dumps(
+                            json.loads( ONOSMastership[ i ] ),
+                            sort_keys=True,
+                            indent=4,
+                            separators=( ',', ': ' ) ) )
+                except ( ValueError, TypeError ):
+                    main.log.warn( repr( ONOSMastership[ i ] ) )
+        elif rolesResults and consistentMastership:
+            mastershipCheck = main.TRUE
+            mastershipState = ONOSMastership[ 0 ]
+
         main.step( "Get the intents from each controller" )
         global intentState
         intentState = []
-        ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
-        ONOS2Intents = main.ONOScli2.intents( jsonFormat=True )
-        ONOS3Intents = main.ONOScli3.intents( jsonFormat=True )
-        ONOS4Intents = main.ONOScli4.intents( jsonFormat=True )
-        ONOS5Intents = main.ONOScli5.intents( jsonFormat=True )
-        ONOS6Intents = main.ONOScli6.intents( jsonFormat=True )
-        ONOS7Intents = main.ONOScli7.intents( jsonFormat=True )
+        ONOSIntents = []
         intentCheck = main.FALSE
-        if "Error" in ONOS1Intents or not ONOS1Intents\
-                or "Error" in ONOS2Intents or not ONOS2Intents\
-                or "Error" in ONOS3Intents or not ONOS3Intents\
-                or "Error" in ONOS4Intents or not ONOS4Intents\
-                or "Error" in ONOS5Intents or not ONOS5Intents\
-                or "Error" in ONOS6Intents or not ONOS6Intents\
-                or "Error" in ONOS7Intents or not ONOS7Intents:
-            main.log.report( "Error in getting ONOS intents" )
-            main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
-            main.log.warn( "ONOS2 intents response: " + repr( ONOS2Intents ) )
-            main.log.warn( "ONOS3 intents response: " + repr( ONOS3Intents ) )
-            main.log.warn( "ONOS4 intents response: " + repr( ONOS4Intents ) )
-            main.log.warn( "ONOS5 intents response: " + repr( ONOS5Intents ) )
-            main.log.warn( "ONOS6 intents response: " + repr( ONOS6Intents ) )
-            main.log.warn( "ONOS7 intents response: " + repr( ONOS7Intents ) )
-        elif ONOS1Intents == ONOS2Intents\
-                and ONOS1Intents == ONOS3Intents\
-                and ONOS1Intents == ONOS4Intents\
-                and ONOS1Intents == ONOS5Intents\
-                and ONOS1Intents == ONOS6Intents\
-                and ONOS1Intents == ONOS7Intents:
-            intentState = ONOS1Intents
-            intentCheck = main.TRUE
-            main.log.report( "Intents are consistent across all ONOS nodes" )
-        else:
-            main.log.warn(
-                "ONOS1 intents: ",
-                json.dumps(
-                    json.loads( ONOS1Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS2 intents: ",
-                json.dumps(
-                    json.loads( ONOS2Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS3 intents: ",
-                json.dumps(
-                    json.loads( ONOS3Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS4 intents: ",
-                json.dumps(
-                    json.loads( ONOS4Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS5 intents: ",
-                json.dumps(
-                    json.loads( ONOS5Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS6 intents: ",
-                json.dumps(
-                    json.loads( ONOS6Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS7 intents: ",
-                json.dumps(
-                    json.loads( ONOS7Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
+        consistentIntents = True
+        intentsResults = True
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].intents,
+                             name="intents-" + str( i ),
+                             args=[],
+                             kwargs={ 'jsonFormat': True } )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            ONOSIntents.append( t.result )
+
+        for i in range( numControllers ):
+            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
+                main.log.report( "Error in getting ONOS" + str( i + 1 ) +
+                                 " intents" )
+                main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
+                               repr( ONOSIntents[ i ] ) )
+                intentsResults = False
         utilities.assert_equals(
-            expect=main.TRUE,
-            actual=intentCheck,
+            expect=True,
+            actual=intentsResults,
+            onpass="No error in reading intents output",
+            onfail="Error in reading intents from ONOS" )
+
+        main.step( "Check for consistency in Intents from each controller" )
+        if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
+            main.log.report( "Intents are consistent across all ONOS " +
+                             "nodes" )
+        else:
+            consistentIntents = False
+            main.log.report( "Intents not consistent" )
+        utilities.assert_equals(
+            expect=True,
+            actual=consistentIntents,
             onpass="Intents are consistent across all ONOS nodes",
             onfail="ONOS nodes have different views of intents" )
 
+        if intentsResults and not consistentIntents:
+            n = len(ONOSIntents)
+            main.log.warn( "ONOS" + str( n ) + " intents: " )
+            main.log.warn( json.dumps( json.loads( ONOSIntents[ -1 ] ),
+                                       sort_keys=True,
+                                       indent=4,
+                                       separators=( ',', ': ' ) ) )
+            for i in range( numControllers ):
+                if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
+                    main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
+                    main.log.warn( json.dumps( json.loads( ONOSIntents[i] ),
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                else:
+                    main.log.warn( nodes[ i ].name + " intents match ONOS" +
+                                   str( n ) + " intents" )
+        elif intentsResults and consistentIntents:
+            intentCheck = main.TRUE
+            intentState = ONOSIntents[ 0 ]
+
         main.step( "Get the flows from each controller" )
         global flowState
         flowState = []
-        ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
-        ONOS2Flows = main.ONOScli2.flows( jsonFormat=True )
-        ONOS3Flows = main.ONOScli3.flows( jsonFormat=True )
-        ONOS4Flows = main.ONOScli4.flows( jsonFormat=True )
-        ONOS5Flows = main.ONOScli5.flows( jsonFormat=True )
-        ONOS6Flows = main.ONOScli6.flows( jsonFormat=True )
-        ONOS7Flows = main.ONOScli7.flows( jsonFormat=True )
-        ONOS1FlowsJson = json.loads( ONOS1Flows )
-        ONOS2FlowsJson = json.loads( ONOS2Flows )
-        ONOS3FlowsJson = json.loads( ONOS3Flows )
-        ONOS4FlowsJson = json.loads( ONOS4Flows )
-        ONOS5FlowsJson = json.loads( ONOS5Flows )
-        ONOS6FlowsJson = json.loads( ONOS6Flows )
-        ONOS7FlowsJson = json.loads( ONOS7Flows )
+        ONOSFlows = []
+        ONOSFlowsJson = []
         flowCheck = main.FALSE
-        if "Error" in ONOS1Flows or not ONOS1Flows\
-                or "Error" in ONOS2Flows or not ONOS2Flows\
-                or "Error" in ONOS3Flows or not ONOS3Flows\
-                or "Error" in ONOS4Flows or not ONOS4Flows\
-                or "Error" in ONOS5Flows or not ONOS5Flows\
-                or "Error" in ONOS6Flows or not ONOS6Flows\
-                or "Error" in ONOS7Flows or not ONOS7Flows:
-            main.log.report( "Error in getting ONOS intents" )
-            main.log.warn( "ONOS1 flows repsponse: " + ONOS1Flows )
-            main.log.warn( "ONOS2 flows repsponse: " + ONOS2Flows )
-            main.log.warn( "ONOS3 flows repsponse: " + ONOS3Flows )
-            main.log.warn( "ONOS4 flows repsponse: " + ONOS4Flows )
-            main.log.warn( "ONOS5 flows repsponse: " + ONOS5Flows )
-            main.log.warn( "ONOS6 flows repsponse: " + ONOS6Flows )
-            main.log.warn( "ONOS7 flows repsponse: " + ONOS7Flows )
-        elif len( ONOS1FlowsJson ) == len( ONOS2FlowsJson )\
-                and len( ONOS1FlowsJson ) == len( ONOS3FlowsJson )\
-                and len( ONOS1FlowsJson ) == len( ONOS4FlowsJson )\
-                and len( ONOS1FlowsJson ) == len( ONOS5FlowsJson )\
-                and len( ONOS1FlowsJson ) == len( ONOS6FlowsJson )\
-                and len( ONOS1FlowsJson ) == len( ONOS7FlowsJson ):
-                # TODO: Do a better check, maybe compare flows on switches?
-            flowState = ONOS1Flows
-            flowCheck = main.TRUE
+        consistentFlows = True
+        flowsResults = True
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].flows,
+                             name="flows-" + str( i ),
+                             args=[],
+                             kwargs={ 'jsonFormat': True } )
+            threads.append( t )
+            t.start()
+
+        time.sleep(30)
+        for t in threads:
+            t.join()
+            result = t.result
+            ONOSFlows.append( result )
+
+        for i in range( numControllers ):
+            num = str( i + 1 )
+            if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
+                main.log.report( "Error in getting ONOS" + num + " flows" )
+                main.log.warn( "ONOS" + num + " flows response: " +
+                               repr( ONOSFlows[ i ] ) )
+                flowsResults = False
+                ONOSFlowsJson.append( None )
+            else:
+                try:
+                    ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
+                except ( ValueError, TypeError ):
+                    # FIXME: change this to log.error?
+                    main.log.exception( "Error in parsing ONOS" + num +
+                                        " response as json." )
+                    main.log.error( repr( ONOSFlows[ i ] ) )
+                    ONOSFlowsJson.append( None )
+                    flowsResults = False
+        utilities.assert_equals(
+            expect=True,
+            actual=flowsResults,
+            onpass="No error in reading flows output",
+            onfail="Error in reading flows from ONOS" )
+
+        main.step( "Check for consistency in Flows from each controller" )
+        tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
+        if all( tmp ):
             main.log.report( "Flow count is consistent across all ONOS nodes" )
         else:
-            main.log.warn( "ONOS1 flows: " +
-                           json.dumps( ONOS1FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS2 flows: " +
-                           json.dumps( ONOS2FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS3 flows: " +
-                           json.dumps( ONOS3FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS4 flows: " +
-                           json.dumps( ONOS4FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS5 flows: " +
-                           json.dumps( ONOS5FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS6 flows: " +
-                           json.dumps( ONOS6FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS7 flows: " +
-                           json.dumps( ONOS7FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
+            consistentFlows = False
         utilities.assert_equals(
-            expect=main.TRUE,
-            actual=flowCheck,
+            expect=True,
+            actual=consistentFlows,
             onpass="The flow count is consistent across all ONOS nodes",
             onfail="ONOS nodes have different flow counts" )
 
+        if flowsResults and not consistentFlows:
+            for i in range( numControllers ):
+                try:
+                    main.log.warn(
+                        "ONOS" + str( i + 1 ) + " flows: " +
+                        json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
+                                    indent=4, separators=( ',', ': ' ) ) )
+                except ( ValueError, TypeError ):
+                    main.log.warn(
+                        "ONOS" + str( i + 1 ) + " flows: " +
+                        repr( ONOSFlows[ i ] ) )
+        elif flowsResults and consistentFlows:
+            flowCheck = main.TRUE
+            flowState = ONOSFlows[ 0 ]
+
         main.step( "Get the OF Table entries" )
         global flows
         flows = []
         for i in range( 1, 29 ):
             flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
-
+        if flowCheck == main.FALSE:
+            for table in flows:
+                main.log.warn( table )
         # TODO: Compare switch flow tables with ONOS flow tables
 
         main.step( "Start continuous pings" )
@@ -909,64 +1179,80 @@
 
         main.step( "Create TestONTopology object" )
         ctrls = []
-        count = 1
-        while True:
-            temp = ()
-            if ( 'ip' + str( count ) ) in main.params[ 'CTRL' ]:
-                temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
-                temp = temp + ( "ONOS" + str( count ), )
-                temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
-                temp = temp + \
-                    ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
-                ctrls.append( temp )
-                count = count + 1
-            else:
-                break
-        MNTopo = TestONTopology(
-            main.Mininet1,
-            ctrls )  # can also add Intent API info for intent operations
+        for node in nodes:
+            temp = ( node, node.name, node.ip_address, 6633 )
+            ctrls.append( temp )
+        MNTopo = TestONTopology( main.Mininet1, ctrls )
 
         main.step( "Collecting topology information from ONOS" )
         devices = []
-        devices.append( main.ONOScli1.devices() )
-        devices.append( main.ONOScli2.devices() )
-        devices.append( main.ONOScli3.devices() )
-        devices.append( main.ONOScli4.devices() )
-        devices.append( main.ONOScli5.devices() )
-        devices.append( main.ONOScli6.devices() )
-        devices.append( main.ONOScli7.devices() )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].devices,
+                             name="devices-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            devices.append( t.result )
         hosts = []
-        hosts.append( main.ONOScli1.hosts() )
-        hosts.append( main.ONOScli2.hosts() )
-        hosts.append( main.ONOScli3.hosts() )
-        hosts.append( main.ONOScli4.hosts() )
-        hosts.append( main.ONOScli5.hosts() )
-        hosts.append( main.ONOScli6.hosts() )
-        hosts.append( main.ONOScli7.hosts() )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].hosts,
+                             name="hosts-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            try:
+                hosts.append( json.loads( t.result ) )
+            except ( ValueError, TypeError ):
+                # FIXME: better handling of this, print which node
+                #        Maybe use thread name?
+                main.log.exception( "Error parsing json output of hosts" )
+                # FIXME: should this be an empty json object instead?
+                hosts.append( None )
+
         ports = []
-        ports.append( main.ONOScli1.ports() )
-        ports.append( main.ONOScli2.ports() )
-        ports.append( main.ONOScli3.ports() )
-        ports.append( main.ONOScli4.ports() )
-        ports.append( main.ONOScli5.ports() )
-        ports.append( main.ONOScli6.ports() )
-        ports.append( main.ONOScli7.ports() )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].ports,
+                             name="ports-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            ports.append( t.result )
         links = []
-        links.append( main.ONOScli1.links() )
-        links.append( main.ONOScli2.links() )
-        links.append( main.ONOScli3.links() )
-        links.append( main.ONOScli4.links() )
-        links.append( main.ONOScli5.links() )
-        links.append( main.ONOScli6.links() )
-        links.append( main.ONOScli7.links() )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].links,
+                             name="links-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            links.append( t.result )
         clusters = []
-        clusters.append( main.ONOScli1.clusters() )
-        clusters.append( main.ONOScli2.clusters() )
-        clusters.append( main.ONOScli3.clusters() )
-        clusters.append( main.ONOScli4.clusters() )
-        clusters.append( main.ONOScli5.clusters() )
-        clusters.append( main.ONOScli6.clusters() )
-        clusters.append( main.ONOScli7.clusters() )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].clusters,
+                             name="clusters-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            clusters.append( t.result )
         # Compare json objects for hosts and dataplane clusters
 
         # hosts
@@ -996,15 +1282,29 @@
             onpass="Hosts view is consistent across all ONOS nodes",
             onfail="ONOS nodes have different views of hosts" )
 
+        ipResult = main.TRUE
+        for controller in range( 0, len( hosts ) ):
+            controllerStr = str( controller + 1 )
+            for host in hosts[ controller ]:
+                if not host.get( 'ips', [ ] ):
+                    main.log.error( "DEBUG:Error with host ips on controller" +
+                                    controllerStr + ": " + str( host ) )
+                    ipResult = main.FALSE
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=ipResult,
+            onpass="The ips of the hosts aren't empty",
+            onfail="The ip of at least one host is missing" )
+
         # Strongly connected clusters of devices
         consistentClustersResult = main.TRUE
         for controller in range( len( clusters ) ):
+            controllerStr = str( controller + 1 )
             if "Error" not in clusters[ controller ]:
                 if clusters[ controller ] == clusters[ 0 ]:
                     continue
                 else:  # clusters not consistent
-                    main.log.report( "clusters from ONOS" +
-                                     controllerStr +
+                    main.log.report( "clusters from ONOS" + controllerStr +
                                      " is inconsistent with ONOS1" )
                     consistentClustersResult = main.FALSE
 
@@ -1021,14 +1321,19 @@
             onpass="Clusters view is consistent across all ONOS nodes",
             onfail="ONOS nodes have different views of clusters" )
         # there should always only be one cluster
-        numClusters = len( json.loads( clusters[ 0 ] ) )
+        try:
+            numClusters = len( json.loads( clusters[ 0 ] ) )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing clusters[0]: " +
+                                repr( clusters[ 0 ] ) )
+        clusterResults = main.FALSE
+        if numClusters == 1:
+            clusterResults = main.TRUE
         utilities.assert_equals(
             expect=1,
             actual=numClusters,
             onpass="ONOS shows 1 SCC",
-            onfail="ONOS shows " +
-            str( numClusters ) +
-            " SCCs" )
+            onfail="ONOS shows " + str( numClusters ) + " SCCs" )
 
         main.step( "Comparing ONOS topology to MN" )
         devicesResults = main.TRUE
@@ -1039,214 +1344,210 @@
             if devices[ controller ] or "Error" not in devices[ controller ]:
                 currentDevicesResult = main.Mininet1.compareSwitches(
                     MNTopo,
-                    json.loads(
-                        devices[ controller ] ) )
+                    json.loads( devices[ 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" )
+                                     actual=currentDevicesResult,
+                                     onpass="ONOS" + controllerStr +
+                                     " Switches view is correct",
+                                     onfail="ONOS" + controllerStr +
+                                     " Switches view is incorrect" )
 
             if ports[ controller ] or "Error" not in ports[ controller ]:
                 currentPortsResult = main.Mininet1.comparePorts(
                     MNTopo,
-                    json.loads(
-                        ports[ controller ] ) )
+                    json.loads( ports[ controller ] ) )
             else:
                 currentPortsResult = main.FALSE
             utilities.assert_equals( expect=main.TRUE,
-                                    actual=currentPortsResult,
-                                    onpass="ONOS" + controllerStr +
-                                    " ports view is correct",
-                                    onfail="ONOS" + controllerStr +
-                                    " ports view is incorrect" )
+                                     actual=currentPortsResult,
+                                     onpass="ONOS" + controllerStr +
+                                     " ports view is correct",
+                                     onfail="ONOS" + controllerStr +
+                                     " ports view is incorrect" )
 
             if links[ controller ] or "Error" not in links[ controller ]:
                 currentLinksResult = main.Mininet1.compareLinks(
                     MNTopo,
-                    json.loads(
-                        links[ controller ] ) )
+                    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" )
+                                     actual=currentLinksResult,
+                                     onpass="ONOS" + controllerStr +
+                                     " links view is correct",
+                                     onfail="ONOS" + controllerStr +
+                                     " links view is incorrect" )
 
             devicesResults = devicesResults and currentDevicesResult
             portsResults = portsResults and currentPortsResult
             linksResults = linksResults and currentLinksResult
 
-        topoResult = devicesResults and portsResults and linksResults\
-            and consistentHostsResult and consistentClustersResult
+        topoResult = ( devicesResults and portsResults and linksResults
+                       and consistentHostsResult and consistentClustersResult
+                       and clusterResults and ipResult )
         utilities.assert_equals( expect=main.TRUE, actual=topoResult,
-                                onpass="Topology Check Test successful",
-                                onfail="Topology Check Test NOT successful" )
+                                 onpass="Topology Check Test successful",
+                                 onfail="Topology Check Test NOT successful" )
 
         finalAssert = main.TRUE
-        finalAssert = finalAssert and topoResult and flowCheck \
-            and intentCheck and consistentMastership and rolesNotNull
+        finalAssert = ( finalAssert and topoResult and flowCheck
+                        and intentCheck and consistentMastership
+                        and rolesNotNull )
         utilities.assert_equals( expect=main.TRUE, actual=finalAssert,
-                                onpass="State check successful",
-                                onfail="State check NOT successful" )
+                                 onpass="State check successful",
+                                 onfail="State check NOT successful" )
 
     def CASE6( self, main ):
         """
         The Failure case.
         """
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         main.log.report( "Restart entire ONOS cluster" )
-        main.log.case( "Restart entire ONOS cluster" )
-        main.ONOSbench.onosKill( ONOS1Ip )
-        main.ONOSbench.onosKill( ONOS2Ip )
-        main.ONOSbench.onosKill( ONOS3Ip )
-        main.ONOSbench.onosKill( ONOS4Ip )
-        main.ONOSbench.onosKill( ONOS5Ip )
-        main.ONOSbench.onosKill( ONOS6Ip )
-        main.ONOSbench.onosKill( ONOS7Ip )
+        main.case( "Restart entire ONOS cluster" )
+        main.step( "Killing ONOS nodes" )
+        killResults = main.TRUE
+        for node in nodes:
+            killed = main.ONOSbench.onosKill( node.ip_address )
+            killResults = killResults and killed
 
         main.step( "Checking if ONOS is up yet" )
-        count = 0
-        onosIsupResult = main.FALSE
-        while onosIsupResult == main.FALSE and count < 10:
-            onos1Isup = main.ONOSbench.isup( ONOS1Ip )
-            onos2Isup = main.ONOSbench.isup( ONOS2Ip )
-            onos3Isup = main.ONOSbench.isup( ONOS3Ip )
-            onos4Isup = main.ONOSbench.isup( ONOS4Ip )
-            onos5Isup = main.ONOSbench.isup( ONOS5Ip )
-            onos6Isup = main.ONOSbench.isup( ONOS6Ip )
-            onos7Isup = main.ONOSbench.isup( ONOS7Ip )
-            onosIsupResult = onos1Isup and onos2Isup and onos3Isup\
-                and onos4Isup and onos5Isup and onos6Isup and onos7Isup
-            count = count + 1
-        # TODO: if it becomes an issue, we can retry this step  a few times
+        for i in range( 2 ):
+            onosIsupResult = main.TRUE
+            for node in nodes:
+                started = main.ONOSbench.isup( node.ip_address )
+                if not started:
+                    main.log.report( node.name + " didn't start!" )
+                onosIsupResult = onosIsupResult and started
+            if onosIsupResult == main.TRUE:
+                break
 
-        cliResult1 = main.ONOScli1.startOnosCli( ONOS1Ip )
-        cliResult2 = main.ONOScli2.startOnosCli( ONOS2Ip )
-        cliResult3 = main.ONOScli3.startOnosCli( ONOS3Ip )
-        cliResult4 = main.ONOScli4.startOnosCli( ONOS4Ip )
-        cliResult5 = main.ONOScli5.startOnosCli( ONOS5Ip )
-        cliResult6 = main.ONOScli6.startOnosCli( ONOS6Ip )
-        cliResult7 = main.ONOScli7.startOnosCli( ONOS7Ip )
-        cliResults = cliResult1 and cliResult2 and cliResult3\
-            and cliResult4 and cliResult5 and cliResult6\
-            and cliResult7
+        main.log.step( "Starting ONOS CLI sessions" )
+        cliResults = main.TRUE
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].startOnosCli,
+                             name="startOnosCli-" + str( i ),
+                             args=[nodes[i].ip_address] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            cliResults = cliResults and t.result
 
         caseResults = main.TRUE and onosIsupResult and cliResults
         utilities.assert_equals( expect=main.TRUE, actual=caseResults,
-                                onpass="ONOS restart successful",
-                                onfail="ONOS restart NOT successful" )
+                                 onpass="ONOS restart successful",
+                                 onfail="ONOS restart NOT successful" )
 
     def CASE7( self, main ):
         """
         Check state after ONOS failure
         """
         import json
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         main.case( "Running ONOS Constant State Tests" )
 
+        main.step( "Check that each switch has a master" )
         # Assert that each device has a master
-        ONOS1MasterNotNull = main.ONOScli1.rolesNotNull()
-        ONOS2MasterNotNull = main.ONOScli2.rolesNotNull()
-        ONOS3MasterNotNull = main.ONOScli3.rolesNotNull()
-        ONOS4MasterNotNull = main.ONOScli4.rolesNotNull()
-        ONOS5MasterNotNull = main.ONOScli5.rolesNotNull()
-        ONOS6MasterNotNull = main.ONOScli6.rolesNotNull()
-        ONOS7MasterNotNull = main.ONOScli7.rolesNotNull()
-        rolesNotNull = ONOS1MasterNotNull and ONOS2MasterNotNull and\
-            ONOS3MasterNotNull and ONOS4MasterNotNull and\
-            ONOS5MasterNotNull and ONOS6MasterNotNull and\
-            ONOS7MasterNotNull
+        rolesNotNull = main.TRUE
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].rolesNotNull,
+                             name="rolesNotNull-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            rolesNotNull = rolesNotNull and t.result
         utilities.assert_equals(
             expect=main.TRUE,
             actual=rolesNotNull,
             onpass="Each device has a master",
             onfail="Some devices don't have a master assigned" )
 
-        main.step( "Check if switch roles are consistent across all nodes" )
-        ONOS1Mastership = main.ONOScli1.roles()
-        ONOS2Mastership = main.ONOScli2.roles()
-        ONOS3Mastership = main.ONOScli3.roles()
-        ONOS4Mastership = main.ONOScli4.roles()
-        ONOS5Mastership = main.ONOScli5.roles()
-        ONOS6Mastership = main.ONOScli6.roles()
-        ONOS7Mastership = main.ONOScli7.roles()
-        if "Error" in ONOS1Mastership or not ONOS1Mastership\
-                or "Error" in ONOS2Mastership or not ONOS2Mastership\
-                or "Error" in ONOS3Mastership or not ONOS3Mastership\
-                or "Error" in ONOS4Mastership or not ONOS4Mastership\
-                or "Error" in ONOS5Mastership or not ONOS5Mastership\
-                or "Error" in ONOS6Mastership or not ONOS6Mastership\
-                or "Error" in ONOS7Mastership or not ONOS7Mastership:
-            main.log.error( "Error in getting ONOS mastership" )
-            main.log.warn( "ONOS1 mastership response: " +
-                           repr( ONOS1Mastership ) )
-            main.log.warn( "ONOS2 mastership response: " +
-                           repr( ONOS2Mastership ) )
-            main.log.warn( "ONOS3 mastership response: " +
-                           repr( ONOS3Mastership ) )
-            main.log.warn( "ONOS4 mastership response: " +
-                           repr( ONOS4Mastership ) )
-            main.log.warn( "ONOS5 mastership response: " +
-                           repr( ONOS5Mastership ) )
-            main.log.warn( "ONOS6 mastership response: " +
-                           repr( ONOS6Mastership ) )
-            main.log.warn( "ONOS7 mastership response: " +
-                           repr( ONOS7Mastership ) )
-            consistentMastership = main.FALSE
-        elif ONOS1Mastership == ONOS2Mastership\
-                and ONOS1Mastership == ONOS3Mastership\
-                and ONOS1Mastership == ONOS4Mastership\
-                and ONOS1Mastership == ONOS5Mastership\
-                and ONOS1Mastership == ONOS6Mastership\
-                and ONOS1Mastership == ONOS7Mastership:
-            consistentMastership = main.TRUE
+        ONOSMastership = []
+        mastershipCheck = main.FALSE
+        consistentMastership = True
+        rolesResults = True
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].roles,
+                             name="roles-" + str( i ),
+                             args=[] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            ONOSMastership.append( t.result )
+
+        for i in range( numControllers ):
+            if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
+                main.log.report( "Error in getting ONOS" + str( i + 1 ) +
+                                 " roles" )
+                main.log.warn(
+                    "ONOS" + str( i + 1 ) + " mastership response: " +
+                    repr( ONOSMastership[i] ) )
+                rolesResults = False
+        utilities.assert_equals(
+            expect=True,
+            actual=rolesResults,
+            onpass="No error in reading roles output",
+            onfail="Error in reading roles from ONOS" )
+
+        main.step( "Check for consistency in roles from each controller" )
+        if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
             main.log.report(
                 "Switch roles are consistent across all ONOS nodes" )
         else:
-            main.log.warn( "ONOS1 roles: ", json.dumps(
-                json.loads( ONOS1Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS2 roles: ", json.dumps(
-                json.loads( ONOS2Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS3 roles: ", json.dumps(
-                json.loads( ONOS3Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS4 roles: ", json.dumps(
-                json.loads( ONOS4Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS5 roles: ", json.dumps(
-                json.loads( ONOS5Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS6 roles: ", json.dumps(
-                json.loads( ONOS6Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS7 roles: ", json.dumps(
-                json.loads( ONOS7Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            consistentMastership = main.FALSE
+            consistentMastership = False
         utilities.assert_equals(
-            expect=main.TRUE,
+            expect=True,
             actual=consistentMastership,
             onpass="Switch roles are consistent across all ONOS nodes",
             onfail="ONOS nodes have different views of switch roles" )
 
+        if rolesResults and not consistentMastership:
+            for i in range( numControllers ):
+                main.log.warn(
+                    "ONOS" + str( i + 1 ) + " roles: ",
+                    json.dumps(
+                        json.loads( ONOSMastership[ i ] ),
+                        sort_keys=True,
+                        indent=4,
+                        separators=( ',', ': ' ) ) )
+        elif rolesResults and not consistentMastership:
+            mastershipCheck = main.TRUE
+
         description2 = "Compare switch roles from before failure"
         main.step( description2 )
-
-        currentJson = json.loads( ONOS1Mastership )
-        oldJson = json.loads( mastershipState )
+        try:
+            currentJson = json.loads( ONOSMastership[0] )
+            oldJson = json.loads( mastershipState )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Something is wrong with parsing " +
+                                "ONOSMastership[0] or mastershipState" )
+            main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
+            main.log.error( "mastershipState" + repr( mastershipState ) )
+            main.cleanup()
+            main.exit()
         mastershipCheck = main.TRUE
         for i in range( 1, 29 ):
             switchDPID = str(
-                main.Mininet1.getSwitchDPID(
-                    switch="s" +
-                    str( i ) ) )
-
+                main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
             current = [ switch[ 'master' ] for switch in currentJson
                         if switchDPID in switch[ 'id' ] ]
             old = [ switch[ 'master' ] for switch in oldJson
@@ -1267,103 +1568,93 @@
         mastershipCheck = mastershipCheck and consistentMastership
 
         main.step( "Get the intents and compare across all nodes" )
-        ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
-        ONOS2Intents = main.ONOScli2.intents( jsonFormat=True )
-        ONOS3Intents = main.ONOScli3.intents( jsonFormat=True )
-        ONOS4Intents = main.ONOScli4.intents( jsonFormat=True )
-        ONOS5Intents = main.ONOScli5.intents( jsonFormat=True )
-        ONOS6Intents = main.ONOScli6.intents( jsonFormat=True )
-        ONOS7Intents = main.ONOScli7.intents( jsonFormat=True )
+        ONOSIntents = []
         intentCheck = main.FALSE
-        if "Error" in ONOS1Intents or not ONOS1Intents\
-                or "Error" in ONOS2Intents or not ONOS2Intents\
-                or "Error" in ONOS3Intents or not ONOS3Intents\
-                or "Error" in ONOS4Intents or not ONOS4Intents\
-                or "Error" in ONOS5Intents or not ONOS5Intents\
-                or "Error" in ONOS6Intents or not ONOS6Intents\
-                or "Error" in ONOS7Intents or not ONOS7Intents:
-            main.log.report( "Error in getting ONOS intents" )
-            main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
-            main.log.warn( "ONOS2 intents response: " + repr( ONOS2Intents ) )
-            main.log.warn( "ONOS3 intents response: " + repr( ONOS3Intents ) )
-            main.log.warn( "ONOS4 intents response: " + repr( ONOS4Intents ) )
-            main.log.warn( "ONOS5 intents response: " + repr( ONOS5Intents ) )
-            main.log.warn( "ONOS6 intents response: " + repr( ONOS6Intents ) )
-            main.log.warn( "ONOS7 intents response: " + repr( ONOS7Intents ) )
-        elif ONOS1Intents == ONOS2Intents\
-                and ONOS1Intents == ONOS3Intents\
-                and ONOS1Intents == ONOS4Intents\
-                and ONOS1Intents == ONOS5Intents\
-                and ONOS1Intents == ONOS6Intents\
-                and ONOS1Intents == ONOS7Intents:
-            intentCheck = main.TRUE
-            main.log.report( "Intents are consistent across all ONOS nodes" )
-        else:
-            main.log.warn( "ONOS1 intents: " )
-            print json.dumps( json.loads( ONOS1Intents ), sort_keys=True,
-                              indent=4, separators=( ',', ': ' ) )
-            main.log.warn( "ONOS2 intents: " )
-            print json.dumps( json.loads( ONOS2Intents ), sort_keys=True,
-                              indent=4, separators=( ',', ': ' ) )
-            main.log.warn( "ONOS3 intents: " )
-            print json.dumps( json.loads( ONOS3Intents ), sort_keys=True,
-                              indent=4, separators=( ',', ': ' ) )
-            main.log.warn( "ONOS4 intents: " )
-            print json.dumps( json.loads( ONOS4Intents ), sort_keys=True,
-                              indent=4, separators=( ',', ': ' ) )
-            main.log.warn( "ONOS5 intents: " )
-            print json.dumps( json.loads( ONOS5Intents ), sort_keys=True,
-                              indent=4, separators=( ',', ': ' ) )
-            main.log.warn( "ONOS6 intents: " )
-            print json.dumps( json.loads( ONOS6Intents ), sort_keys=True,
-                              indent=4, separators=( ',', ': ' ) )
-            main.log.warn( "ONOS7 intents: " )
-            print json.dumps( json.loads( ONOS7Intents ), sort_keys=True,
-                              indent=4, separators=( ',', ': ' ) )
+        consistentIntents = True
+        intentsResults = True
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].intents,
+                             name="intents-" + str( i ),
+                             args=[],
+                             kwargs={ 'jsonFormat': True } )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            ONOSIntents.append( t.result )
+
+        for i in range( numControllers ):
+            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
+                main.log.report( "Error in getting ONOS" + str( i + 1 ) +
+                                 " intents" )
+                main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
+                               repr( ONOSIntents[ i ] ) )
+                intentsResults = False
         utilities.assert_equals(
-            expect=main.TRUE,
-            actual=intentCheck,
+            expect=True,
+            actual=intentsResults,
+            onpass="No error in reading intents output",
+            onfail="Error in reading intents from ONOS" )
+
+        main.step( "Check for consistency in Intents from each controller" )
+        if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
+            main.log.report( "Intents are consistent across all ONOS " +
+                             "nodes" )
+        else:
+            consistentIntents = False
+        utilities.assert_equals(
+            expect=True,
+            actual=consistentIntents,
             onpass="Intents are consistent across all ONOS nodes",
             onfail="ONOS nodes have different views of intents" )
-        # Print the intent states
-        intents = []
-        intents.append( ONOS1Intents )
-        intents.append( ONOS2Intents )
-        intents.append( ONOS3Intents )
-        intents.append( ONOS4Intents )
-        intents.append( ONOS5Intents )
-        intents.append( ONOS6Intents )
-        intents.append( ONOS7Intents )
         intentStates = []
-        for node in intents:  # Iter through ONOS nodes
+        for node in ONOSIntents:  # Iter through ONOS nodes
             nodeStates = []
-            for intent in json.loads( node ):  # Iter through intents of a node
-                nodeStates.append( intent[ 'state' ] )
+            # Iter through intents of a node
+            try:
+                for intent in json.loads( node ):
+                    nodeStates.append( intent[ 'state' ] )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error in parsing intents" )
+                main.log.error( repr( node ) )
             intentStates.append( nodeStates )
             out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
             main.log.info( dict( out ) )
 
+        if intentsResults and not consistentIntents:
+            for i in range( numControllers ):
+                main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
+                main.log.warn( json.dumps(
+                    json.loads( ONOSIntents[ i ] ),
+                    sort_keys=True,
+                    indent=4,
+                    separators=( ',', ': ' ) ) )
+        elif intentsResults and consistentIntents:
+            intentCheck = main.TRUE
 
-        # NOTE: Hazelcast has no durability, so intents are lost across system
-        # restarts
+        # NOTE: Store has no durability, so intents are lost across system
+        #       restarts
         """
         main.step( "Compare current intents with intents before the failure" )
         # NOTE: this requires case 5 to pass for intentState to be set.
         #      maybe we should stop the test if that fails?
         sameIntents = main.TRUE
-        if intentState and intentState == ONOS1Intents:
+        if intentState and intentState == ONOSIntents[ 0 ]:
             sameIntents = main.TRUE
             main.log.report( "Intents are consistent with before failure" )
         # TODO: possibly the states have changed? we may need to figure out
-        # what the aceptable states are
+        #       what the acceptable states are
         else:
             try:
-                main.log.warn( "ONOS1 intents: " )
-                print json.dumps( json.loads( ONOS1Intents ),
-                                  sort_keys=True, indent=4,
-                                  separators=( ',', ': ' ) )
-            except:
-                pass
+                main.log.warn( "ONOS intents: " )
+                main.log.warn( json.dumps( json.loads( ONOSIntents[ 0 ] ),
+                                           sort_keys=True, indent=4,
+                                           separators=( ',', ': ' ) ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Exception printing intents" )
+                main.log.warn( repr( ONOSIntents[0] ) )
             sameIntents = main.FALSE
         utilities.assert_equals(
             expect=main.TRUE,
@@ -1397,12 +1688,8 @@
 
         main.step( "Check the continuous pings to ensure that no packets " +
                    "were dropped during component failure" )
-        # FIXME: This check is always failing. Investigate cause
-        # NOTE:  this may be something to do with file permsissions
-        #       or slight change in format
-        main.Mininet2.pingKill(
-            main.params[ 'TESTONUSER' ],
-            main.params[ 'TESTONIP' ] )
+        main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
+                                main.params[ 'TESTONIP' ] )
         LossInPings = main.FALSE
         # NOTE: checkForLoss returns main.FALSE with 0% packet loss
         for i in range( 8, 18 ):
@@ -1424,16 +1711,15 @@
             actual=LossInPings,
             onpass="No Loss of connectivity",
             onfail="Loss of dataplane connectivity detected" )
-        # NOTE: Since intents are not persisted with Hazelcast, we expect this
+        # NOTE: Since intents are not persisted with IntnentStore,
+        #       we expect loss in dataplane connectivity
         LossInPings = main.FALSE
 
         # Test of LeadershipElection
         leaderList = []
         leaderResult = main.TRUE
-        for controller in range( 1, numControllers + 1 ):
-            # loop through ONOScli handlers
-            node = getattr( main, ( 'ONOScli' + str( controller ) ) )
-            leaderN = node.electionTestLeader()
+        for cli in CLIs:
+            leaderN = cli.electionTestLeader()
             leaderList.append( leaderN )
             if leaderN == main.FALSE:
                 # error in  response
@@ -1442,7 +1728,7 @@
                                  " error logs" )
                 leaderResult = main.FALSE
             elif leaderN is None:
-                main.log.report( "ONOS" + str( controller ) +
+                main.log.report( cli.name +
                                  " shows no leader for the election-app was" +
                                  " elected after the old one died" )
                 leaderResult = main.FALSE
@@ -1467,8 +1753,8 @@
         if result == main.TRUE:
             main.log.report( "Constant State Tests Passed" )
         utilities.assert_equals( expect=main.TRUE, actual=result,
-                                onpass="Constant State Tests Passed",
-                                onfail="Constant state tests failed" )
+                                 onpass="Constant State Tests Passed",
+                                 onfail="Constant state tests failed" )
 
     def CASE8( self, main ):
         """
@@ -1481,33 +1767,27 @@
         from sts.topology.teston_topology import TestONTopology
         import json
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
 
         description = "Compare ONOS Topology view to Mininet topology"
         main.case( description )
         main.log.report( description )
         main.step( "Create TestONTopology object" )
         ctrls = []
-        count = 1
-        while True:
-            temp = ()
-            if ( 'ip' + str( count ) ) in main.params[ 'CTRL' ]:
-                temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
-                temp = temp + ( "ONOS" + str( count ), )
-                temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
-                temp = temp + \
-                    ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
-                ctrls.append( temp )
-                count = count + 1
-            else:
-                break
-        MNTopo = TestONTopology(
-            main.Mininet1,
-            ctrls )  # can also add Intent API info for intent operations
+        for node in nodes:
+            temp = ( node, node.name, node.ip_address, 6633 )
+            ctrls.append( temp )
+        MNTopo = TestONTopology( main.Mininet1, ctrls )
 
         main.step( "Comparing ONOS topology to MN" )
         devicesResults = main.TRUE
         portsResults = main.TRUE
         linksResults = main.TRUE
+        hostsResults = main.TRUE
         topoResult = main.FALSE
         elapsed = 0
         count = 0
@@ -1515,60 +1795,84 @@
         startTime = time.time()
         # Give time for Gossip to work
         while topoResult == main.FALSE and elapsed < 60:
-            count = count + 1
+            count += 1
             if count > 1:
-                # TODO: Depricate STS usage
-                MNTopo = TestONTopology(
-                    main.Mininet1,
-                    ctrls )
+                # TODO: Deprecate STS usage
+                MNTopo = TestONTopology( main.Mininet1, ctrls )
             cliStart = time.time()
             devices = []
-            devices.append( main.ONOScli1.devices() )
-            devices.append( main.ONOScli2.devices() )
-            devices.append( main.ONOScli3.devices() )
-            devices.append( main.ONOScli4.devices() )
-            devices.append( main.ONOScli5.devices() )
-            devices.append( main.ONOScli6.devices() )
-            devices.append( main.ONOScli7.devices() )
+            threads = []
+            for i in range( numControllers ):
+                t = main.Thread( target=CLIs[i].devices,
+                                 name="devices-" + str( i ),
+                                 args=[ ] )
+                threads.append( t )
+                t.start()
+
+            for t in threads:
+                t.join()
+                devices.append( t.result )
             hosts = []
-            hosts.append( json.loads( main.ONOScli1.hosts() ) )
-            hosts.append( json.loads( main.ONOScli2.hosts() ) )
-            hosts.append( json.loads( main.ONOScli3.hosts() ) )
-            hosts.append( json.loads( main.ONOScli4.hosts() ) )
-            hosts.append( json.loads( main.ONOScli5.hosts() ) )
-            hosts.append( json.loads( main.ONOScli6.hosts() ) )
-            hosts.append( json.loads( main.ONOScli7.hosts() ) )
+            ipResult = main.TRUE
+            threads = []
+            for i in range( numControllers ):
+                t = main.Thread( target=CLIs[i].hosts,
+                                 name="hosts-" + str( i ),
+                                 args=[ ] )
+                threads.append( t )
+                t.start()
+
+            for t in threads:
+                t.join()
+                try:
+                    hosts.append( json.loads( t.result ) )
+                except ( ValueError, TypeError ):
+                    main.log.exception( "Error parsing hosts results" )
+                    main.log.error( repr( t.result ) )
             for controller in range( 0, len( hosts ) ):
                 controllerStr = str( controller + 1 )
                 for host in hosts[ controller ]:
-                    if host[ 'ips' ] == []:
+                    if host is None or host.get( 'ips', [] ) == []:
                         main.log.error(
                             "DEBUG:Error with host ips on controller" +
                             controllerStr + ": " + str( host ) )
+                        ipResult = main.FALSE
             ports = []
-            ports.append( main.ONOScli1.ports() )
-            ports.append( main.ONOScli2.ports() )
-            ports.append( main.ONOScli3.ports() )
-            ports.append( main.ONOScli4.ports() )
-            ports.append( main.ONOScli5.ports() )
-            ports.append( main.ONOScli6.ports() )
-            ports.append( main.ONOScli7.ports() )
+            threads = []
+            for i in range( numControllers ):
+                t = main.Thread( target=CLIs[i].ports,
+                                 name="ports-" + str( i ),
+                                 args=[ ] )
+                threads.append( t )
+                t.start()
+
+            for t in threads:
+                t.join()
+                ports.append( t.result )
             links = []
-            links.append( main.ONOScli1.links() )
-            links.append( main.ONOScli2.links() )
-            links.append( main.ONOScli3.links() )
-            links.append( main.ONOScli4.links() )
-            links.append( main.ONOScli5.links() )
-            links.append( main.ONOScli6.links() )
-            links.append( main.ONOScli7.links() )
+            threads = []
+            for i in range( numControllers ):
+                t = main.Thread( target=CLIs[i].links,
+                                 name="links-" + str( i ),
+                                 args=[ ] )
+                threads.append( t )
+                t.start()
+
+            for t in threads:
+                t.join()
+                links.append( t.result )
             clusters = []
-            clusters.append( main.ONOScli1.clusters() )
-            clusters.append( main.ONOScli2.clusters() )
-            clusters.append( main.ONOScli3.clusters() )
-            clusters.append( main.ONOScli4.clusters() )
-            clusters.append( main.ONOScli5.clusters() )
-            clusters.append( main.ONOScli6.clusters() )
-            clusters.append( main.ONOScli7.clusters() )
+            threads = []
+            for i in range( numControllers ):
+                t = main.Thread( target=CLIs[i].clusters,
+                                 name="clusters-" + str( i ),
+                                 args=[ ] )
+                threads.append( t )
+                t.start()
+
+            for t in threads:
+                t.join()
+                clusters.append( t.result )
 
             elapsed = time.time() - startTime
             cliTime = time.time() - cliStart
@@ -1580,47 +1884,58 @@
                         controller ]:
                     currentDevicesResult = main.Mininet1.compareSwitches(
                         MNTopo,
-                        json.loads(
-                            devices[ controller ] ) )
+                        json.loads( devices[ 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" )
+                                         actual=currentDevicesResult,
+                                         onpass="ONOS" + controllerStr +
+                                         " Switches view is correct",
+                                         onfail="ONOS" + controllerStr +
+                                         " Switches view is incorrect" )
 
                 if ports[ controller ] or "Error" not in ports[ controller ]:
                     currentPortsResult = main.Mininet1.comparePorts(
                         MNTopo,
-                        json.loads(
-                            ports[ controller ] ) )
+                        json.loads( ports[ controller ] ) )
                 else:
                     currentPortsResult = main.FALSE
                 utilities.assert_equals( expect=main.TRUE,
-                                        actual=currentPortsResult,
-                                        onpass="ONOS" + controllerStr +
-                                        " ports view is correct",
-                                        onfail="ONOS" + controllerStr +
-                                        " ports view is incorrect" )
+                                         actual=currentPortsResult,
+                                         onpass="ONOS" + controllerStr +
+                                         " ports view is correct",
+                                         onfail="ONOS" + controllerStr +
+                                         " ports view is incorrect" )
 
                 if links[ controller ] or "Error" not in links[ controller ]:
                     currentLinksResult = main.Mininet1.compareLinks(
                         MNTopo,
-                        json.loads(
-                            links[ controller ] ) )
+                        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" )
-            devicesResults = devicesResults and currentDevicesResult
-            portsResults = portsResults and currentPortsResult
-            linksResults = linksResults and currentLinksResult
+                                         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(
+                        MNTopo, 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" )
+
+                devicesResults = devicesResults and currentDevicesResult
+                portsResults = portsResults and currentPortsResult
+                linksResults = linksResults and currentLinksResult
+                hostsResults = hostsResults and currentHostsResult
 
             # Compare json objects for hosts and dataplane clusters
 
@@ -1676,18 +1991,24 @@
                 onpass="Clusters view is consistent across all ONOS nodes",
                 onfail="ONOS nodes have different views of clusters" )
             # there should always only be one cluster
-            numClusters = len( json.loads( clusters[ 0 ] ) )
+            try:
+                numClusters = len( json.loads( clusters[ 0 ] ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing clusters[0]: " +
+                                    repr( clusters[0] ) )
+            clusterResults = main.FALSE
+            if numClusters == 1:
+                clusterResults = main.TRUE
             utilities.assert_equals(
                 expect=1,
                 actual=numClusters,
                 onpass="ONOS shows 1 SCC",
-                onfail="ONOS shows " +
-                str( numClusters ) +
-                " SCCs" )
+                onfail="ONOS shows " + str( numClusters ) + " SCCs" )
 
             topoResult = ( devicesResults and portsResults and linksResults
-                           and consistentHostsResult
-                           and consistentClustersResult )
+                           and hostsResults and consistentHostsResult
+                           and consistentClustersResult and clusterResults
+                           and ipResult )
 
         topoResult = topoResult and int( count <= 2 )
         note = "note it takes about " + str( int( cliTime ) ) + \
@@ -1698,8 +2019,8 @@
             str( note ) + " ): " + str( elapsed ) + " seconds, " +
             str( count ) + " tries" )
         utilities.assert_equals( expect=main.TRUE, actual=topoResult,
-                                onpass="Topology Check Test successful",
-                                onfail="Topology Check Test NOT successful" )
+                                 onpass="Topology Check Test successful",
+                                 onfail="Topology Check Test NOT successful" )
         if topoResult == main.TRUE:
             main.log.report( "ONOS topology view matches Mininet topology" )
 
@@ -1708,25 +2029,28 @@
         Link s3-s28 down
         """
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         # NOTE: You should probably run a topology check after this
 
         linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
 
         description = "Turn off a link to ensure that Link Discovery " +\
-            "is working properly"
+                      "is working properly"
         main.log.report( description )
         main.case( description )
 
         main.step( "Kill Link between s3 and s28" )
         LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
-        main.log.info(
-            "Waiting " +
-            str( linkSleep ) +
-            " seconds for link down to be discovered" )
+        main.log.info( "Waiting " + str( linkSleep ) +
+                       " seconds for link down to be discovered" )
         time.sleep( linkSleep )
         utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
-                                onpass="Link down succesful",
-                                onfail="Failed to bring link down" )
+                                 onpass="Link down successful",
+                                 onfail="Failed to bring link down" )
         # TODO do some sort of check here
 
     def CASE10( self, main ):
@@ -1734,25 +2058,28 @@
         Link s3-s28 up
         """
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         # NOTE: You should probably run a topology check after this
 
         linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
 
         description = "Restore a link to ensure that Link Discovery is " + \
-            "working properly"
+                      "working properly"
         main.log.report( description )
         main.case( description )
 
         main.step( "Bring link between s3 and s28 back up" )
         LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
-        main.log.info(
-            "Waiting " +
-            str( linkSleep ) +
-            " seconds for link up to be discovered" )
+        main.log.info( "Waiting " + str( linkSleep ) +
+                       " seconds for link up to be discovered" )
         time.sleep( linkSleep )
         utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
-                                onpass="Link up succesful",
-                                onfail="Failed to bring link up" )
+                                 onpass="Link up successful",
+                                 onfail="Failed to bring link up" )
         # TODO do some sort of check here
 
     def CASE11( self, main ):
@@ -1761,6 +2088,11 @@
         """
         # NOTE: You should probably run a topology check after this
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
 
         switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
 
@@ -1784,8 +2116,8 @@
         if device and device[ 'available' ] is False:
             result = main.TRUE
         utilities.assert_equals( expect=main.TRUE, actual=result,
-                                onpass="Kill switch succesful",
-                                onfail="Failed to kill switch?" )
+                                 onpass="Kill switch successful",
+                                 onfail="Failed to kill switch?" )
 
     def CASE12( self, main ):
         """
@@ -1793,6 +2125,18 @@
         """
         # NOTE: You should probably run a topology check after this
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
+        assert ONOS1Port, "ONOS1Port not defined"
+        assert ONOS2Port, "ONOS2Port not defined"
+        assert ONOS3Port, "ONOS3Port not defined"
+        assert ONOS4Port, "ONOS4Port not defined"
+        assert ONOS5Port, "ONOS5Port not defined"
+        assert ONOS6Port, "ONOS6Port not defined"
+        assert ONOS7Port, "ONOS7Port not defined"
 
         switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
         switch = main.params[ 'kill' ][ 'switch' ]
@@ -1805,30 +2149,26 @@
         main.step( "Add back " + switch )
         main.log.report( "Adding back " + switch )
         main.Mininet1.addSwitch( switch, dpid=switchDPID )
-        # TODO: New dpid or same? Ask Thomas?
         for peer in links:
             main.Mininet1.addLink( switch, peer )
-        main.Mininet1.assignSwController(
-            sw=switch.split( 's' )[ 1 ],
-            count=numControllers,
-            ip1=ONOS1Ip,
-            port1=ONOS1Port,
-            ip2=ONOS2Ip,
-            port2=ONOS2Port,
-            ip3=ONOS3Ip,
-            port3=ONOS3Port,
-            ip4=ONOS4Ip,
-            port4=ONOS4Port,
-            ip5=ONOS5Ip,
-            port5=ONOS5Port,
-            ip6=ONOS6Ip,
-            port6=ONOS6Port,
-            ip7=ONOS7Ip,
-            port7=ONOS7Port )
-        main.log.info(
-            "Waiting " +
-            str( switchSleep ) +
-            " seconds for switch up to be discovered" )
+        main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
+                                          count=numControllers,
+                                          ip1=nodes[ 0 ].ip_address,
+                                          port1=ONOS1Port,
+                                          ip2=nodes[ 1 ].ip_address,
+                                          port2=ONOS2Port,
+                                          ip3=nodes[ 2 ].ip_address,
+                                          port3=ONOS3Port,
+                                          ip4=nodes[ 3 ].ip_address,
+                                          port4=ONOS4Port,
+                                          ip5=nodes[ 4 ].ip_address,
+                                          port5=ONOS5Port,
+                                          ip6=nodes[ 5 ].ip_address,
+                                          port6=ONOS6Port,
+                                          ip7=nodes[ 6 ].ip_address,
+                                          port7=ONOS7Port )
+        main.log.info( "Waiting " + str( switchSleep ) +
+                       " seconds for switch up to be discovered" )
         time.sleep( switchSleep )
         device = main.ONOScli1.getDevice( dpid=switchDPID )
         # Peek at the deleted switch
@@ -1837,8 +2177,8 @@
         if device and device[ 'available' ]:
             result = main.TRUE
         utilities.assert_equals( expect=main.TRUE, actual=result,
-                                onpass="add switch succesful",
-                                onfail="Failed to add switch?" )
+                                 onpass="add switch successful",
+                                 onfail="Failed to add switch?" )
 
     def CASE13( self, main ):
         """
@@ -1846,37 +2186,22 @@
         """
         import os
         import time
-        # TODO: make use of this elsewhere
-        ips = []
-        ips.append( ONOS1Ip )
-        ips.append( ONOS2Ip )
-        ips.append( ONOS3Ip )
-        ips.append( ONOS4Ip )
-        ips.append( ONOS5Ip )
-        ips.append( ONOS6Ip )
-        ips.append( ONOS7Ip )
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
 
         # printing colors to terminal
-        colors = {}
-        colors[ 'cyan' ] = '\033[96m'
-        colors[ 'purple' ] = '\033[95m'
-        colors[ 'blue' ] = '\033[94m'
-        colors[ 'green' ] = '\033[92m'
-        colors[ 'yellow' ] = '\033[93m'
-        colors[ 'red' ] = '\033[91m'
-        colors[ 'end' ] = '\033[0m'
+        colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
+                   'blue': '\033[94m', 'green': '\033[92m',
+                   'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
         description = "Test Cleanup"
         main.log.report( description )
         main.case( description )
         main.step( "Killing tcpdumps" )
         main.Mininet2.stopTcpdump()
 
-        main.step( "Checking ONOS Logs for errors" )
-        for i in range( 7 ):
-            print colors[ 'purple' ] + "Checking logs for errors on " + \
-                "ONOS" + str( i + 1 ) + ":" + colors[ 'end' ]
-            print main.ONOSbench.checkLogs( ips[ i ] )
-
         main.step( "Copying MN pcap and ONOS log files to test station" )
         testname = main.TEST
         teststationUser = main.params[ 'TESTONUSER' ]
@@ -1892,14 +2217,15 @@
         # NOTE: must end in /
         dstDir = "~/packet_captures/"
         for f in logFiles:
-            for i in range( 7 ):
-                main.ONOSbench.handle.sendline( "scp sdn@" + ips[ i ] + ":" +
-                                                logFolder + f + " " +
+            for node in nodes:
+                main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
+                                                ":" + logFolder + f + " " +
                                                 teststationUser + "@" +
                                                 teststationIP + ":" +
                                                 dstDir + str( testname ) +
-                                                "-ONOS" + str( i + 1 ) + "-" +
-                                                f )
+                                                "-" + node.name + "-" + f )
+                main.ONOSbench.handle.expect( "\$" )
+
         # std*.log's
         # NOTE: must end in /
         logFolder = "/opt/onos/var/"
@@ -1907,44 +2233,61 @@
         # NOTE: must end in /
         dstDir = "~/packet_captures/"
         for f in logFiles:
-            for i in range( 7 ):
-                main.ONOSbench.handle.sendline( "scp sdn@" + ips[ i ] + ":" +
-                                                logFolder + f + " " +
+            for node in nodes:
+                main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
+                                                ":" + logFolder + f + " " +
                                                 teststationUser + "@" +
                                                 teststationIP + ":" +
                                                 dstDir + str( testname ) +
-                                                "-ONOS" + str( i + 1 ) + "-" +
-                                                f )
+                                                "-" + node.name + "-" + f )
+                main.ONOSbench.handle.expect( "\$" )
         # sleep so scp can finish
         time.sleep( 10 )
+
+        main.step( "Stopping Mininet" )
+        main.Mininet1.stopNet()
+
+        main.step( "Checking ONOS Logs for errors" )
+        for node in nodes:
+            print colors[ 'purple' ] + "Checking logs for errors on " + \
+                node.name + ":" + colors[ 'end' ]
+            print main.ONOSbench.checkLogs( node.ip_address )
+
         main.step( "Packing and rotating pcap archives" )
         os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
 
         # TODO: actually check something here
         utilities.assert_equals( expect=main.TRUE, actual=main.TRUE,
-                                onpass="Test cleanup successful",
-                                onfail="Test cleanup NOT successful" )
+                                 onpass="Test cleanup successful",
+                                 onfail="Test cleanup NOT successful" )
 
     def CASE14( self, main ):
         """
         start election app on all onos nodes
         """
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
+
         leaderResult = main.TRUE
         # install app on onos 1
         main.log.info( "Install leadership election app" )
         main.ONOScli1.featureInstall( "onos-app-election" )
+        leader = nodes[0].ip_address
         # wait for election
         # check for leader
-        leader = main.ONOScli1.electionTestLeader()
+        leader1 = main.ONOScli1.electionTestLeader()
         # verify leader is ONOS1
-        if leader == ONOS1Ip:
+        if leader1 == leader:
             # all is well
             pass
-        elif leader is None:
+        elif leader1 is None:
             # No leader elected
             main.log.report( "No leader was elected" )
             leaderResult = main.FALSE
-        elif leader == main.FALSE:
+        elif leader1 == main.FALSE:
             # error in  response
             # TODO: add check for "Command not found:" in the driver, this
             # means the app isn't loaded
@@ -1955,19 +2298,16 @@
             # error in  response
             main.log.report(
                 "Unexpected response from electionTestLeader function:'" +
-                str( leader ) +
-                "'" )
+                str( leader1 ) + "'" )
             leaderResult = main.FALSE
 
         # install on other nodes and check for leader.
-        # Should be onos1 and each app should show the same leader
-        for controller in range( 2, numControllers + 1 ):
-            # loop through ONOScli handlers
-            node = getattr( main, ( 'ONOScli' + str( controller ) ) )
-            node.featureInstall( "onos-app-election" )
-            leaderN = node.electionTestLeader()
+        # Leader should be ONOS1 and each app should show the same leader
+        for cli in CLIs[ 1: ]:
+            cli.featureInstall( "onos-app-election" )
+            leaderN = cli.electionTestLeader()
             # verify leader is ONOS1
-            if leaderN == ONOS1Ip:
+            if leaderN == leader:
                 # all is well
                 pass
             elif leaderN == main.FALSE:
@@ -1980,8 +2320,7 @@
                 leaderResult = main.FALSE
             elif leader != leaderN:
                 leaderResult = main.FALSE
-                main.log.report( "ONOS" + str( controller ) + " sees " +
-                                 str( leaderN ) +
+                main.log.report( cli.name + " sees " + str( leaderN ) +
                                  " as the leader of the election app. Leader" +
                                  " should be " +
                                  str( leader ) )
@@ -1999,6 +2338,12 @@
         """
         Check that Leadership Election is still functional
         """
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
+
         leaderResult = main.TRUE
         description = "Check that Leadership Election is still functional"
         main.log.report( description )
@@ -2007,28 +2352,20 @@
         leader = main.ONOScli1.electionTestLeader()
         # TODO: do some sanity checking on leader before using it
         withdrawResult = main.FALSE
-        if leader == ONOS1Ip:
-            oldLeader = getattr( main, "ONOScli1" )
-        elif leader == ONOS2Ip:
-            oldLeader = getattr( main, "ONOScli2" )
-        elif leader == ONOS3Ip:
-            oldLeader = getattr( main, "ONOScli3" )
-        elif leader == ONOS4Ip:
-            oldLeader = getattr( main, "ONOScli4" )
-        elif leader == ONOS5Ip:
-            oldLeader = getattr( main, "ONOScli5" )
-        elif leader == ONOS6Ip:
-            oldLeader = getattr( main, "ONOScli6" )
-        elif leader == ONOS7Ip:
-            oldLeader = getattr( main, "ONOScli7" )
-        elif leader is None or leader == main.FALSE:
+        if leader is None or leader == main.FALSE:
             main.log.report(
                 "Leader for the election app should be an ONOS node," +
-                "instead got '" +
-                str( leader ) +
-                "'" )
+                "instead got '" + str( leader ) + "'" )
             leaderResult = main.FALSE
-        withdrawResult = oldLeader.electionTestWithdraw()
+            oldLeader = None
+        for i in range( len( CLIs ) ):
+            if leader == nodes[ i ].ip_address:
+                oldLeader = CLIs[ i ]
+                break
+        else:
+            main.log.error( "Leader election, could not find current leader" )
+        if oldLeader:
+            withdrawResult = oldLeader.electionTestWithdraw()
         utilities.assert_equals(
             expect=main.TRUE,
             actual=withdrawResult,
@@ -2037,23 +2374,17 @@
 
         main.step( "Make sure new leader is elected" )
         leaderList = []
-        for controller in range( 1, numControllers + 1 ):
-            # loop through ONOScli handlers
-            node = getattr( main, ( 'ONOScli' + str( controller ) ) )
-            leaderList.append( node.electionTestLeader() )
-        for leaderN in leaderList:
+        for cli in CLIs:
+            leaderN = cli.electionTestLeader()
+            leaderList.append( leaderN )
             if leaderN == leader:
-                main.log.report(
-                    "ONOS" +
-                    str( controller ) +
-                    " still sees " +
-                    str( leader ) +
-                    " as leader after they withdrew" )
+                main.log.report(  cli.name + " still sees " + str( leader ) +
+                                  " as leader after they withdrew" )
                 leaderResult = main.FALSE
             elif leaderN == main.FALSE:
                 # error in  response
                 # TODO: add check for "Command not found:" in the driver, this
-                # means the app isn't loaded
+                #       means the app isn't loaded
                 main.log.report( "Something is wrong with " +
                                  "electionTestLeader function, " +
                                  "check the error logs" )
@@ -2070,6 +2401,7 @@
             for n in range( len( leaderList ) ):
                 main.log.report( "ONOS" + str( n + 1 ) + " response: " +
                                  str( leaderList[ n ] ) )
+        leaderResult = leaderResult and consistentLeader
         if leaderResult:
             main.log.report( "Leadership election tests passed( consistent " +
                              "view of leader across listeners and a new " +
@@ -2081,9 +2413,12 @@
             onpass="Leadership election passed",
             onfail="Something went wrong with Leadership election" )
 
-        main.step(
-            "Run for election on old leader( just so everyone is in the hat )" )
-        runResult = oldLeader.electionTestRun()
+        main.step( "Run for election on old leader( just so everyone " +
+                   "is in the hat )" )
+        if oldLeader:
+            runResult = oldLeader.electionTestRun()
+        else:
+            runResult = main.FALSE
         utilities.assert_equals(
             expect=main.TRUE,
             actual=runResult,
diff --git a/TestON/tests/HATestMinorityRestart/HATestMinorityRestart.py b/TestON/tests/HATestMinorityRestart/HATestMinorityRestart.py
index de26e67..ba2b113 100644
--- a/TestON/tests/HATestMinorityRestart/HATestMinorityRestart.py
+++ b/TestON/tests/HATestMinorityRestart/HATestMinorityRestart.py
@@ -31,21 +31,25 @@
         CASE1 is to compile ONOS and push it to the test machines
 
         Startup sequence:
-        git pull
-        mvn clean install
-        onos-package
         cell <name>
         onos-verify-cell
         NOTE: temporary - onos-remove-raft-logs
+        onos-uninstall
+        start mininet
+        git pull
+        mvn clean install
+        onos-package
         onos-install -f
         onos-wait-for-start
+        start cli sessions
+        start tcpdump
         """
         main.log.report(
             "ONOS HA test: Restart minority of ONOS nodes - initialization" )
         main.case( "Setting up test environment" )
         # TODO: save all the timers and output them for plotting
 
-        # load some vairables from the params file
+        # load some variables from the params file
         PULLCODE = False
         if main.params[ 'Git' ] == 'True':
             PULLCODE = True
@@ -53,38 +57,34 @@
         cellName = main.params[ 'ENV' ][ 'cellName' ]
 
         # set global variables
-        global ONOS1Ip
         global ONOS1Port
-        global ONOS2Ip
         global ONOS2Port
-        global ONOS3Ip
         global ONOS3Port
-        global ONOS4Ip
         global ONOS4Port
-        global ONOS5Ip
         global ONOS5Port
-        global ONOS6Ip
         global ONOS6Port
-        global ONOS7Ip
         global ONOS7Port
         global numControllers
-
-        ONOS1Ip = main.params[ 'CTRL' ][ 'ip1' ]
-        ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
-        ONOS2Ip = main.params[ 'CTRL' ][ 'ip2' ]
-        ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
-        ONOS3Ip = main.params[ 'CTRL' ][ 'ip3' ]
-        ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
-        ONOS4Ip = main.params[ 'CTRL' ][ 'ip4' ]
-        ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
-        ONOS5Ip = main.params[ 'CTRL' ][ 'ip5' ]
-        ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
-        ONOS6Ip = main.params[ 'CTRL' ][ 'ip6' ]
-        ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
-        ONOS7Ip = main.params[ 'CTRL' ][ 'ip7' ]
-        ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
         numControllers = int( main.params[ 'num_controllers' ] )
 
+        # FIXME: just get controller port from params?
+        # TODO: do we really need all these?
+        ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
+        ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
+        ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
+        ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
+        ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
+        ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
+        ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
+
+        global CLIs
+        CLIs = []
+        global nodes
+        nodes = []
+        for i in range( 1, numControllers + 1 ):
+            CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
+            nodes.append( getattr( main, 'ONOS' + str( i ) ) )
+
         main.step( "Applying cell variable to environment" )
         cellResult = main.ONOSbench.setCell( cellName )
         verifyResult = main.ONOSbench.verifyCell()
@@ -92,14 +92,10 @@
         # FIXME:this is short term fix
         main.log.report( "Removing raft logs" )
         main.ONOSbench.onosRemoveRaftLogs()
+
         main.log.report( "Uninstalling ONOS" )
-        main.ONOSbench.onosUninstall( ONOS1Ip )
-        main.ONOSbench.onosUninstall( ONOS2Ip )
-        main.ONOSbench.onosUninstall( ONOS3Ip )
-        main.ONOSbench.onosUninstall( ONOS4Ip )
-        main.ONOSbench.onosUninstall( ONOS5Ip )
-        main.ONOSbench.onosUninstall( ONOS6Ip )
-        main.ONOSbench.onosUninstall( ONOS7Ip )
+        for node in nodes:
+            main.ONOSbench.onosUninstall( node.ip_address )
 
         cleanInstallResult = main.TRUE
         gitPullResult = main.TRUE
@@ -109,10 +105,11 @@
 
         main.step( "Compiling the latest version of ONOS" )
         if PULLCODE:
-            # TODO Configure branch in params
-            main.step( "Git checkout and pull master" )
+            main.step( "Git checkout and pull " + gitBranch )
             main.ONOSbench.gitCheckout( gitBranch )
             gitPullResult = main.ONOSbench.gitPull()
+            if gitPullResult == main.ERROR:
+                main.log.error( "Error pulling git branch" )
 
             main.step( "Using mvn clean & install" )
             cleanInstallResult = main.ONOSbench.cleanInstall()
@@ -125,77 +122,38 @@
         packageResult = main.ONOSbench.onosPackage()
 
         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 )
-        onos4InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                           node=ONOS4Ip )
-        onos5InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                           node=ONOS5Ip )
-        onos6InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                           node=ONOS6Ip )
-        onos7InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                           node=ONOS7Ip )
-        onosInstallResult = onos1InstallResult and onos2InstallResult\
-            and onos3InstallResult and onos4InstallResult\
-            and onos5InstallResult and onos6InstallResult\
-            and onos7InstallResult
+        onosInstallResult = main.TRUE
+        for node in nodes:
+            tmpResult = main.ONOSbench.onosInstall( options="-f",
+                                                    node=node.ip_address )
+            onosInstallResult = onosInstallResult and tmpResult
 
         main.step( "Checking if ONOS is up yet" )
-        # TODO check bundle:list?
         for i in range( 2 ):
-            onos1Isup = main.ONOSbench.isup( ONOS1Ip )
-            if not onos1Isup:
-                main.log.report( "ONOS1 didn't start!" )
-                main.ONOSbench.onosStop( ONOS1Ip )
-                main.ONOSbench.onosStart( ONOS1Ip )
-            onos2Isup = main.ONOSbench.isup( ONOS2Ip )
-            if not onos2Isup:
-                main.log.report( "ONOS2 didn't start!" )
-                main.ONOSbench.onosStop( ONOS2Ip )
-                main.ONOSbench.onosStart( ONOS2Ip )
-            onos3Isup = main.ONOSbench.isup( ONOS3Ip )
-            if not onos3Isup:
-                main.log.report( "ONOS3 didn't start!" )
-                main.ONOSbench.onosStop( ONOS3Ip )
-                main.ONOSbench.onosStart( ONOS3Ip )
-            onos4Isup = main.ONOSbench.isup( ONOS4Ip )
-            if not onos4Isup:
-                main.log.report( "ONOS4 didn't start!" )
-                main.ONOSbench.onosStop( ONOS4Ip )
-                main.ONOSbench.onosStart( ONOS4Ip )
-            onos5Isup = main.ONOSbench.isup( ONOS5Ip )
-            if not onos5Isup:
-                main.log.report( "ONOS5 didn't start!" )
-                main.ONOSbench.onosStop( ONOS5Ip )
-                main.ONOSbench.onosStart( ONOS5Ip )
-            onos6Isup = main.ONOSbench.isup( ONOS6Ip )
-            if not onos6Isup:
-                main.log.report( "ONOS6 didn't start!" )
-                main.ONOSbench.onosStop( ONOS6Ip )
-                main.ONOSbench.onosStart( ONOS6Ip )
-            onos7Isup = main.ONOSbench.isup( ONOS7Ip )
-            if not onos7Isup:
-                main.log.report( "ONOS7 didn't start!" )
-                main.ONOSbench.onosStop( ONOS7Ip )
-                main.ONOSbench.onosStart( ONOS7Ip )
-            onosIsupResult = onos1Isup and onos2Isup and onos3Isup\
-                and onos4Isup and onos5Isup and onos6Isup and onos7Isup
+            onosIsupResult = main.TRUE
+            for node in nodes:
+                started = main.ONOSbench.isup( node.ip_address )
+                if not started:
+                    main.log.report( node.name + " didn't start!" )
+                    main.ONOSbench.onosStop( node.ip_address )
+                    main.ONOSbench.onosStart( node.ip_address )
+                onosIsupResult = onosIsupResult and started
             if onosIsupResult == main.TRUE:
                 break
 
-        cliResult1 = main.ONOScli1.startOnosCli( ONOS1Ip )
-        cliResult2 = main.ONOScli2.startOnosCli( ONOS2Ip )
-        cliResult3 = main.ONOScli3.startOnosCli( ONOS3Ip )
-        cliResult4 = main.ONOScli4.startOnosCli( ONOS4Ip )
-        cliResult5 = main.ONOScli5.startOnosCli( ONOS5Ip )
-        cliResult6 = main.ONOScli6.startOnosCli( ONOS6Ip )
-        cliResult7 = main.ONOScli7.startOnosCli( ONOS7Ip )
-        cliResults = cliResult1 and cliResult2 and cliResult3 and\
-            cliResult4 and cliResult5 and cliResult6 and cliResult7
+        main.log.step( "Starting ONOS CLI sessions" )
+        cliResults = main.TRUE
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].startOnosCli,
+                             name="startOnosCli-" + str( i ),
+                             args=[nodes[i].ip_address] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            cliResults = cliResults and t.result
 
         main.step( "Start Packet Capture MN" )
         main.Mininet2.startTcpdump(
@@ -209,8 +167,8 @@
                         and onosIsupResult and cliResults )
 
         utilities.assert_equals( expect=main.TRUE, actual=case1Result,
-                                onpass="Test startup successful",
-                                onfail="Test startup NOT successful" )
+                                 onpass="Test startup successful",
+                                 onfail="Test startup NOT successful" )
 
         if case1Result == main.FALSE:
             main.cleanup()
@@ -221,40 +179,49 @@
         Assign mastership to controllers
         """
         import re
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
+        assert ONOS1Port, "ONOS1Port not defined"
+        assert ONOS2Port, "ONOS2Port not defined"
+        assert ONOS3Port, "ONOS3Port not defined"
+        assert ONOS4Port, "ONOS4Port not defined"
+        assert ONOS5Port, "ONOS5Port not defined"
+        assert ONOS6Port, "ONOS6Port not defined"
+        assert ONOS7Port, "ONOS7Port not defined"
 
         main.log.report( "Assigning switches to controllers" )
         main.case( "Assigning Controllers" )
         main.step( "Assign switches to controllers" )
 
+        # TODO: rewrite this function to take lists of ips and ports?
+        #       or list of tuples?
         for i in range( 1, 29 ):
             main.Mininet1.assignSwController(
                 sw=str( i ),
                 count=numControllers,
-                ip1=ONOS1Ip, port1=ONOS1Port,
-                ip2=ONOS2Ip, port2=ONOS2Port,
-                ip3=ONOS3Ip, port3=ONOS3Port,
-                ip4=ONOS4Ip, port4=ONOS4Port,
-                ip5=ONOS5Ip, port5=ONOS5Port,
-                ip6=ONOS6Ip, port6=ONOS6Port,
-                ip7=ONOS7Ip, port7=ONOS7Port )
+                ip1=nodes[ 0 ].ip_address, port1=ONOS1Port,
+                ip2=nodes[ 1 ].ip_address, port2=ONOS2Port,
+                ip3=nodes[ 2 ].ip_address, port3=ONOS3Port,
+                ip4=nodes[ 3 ].ip_address, port4=ONOS4Port,
+                ip5=nodes[ 4 ].ip_address, port5=ONOS5Port,
+                ip6=nodes[ 5 ].ip_address, port6=ONOS6Port,
+                ip7=nodes[ 6 ].ip_address, port7=ONOS7Port )
 
         mastershipCheck = main.TRUE
         for i in range( 1, 29 ):
             response = main.Mininet1.getSwController( "s" + str( i ) )
             try:
                 main.log.info( str( response ) )
-            except:
+            except Exception:
                 main.log.info( repr( response ) )
-            if re.search( "tcp:" + ONOS1Ip, response )\
-                    and re.search( "tcp:" + ONOS2Ip, response )\
-                    and re.search( "tcp:" + ONOS3Ip, response )\
-                    and re.search( "tcp:" + ONOS4Ip, response )\
-                    and re.search( "tcp:" + ONOS5Ip, response )\
-                    and re.search( "tcp:" + ONOS6Ip, response )\
-                    and re.search( "tcp:" + ONOS7Ip, response ):
-                mastershipCheck = mastershipCheck and main.TRUE
-            else:
-                mastershipCheck = main.FALSE
+            for node in nodes:
+                if re.search( "tcp:" + node.ip_address, response ):
+                    mastershipCheck = mastershipCheck and main.TRUE
+                else:
+                    mastershipCheck = main.FALSE
         if mastershipCheck == main.TRUE:
             main.log.report( "Switch mastership assigned correctly" )
         utilities.assert_equals(
@@ -262,122 +229,141 @@
             actual=mastershipCheck,
             onpass="Switch mastership assigned correctly",
             onfail="Switches not assigned correctly to controllers" )
-
+        #FIXME: turning off because of ONOS-1286
         # Manually assign mastership to the controller we want
         roleCall = main.TRUE
         roleCheck = main.TRUE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS1Ip )
-        # Check assignment
-        if ONOS1Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS1Ip )
-        # Check assignment
-        if ONOS1Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS2Ip )
-        # Check assignment
-        if ONOS2Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS2Ip )
-        # Check assignment
-        if ONOS2Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS3Ip )
-        # Check assignment
-        if ONOS3Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS3Ip )
-        # Check assignment
-        if ONOS3Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS4Ip )
-        # Check assignment
-        if ONOS4Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        for i in range( 8, 18 ):
-            dpid = '3' + str( i ).zfill( 3 )
-            deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+        try:
+            # Assign switch
+            ip = nodes[ 0 ].ip_address  # ONOS1
+            deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
+            assert deviceId, "No device id for s1 in ONOS"
             roleCall = roleCall and main.ONOScli1.deviceRole(
                 deviceId,
-                ONOS5Ip )
+                ip )
             # Check assignment
-            if ONOS5Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
                 roleCheck = roleCheck and main.TRUE
             else:
                 roleCheck = roleCheck and main.FALSE
 
-        deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS6Ip )
-        # Check assignment
-        if ONOS6Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        for i in range( 18, 28 ):
-            dpid = '6' + str( i ).zfill( 3 )
-            deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
+            assert deviceId, "No device id for s28 in ONOS"
             roleCall = roleCall and main.ONOScli1.deviceRole(
                 deviceId,
-                ONOS7Ip )
+                ip )
             # Check assignment
-            if ONOS7Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
                 roleCheck = roleCheck and main.TRUE
             else:
                 roleCheck = roleCheck and main.FALSE
 
+            ip = nodes[ 1 ].ip_address  # ONOS2
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
+            assert deviceId, "No device id for s2 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
+            assert deviceId, "No device id for s3 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            ip = nodes[ 2 ].ip_address  # ONOS3
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
+            assert deviceId, "No device id for s5 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
+            assert deviceId, "No device id for s6 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            ip = nodes[ 3 ].ip_address  # ONOS4
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
+            assert deviceId, "No device id for s4 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            ip = nodes[ 4 ].ip_address  # ONOS5
+            for i in range( 8, 18 ):
+                dpid = '3' + str( i ).zfill( 3 )
+                deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                assert deviceId, "No device id for s%i in ONOS" % i
+                roleCall = roleCall and main.ONOScli1.deviceRole(
+                    deviceId,
+                    ip )
+                # Check assignment
+                if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                    roleCheck = roleCheck and main.TRUE
+                else:
+                    roleCheck = roleCheck and main.FALSE
+
+            ip = nodes[ 5 ].ip_address  # ONOS6
+            deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
+            assert deviceId, "No device id for s7 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            ip = nodes[ 6 ].ip_address  # ONOS7
+            for i in range( 18, 28 ):
+                dpid = '6' + str( i ).zfill( 3 )
+                deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                assert deviceId, "No device id for s%i in ONOS" % i
+                roleCall = roleCall and main.ONOScli1.deviceRole(
+                    deviceId,
+                    ip )
+                # Check assignment
+                if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                    roleCheck = roleCheck and main.TRUE
+                else:
+                    roleCheck = roleCheck and main.FALSE
+        except ( AttributeError, AssertionError ):
+            main.log.exception( "Something is wrong with ONOS device view" )
+            main.log.info( main.ONOScli1.devices() )
         utilities.assert_equals(
             expect=main.TRUE,
             actual=roleCall,
@@ -401,6 +387,12 @@
         Assign intents
         """
         import time
+        import json
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         main.log.report( "Adding host intents" )
         main.case( "Adding host Intents" )
 
@@ -409,41 +401,55 @@
 
         # install onos-app-fwd
         main.log.info( "Install reactive forwarding app" )
-        main.ONOScli1.featureInstall( "onos-app-fwd" )
-        main.ONOScli2.featureInstall( "onos-app-fwd" )
-        main.ONOScli3.featureInstall( "onos-app-fwd" )
-        main.ONOScli4.featureInstall( "onos-app-fwd" )
-        main.ONOScli5.featureInstall( "onos-app-fwd" )
-        main.ONOScli6.featureInstall( "onos-app-fwd" )
-        main.ONOScli7.featureInstall( "onos-app-fwd" )
+        appResults = main.TRUE
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].featureInstall,
+                             name="featureInstall-" + str( i ),
+                             args=["onos-app-fwd"] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            appResults = appResults and t.result
 
         # REACTIVE FWD test
         pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall()
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=pingResult,
-            onpass="Reactive Pingall test passed",
-            onfail="Reactive Pingall failed, one or more ping pairs failed" )
-        time2 = time.time()
-        main.log.info( "Time for pingall: %2f seconds" % ( time2 - time1 ) )
+        for i in range(2):  # Retry if pingall fails first time
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall()
+            utilities.assert_equals(
+                expect=main.TRUE,
+                actual=pingResult,
+                onpass="Reactive Pingall test passed",
+                onfail="Reactive Pingall failed, one or more ping pairs failed" )
+            time2 = time.time()
+            main.log.info( "Time for pingall: %2f seconds" % ( time2 - time1 ) )
 
         # uninstall onos-app-fwd
         main.log.info( "Uninstall reactive forwarding app" )
-        main.ONOScli1.featureUninstall( "onos-app-fwd" )
-        main.ONOScli2.featureUninstall( "onos-app-fwd" )
-        main.ONOScli3.featureUninstall( "onos-app-fwd" )
-        main.ONOScli4.featureUninstall( "onos-app-fwd" )
-        main.ONOScli5.featureUninstall( "onos-app-fwd" )
-        main.ONOScli6.featureUninstall( "onos-app-fwd" )
-        main.ONOScli7.featureUninstall( "onos-app-fwd" )
-        # timeout for fwd flows
-        time.sleep( 10 )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].featureUninstall,
+                             name="featureUninstall-" + str( i ),
+                             args=["onos-app-fwd"] )
+            threads.append( t )
+            t.start()
 
-        main.step( "Add  host intents" )
+        for t in threads:
+            t.join()
+            appResults = appResults and t.result
+
+        # timeout for fwd flows
+        time.sleep( 11 )
+
+        main.step( "Add host intents" )
+        intentIds = []
         # TODO:  move the host numbers to params
+        #        Maybe look at all the paths we ping?
         intentAddResult = True
+        hostResult = main.TRUE
         for i in range( 8, 18 ):
             main.log.info( "Adding host intent between h" + str( i ) +
                            " and h" + str( i + 10 ) )
@@ -460,39 +466,226 @@
                 host1Id = host1Dict.get( 'id', None )
                 host2Id = host2Dict.get( 'id', None )
             if host1Id and host2Id:
-                #Changed onos node to test something
-                tmpResult = main.ONOScli4.addHostIntent(
-                    host1Id,
-                    host2Id )
+                nodeNum = ( i % 7 )
+                tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
+                if tmpId:
+                    main.log.info( "Added intent with id: " + tmpId )
+                    intentIds.append( tmpId )
+                else:
+                    main.log.error( "addHostIntent returned: " +
+                                     repr( tmpId ) )
             else:
-                main.log.error( "Error, getHost() failed" )
-                main.log.warn( json.dumps( json.loads( main.ONOScli1.hosts() ),
+                main.log.error( "Error, getHost() failed for h" + str( i ) +
+                                " and/or h" + str( i + 10 ) )
+                hosts = CLIs[ 0 ].hosts()
+                main.log.warn( "Hosts output: " )
+                try:
+                    main.log.warn( json.dumps( json.loads( hosts ),
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                except ( ValueError, TypeError ):
+                    main.log.warn( repr( hosts ) )
+                hostResult = main.FALSE
+        onosIds = main.ONOScli1.getAllIntentsId()
+        main.log.info( "Submitted intents: " + str( intentIds ) )
+        main.log.info( "Intents in ONOS: " + str( onosIds ) )
+        for intent in intentIds:
+            if intent in onosIds:
+                pass  # intent submitted is in onos
+            else:
+                intentAddResult = False
+        # Print the intent states
+        intents = main.ONOScli1.intents()
+        intentStates = []
+        installedCheck = True
+        main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
+        count = 0
+        try:
+            for intent in json.loads( intents ):
+                state = intent.get( 'state', None )
+                if "INSTALLED" not in state:
+                    installedCheck = False
+                intentId = intent.get( 'id', None )
+                intentStates.append( ( intentId, state ) )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing intents" )
+        # add submitted intents not in the store
+        tmplist = [ i for i, s in intentStates ]
+        missingIntents = False
+        for i in intentIds:
+            if i not in tmplist:
+                intentStates.append( ( i, " - " ) )
+                missingIntents = True
+        intentStates.sort()
+        for i, s in intentStates:
+            count += 1
+            main.log.info( "%-6s%-15s%-15s" %
+                           ( str( count ), str( i ), str( s ) ) )
+        leaders = main.ONOScli1.leaders()
+        try:
+            if leaders:
+                parsedLeaders = json.loads( leaders )
+                main.log.warn( json.dumps( parsedLeaders,
                                            sort_keys=True,
                                            indent=4,
                                            separators=( ',', ': ' ) ) )
-                tmpResult = main.FALSE
-            intentAddResult = bool( pingResult and intentAddResult
-                                     and tmpResult )
-            # TODO Check that intents were added?
-        # Print the intent states
-        intents = main.ONOScli1.intents( )
-        intentStates = []
-        for intent in json.loads( intents ):  # Iter through intents of a node
-            intentStates.append( intent.get( 'state', None ) )
-        out = [ (i, intentStates.count( i ) ) for i in set( intentStates ) ]
-        main.log.info( dict( out ) )
+                # check for all intent partitions
+                # check for election
+                topics = []
+                for i in range( 14 ):
+                    topics.append( "intent-partition-" + str( i ) )
+                # FIXME: this should only be after we start the app
+                topics.append( "org.onosproject.election" )
+                main.log.debug( topics )
+                ONOStopics = [ j['topic'] for j in parsedLeaders ]
+                for topic in topics:
+                    if topic not in ONOStopics:
+                        main.log.error( "Error: " + topic +
+                                        " not in leaders" )
+            else:
+                main.log.error( "leaders() returned None" )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing leaders" )
+            main.log.error( repr( leaders ) )
+        partitions = main.ONOScli1.partitions()
+        try:
+            if partitions :
+                parsedPartitions = json.loads( partitions )
+                main.log.warn( json.dumps( parsedPartitions,
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+                # TODO check for a leader in all paritions
+                # TODO check for consistency among nodes
+            else:
+                main.log.error( "partitions() returned None" )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing partitions" )
+            main.log.error( repr( partitions ) )
+        pendingMap = main.ONOScli1.pendingMap()
+        try:
+            if pendingMap :
+                parsedPending = json.loads( pendingMap )
+                main.log.warn( json.dumps( parsedPending,
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+                # TODO check something here?
+            else:
+                main.log.error( "pendingMap() returned None" )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing pending map" )
+            main.log.error( repr( pendingMap ) )
 
+        intentAddResult = bool( pingResult and hostResult and intentAddResult
+                                and not missingIntents and installedCheck )
         utilities.assert_equals(
             expect=True,
             actual=intentAddResult,
             onpass="Pushed host intents to ONOS",
             onfail="Error in pushing host intents to ONOS" )
-        # TODO Check if intents all exist in datastore
+
+        if not intentAddResult or "key" in pendingMap:
+            import time
+            installedCheck = True
+            main.log.info( "Sleeping 60 seconds to see if intents are found" )
+            time.sleep( 60 )
+            onosIds = main.ONOScli1.getAllIntentsId()
+            main.log.info( "Submitted intents: " + str( intentIds ) )
+            main.log.info( "Intents in ONOS: " + str( onosIds ) )
+            # Print the intent states
+            intents = main.ONOScli1.intents()
+            intentStates = []
+            main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
+            count = 0
+            try:
+                for intent in json.loads( intents ):
+                    # Iter through intents of a node
+                    state = intent.get( 'state', None )
+                    if "INSTALLED" not in state:
+                        installedCheck = False
+                    intentId = intent.get( 'id', None )
+                    intentStates.append( ( intentId, state ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing intents" )
+            # add submitted intents not in the store
+            tmplist = [ i for i, s in intentStates ]
+            for i in intentIds:
+                if i not in tmplist:
+                    intentStates.append( ( i, " - " ) )
+            intentStates.sort()
+            for i, s in intentStates:
+                count += 1
+                main.log.info( "%-6s%-15s%-15s" %
+                               ( str( count ), str( i ), str( s ) ) )
+            leaders = main.ONOScli1.leaders()
+            try:
+                if leaders:
+                    parsedLeaders = json.loads( leaders )
+                    main.log.warn( json.dumps( parsedLeaders,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # check for all intent partitions
+                    # check for election
+                    topics = []
+                    for i in range( 14 ):
+                        topics.append( "intent-partition-" + str( i ) )
+                    # FIXME: this should only be after we start the app
+                    topics.append( "org.onosproject.election" )
+                    main.log.debug( topics )
+                    ONOStopics = [ j['topic'] for j in parsedLeaders ]
+                    for topic in topics:
+                        if topic not in ONOStopics:
+                            main.log.error( "Error: " + topic +
+                                            " not in leaders" )
+                else:
+                    main.log.error( "leaders() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing leaders" )
+                main.log.error( repr( leaders ) )
+            partitions = main.ONOScli1.partitions()
+            try:
+                if partitions :
+                    parsedPartitions = json.loads( partitions )
+                    main.log.warn( json.dumps( parsedPartitions,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check for a leader in all paritions
+                    # TODO check for consistency among nodes
+                else:
+                    main.log.error( "partitions() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing partitions" )
+                main.log.error( repr( partitions ) )
+            pendingMap = main.ONOScli1.pendingMap()
+            try:
+                if pendingMap :
+                    parsedPending = json.loads( pendingMap )
+                    main.log.warn( json.dumps( parsedPending,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check something here?
+                else:
+                    main.log.error( "pendingMap() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing pending map" )
+                main.log.error( repr( pendingMap ) )
 
     def CASE4( self, main ):
         """
         Ping across added host intents
         """
+        import json
+        import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         description = " Ping across added host intents"
         main.log.report( description )
         main.case( description )
@@ -510,12 +703,16 @@
         if PingResult == main.FALSE:
             main.log.report(
                 "Intents have not been installed correctly, pings failed." )
-            #TODO: pretty print
-            main.log.warn( "ONSO1 intents: " )
-            main.log.warn( json.dumps( json.loads( main.ONOScli1.intents() ),
-                                       sort_keys=True,
-                                       indent=4,
-                                       separators=( ',', ': ' ) ) )
+            # TODO: pretty print
+            main.log.warn( "ONOS1 intents: " )
+            try:
+                tmpIntents = main.ONOScli1.intents()
+                main.log.warn( json.dumps( json.loads( tmpIntents ),
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+            except ( ValueError, TypeError ):
+                main.log.warn( repr( tmpIntents ) )
         if PingResult == main.TRUE:
             main.log.report(
                 "Intents have been installed correctly and verified by pings" )
@@ -525,11 +722,175 @@
             onpass="Intents have been installed correctly and pings work",
             onfail="Intents have not been installed correctly, pings failed." )
 
+        installedCheck = True
+        if PingResult is not main.TRUE:
+            # Print the intent states
+            intents = main.ONOScli1.intents()
+            intentStates = []
+            main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
+            count = 0
+            # Iter through intents of a node
+            try:
+                for intent in json.loads( intents ):
+                    state = intent.get( 'state', None )
+                    if "INSTALLED" not in state:
+                        installedCheck = False
+                    intentId = intent.get( 'id', None )
+                    intentStates.append( ( intentId, state ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing intents." )
+            intentStates.sort()
+            for i, s in intentStates:
+                count += 1
+                main.log.info( "%-6s%-15s%-15s" %
+                               ( str( count ), str( i ), str( s ) ) )
+            leaders = main.ONOScli1.leaders()
+            try:
+                if leaders:
+                    parsedLeaders = json.loads( leaders )
+                    main.log.warn( json.dumps( parsedLeaders,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # check for all intent partitions
+                    # check for election
+                    topics = []
+                    for i in range( 14 ):
+                        topics.append( "intent-partition-" + str( i ) )
+                    # FIXME: this should only be after we start the app
+                    topics.append( "org.onosproject.election" )
+                    main.log.debug( topics )
+                    ONOStopics = [ j['topic'] for j in parsedLeaders ]
+                    for topic in topics:
+                        if topic not in ONOStopics:
+                            main.log.error( "Error: " + topic +
+                                            " not in leaders" )
+                else:
+                    main.log.error( "leaders() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing leaders" )
+                main.log.error( repr( leaders ) )
+            partitions = main.ONOScli1.partitions()
+            try:
+                if partitions :
+                    parsedPartitions = json.loads( partitions )
+                    main.log.warn( json.dumps( parsedPartitions,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check for a leader in all paritions
+                    # TODO check for consistency among nodes
+                else:
+                    main.log.error( "partitions() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing partitions" )
+                main.log.error( repr( partitions ) )
+            pendingMap = main.ONOScli1.pendingMap()
+            try:
+                if pendingMap :
+                    parsedPending = json.loads( pendingMap )
+                    main.log.warn( json.dumps( parsedPending,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check something here?
+                else:
+                    main.log.error( "pendingMap() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing pending map" )
+                main.log.error( repr( pendingMap ) )
+
+        if not installedCheck:
+            main.log.info( "Waiting 60 seconds to see if the state of " +
+                           "intents change" )
+            time.sleep( 60 )
+            # Print the intent states
+            intents = main.ONOScli1.intents()
+            intentStates = []
+            main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
+            count = 0
+            # Iter through intents of a node
+            try:
+                for intent in json.loads( intents ):
+                    state = intent.get( 'state', None )
+                    if "INSTALLED" not in state:
+                        installedCheck = False
+                    intentId = intent.get( 'id', None )
+                    intentStates.append( ( intentId, state ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing intents." )
+            intentStates.sort()
+            for i, s in intentStates:
+                count += 1
+                main.log.info( "%-6s%-15s%-15s" %
+                               ( str( count ), str( i ), str( s ) ) )
+            leaders = main.ONOScli1.leaders()
+            try:
+                if leaders:
+                    parsedLeaders = json.loads( leaders )
+                    main.log.warn( json.dumps( parsedLeaders,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # check for all intent partitions
+                    # check for election
+                    topics = []
+                    for i in range( 14 ):
+                        topics.append( "intent-partition-" + str( i ) )
+                    # FIXME: this should only be after we start the app
+                    topics.append( "org.onosproject.election" )
+                    main.log.debug( topics )
+                    ONOStopics = [ j['topic'] for j in parsedLeaders ]
+                    for topic in topics:
+                        if topic not in ONOStopics:
+                            main.log.error( "Error: " + topic +
+                                            " not in leaders" )
+                else:
+                    main.log.error( "leaders() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing leaders" )
+                main.log.error( repr( leaders ) )
+            partitions = main.ONOScli1.partitions()
+            try:
+                if partitions :
+                    parsedPartitions = json.loads( partitions )
+                    main.log.warn( json.dumps( parsedPartitions,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check for a leader in all paritions
+                    # TODO check for consistency among nodes
+                else:
+                    main.log.error( "partitions() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing partitions" )
+                main.log.error( repr( partitions ) )
+            pendingMap = main.ONOScli1.pendingMap()
+            try:
+                if pendingMap :
+                    parsedPending = json.loads( pendingMap )
+                    main.log.warn( json.dumps( parsedPending,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check something here?
+                else:
+                    main.log.error( "pendingMap() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing pending map" )
+                main.log.error( repr( pendingMap ) )
+
     def CASE5( self, main ):
         """
         Reading state of ONOS
         """
         import json
+        import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         # assumes that sts is already in you PYTHONPATH
         from sts.topology.teston_topology import TestONTopology
 
@@ -537,330 +898,239 @@
         main.case( "Setting up and gathering data for current state" )
         # The general idea for this test case is to pull the state of
         # ( intents,flows, topology,... ) from each ONOS node
-        # We can then compare them with eachother and also with past states
+        # We can then compare them with each other and also with past states
 
-        main.step( "Get the Mastership of each switch from each controller" )
+        main.step( "Check that each switch has a master" )
         global mastershipState
-        mastershipState = []
+        mastershipState = '[]'
 
         # Assert that each device has a master
-        ONOS1MasterNotNull = main.ONOScli1.rolesNotNull()
-        ONOS2MasterNotNull = main.ONOScli2.rolesNotNull()
-        ONOS3MasterNotNull = main.ONOScli3.rolesNotNull()
-        ONOS4MasterNotNull = main.ONOScli4.rolesNotNull()
-        ONOS5MasterNotNull = main.ONOScli5.rolesNotNull()
-        ONOS6MasterNotNull = main.ONOScli6.rolesNotNull()
-        ONOS7MasterNotNull = main.ONOScli7.rolesNotNull()
-        rolesNotNull = ONOS1MasterNotNull and ONOS2MasterNotNull and\
-            ONOS3MasterNotNull and ONOS4MasterNotNull and\
-            ONOS5MasterNotNull and ONOS6MasterNotNull and\
-            ONOS7MasterNotNull
+        rolesNotNull = main.TRUE
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].rolesNotNull,
+                             name="rolesNotNull-" + str( i ),
+                             args=[] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            rolesNotNull = rolesNotNull and t.result
         utilities.assert_equals(
             expect=main.TRUE,
             actual=rolesNotNull,
             onpass="Each device has a master",
             onfail="Some devices don't have a master assigned" )
 
-        ONOS1Mastership = main.ONOScli1.roles()
-        ONOS2Mastership = main.ONOScli2.roles()
-        ONOS3Mastership = main.ONOScli3.roles()
-        ONOS4Mastership = main.ONOScli4.roles()
-        ONOS5Mastership = main.ONOScli5.roles()
-        ONOS6Mastership = main.ONOScli6.roles()
-        ONOS7Mastership = main.ONOScli7.roles()
-        if "Error" in ONOS1Mastership or not ONOS1Mastership\
-                or "Error" in ONOS2Mastership or not ONOS2Mastership\
-                or "Error" in ONOS3Mastership or not ONOS3Mastership\
-                or "Error" in ONOS4Mastership or not ONOS4Mastership\
-                or "Error" in ONOS5Mastership or not ONOS5Mastership\
-                or "Error" in ONOS6Mastership or not ONOS6Mastership\
-                or "Error" in ONOS7Mastership or not ONOS7Mastership:
-            main.log.report( "Error in getting ONOS roles" )
-            main.log.warn(
-                "ONOS1 mastership response: " +
-                repr( ONOS1Mastership ) )
-            main.log.warn(
-                "ONOS2 mastership response: " +
-                repr( ONOS2Mastership ) )
-            main.log.warn(
-                "ONOS3 mastership response: " +
-                repr( ONOS3Mastership ) )
-            main.log.warn(
-                "ONOS4 mastership response: " +
-                repr( ONOS4Mastership ) )
-            main.log.warn(
-                "ONOS5 mastership response: " +
-                repr( ONOS5Mastership ) )
-            main.log.warn(
-                "ONOS6 mastership response: " +
-                repr( ONOS6Mastership ) )
-            main.log.warn(
-                "ONOS7 mastership response: " +
-                repr( ONOS7Mastership ) )
-            consistentMastership = main.FALSE
-        elif ONOS1Mastership == ONOS2Mastership\
-                and ONOS1Mastership == ONOS3Mastership\
-                and ONOS1Mastership == ONOS4Mastership\
-                and ONOS1Mastership == ONOS5Mastership\
-                and ONOS1Mastership == ONOS6Mastership\
-                and ONOS1Mastership == ONOS7Mastership:
-            mastershipState = ONOS1Mastership
-            consistentMastership = main.TRUE
+        main.step( "Get the Mastership of each switch from each controller" )
+        ONOSMastership = []
+        mastershipCheck = main.FALSE
+        consistentMastership = True
+        rolesResults = True
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].roles,
+                             name="roles-" + str( i ),
+                             args=[] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            ONOSMastership.append( t.result )
+
+        for i in range( numControllers ):
+            if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
+                main.log.report( "Error in getting ONOS" + str( i + 1 ) +
+                                 " roles" )
+                main.log.warn(
+                    "ONOS" + str( i + 1 ) + " mastership response: " +
+                    repr( ONOSMastership[i] ) )
+                rolesResults = False
+        utilities.assert_equals(
+            expect=True,
+            actual=rolesResults,
+            onpass="No error in reading roles output",
+            onfail="Error in reading roles from ONOS" )
+
+        main.step( "Check for consistency in roles from each controller" )
+        if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
             main.log.report(
                 "Switch roles are consistent across all ONOS nodes" )
         else:
-            main.log.warn(
-                "ONOS1 roles: ",
-                json.dumps(
-                    json.loads( ONOS1Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS2 roles: ",
-                json.dumps(
-                    json.loads( ONOS2Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS3 roles: ",
-                json.dumps(
-                    json.loads( ONOS3Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS4 roles: ",
-                json.dumps(
-                    json.loads( ONOS4Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS5 roles: ",
-                json.dumps(
-                    json.loads( ONOS5Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS6 roles: ",
-                json.dumps(
-                    json.loads( ONOS6Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS7 roles: ",
-                json.dumps(
-                    json.loads( ONOS7Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            consistentMastership = main.FALSE
+            consistentMastership = False
         utilities.assert_equals(
-            expect=main.TRUE,
+            expect=True,
             actual=consistentMastership,
             onpass="Switch roles are consistent across all ONOS nodes",
             onfail="ONOS nodes have different views of switch roles" )
 
+        if rolesResults and not consistentMastership:
+            for i in range( numControllers ):
+                try:
+                    main.log.warn(
+                        "ONOS" + str( i + 1 ) + " roles: ",
+                        json.dumps(
+                            json.loads( ONOSMastership[ i ] ),
+                            sort_keys=True,
+                            indent=4,
+                            separators=( ',', ': ' ) ) )
+                except ( ValueError, TypeError ):
+                    main.log.warn( repr( ONOSMastership[ i ] ) )
+        elif rolesResults and consistentMastership:
+            mastershipCheck = main.TRUE
+            mastershipState = ONOSMastership[ 0 ]
+
         main.step( "Get the intents from each controller" )
         global intentState
         intentState = []
-        ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
-        ONOS2Intents = main.ONOScli2.intents( jsonFormat=True )
-        ONOS3Intents = main.ONOScli3.intents( jsonFormat=True )
-        ONOS4Intents = main.ONOScli4.intents( jsonFormat=True )
-        ONOS5Intents = main.ONOScli5.intents( jsonFormat=True )
-        ONOS6Intents = main.ONOScli6.intents( jsonFormat=True )
-        ONOS7Intents = main.ONOScli7.intents( jsonFormat=True )
+        ONOSIntents = []
         intentCheck = main.FALSE
-        if "Error" in ONOS1Intents or not ONOS1Intents\
-                or "Error" in ONOS2Intents or not ONOS2Intents\
-                or "Error" in ONOS3Intents or not ONOS3Intents\
-                or "Error" in ONOS4Intents or not ONOS4Intents\
-                or "Error" in ONOS5Intents or not ONOS5Intents\
-                or "Error" in ONOS6Intents or not ONOS6Intents\
-                or "Error" in ONOS7Intents or not ONOS7Intents:
-            main.log.report( "Error in getting ONOS intents" )
-            main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
-            main.log.warn( "ONOS2 intents response: " + repr( ONOS2Intents ) )
-            main.log.warn( "ONOS3 intents response: " + repr( ONOS3Intents ) )
-            main.log.warn( "ONOS4 intents response: " + repr( ONOS4Intents ) )
-            main.log.warn( "ONOS5 intents response: " + repr( ONOS5Intents ) )
-            main.log.warn( "ONOS6 intents response: " + repr( ONOS6Intents ) )
-            main.log.warn( "ONOS7 intents response: " + repr( ONOS7Intents ) )
-        elif ONOS1Intents == ONOS2Intents\
-                and ONOS1Intents == ONOS3Intents\
-                and ONOS1Intents == ONOS4Intents\
-                and ONOS1Intents == ONOS5Intents\
-                and ONOS1Intents == ONOS6Intents\
-                and ONOS1Intents == ONOS7Intents:
-            intentState = ONOS1Intents
-            intentCheck = main.TRUE
-            main.log.report( "Intents are consistent across all ONOS nodes" )
-        else:
-            main.log.warn(
-                "ONOS1 intents: ",
-                json.dumps(
-                    json.loads( ONOS1Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS2 intents: ",
-                json.dumps(
-                    json.loads( ONOS2Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS3 intents: ",
-                json.dumps(
-                    json.loads( ONOS3Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS4 intents: ",
-                json.dumps(
-                    json.loads( ONOS4Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS5 intents: ",
-                json.dumps(
-                    json.loads( ONOS5Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS6 intents: ",
-                json.dumps(
-                    json.loads( ONOS6Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS7 intents: ",
-                json.dumps(
-                    json.loads( ONOS7Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
+        consistentIntents = True
+        intentsResults = True
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].intents,
+                             name="intents-" + str( i ),
+                             args=[],
+                             kwargs={ 'jsonFormat': True } )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            ONOSIntents.append( t.result )
+
+        for i in range( numControllers ):
+            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
+                main.log.report( "Error in getting ONOS" + str( i + 1 ) +
+                                 " intents" )
+                main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
+                               repr( ONOSIntents[ i ] ) )
+                intentsResults = False
         utilities.assert_equals(
-            expect=main.TRUE,
-            actual=intentCheck,
+            expect=True,
+            actual=intentsResults,
+            onpass="No error in reading intents output",
+            onfail="Error in reading intents from ONOS" )
+
+        main.step( "Check for consistency in Intents from each controller" )
+        if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
+            main.log.report( "Intents are consistent across all ONOS " +
+                             "nodes" )
+        else:
+            consistentIntents = False
+            main.log.report( "Intents not consistent" )
+        utilities.assert_equals(
+            expect=True,
+            actual=consistentIntents,
             onpass="Intents are consistent across all ONOS nodes",
             onfail="ONOS nodes have different views of intents" )
 
+        if intentsResults and not consistentIntents:
+            n = len(ONOSIntents)
+            main.log.warn( "ONOS" + str( n ) + " intents: " )
+            main.log.warn( json.dumps( json.loads( ONOSIntents[ -1 ] ),
+                                       sort_keys=True,
+                                       indent=4,
+                                       separators=( ',', ': ' ) ) )
+            for i in range( numControllers ):
+                if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
+                    main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
+                    main.log.warn( json.dumps( json.loads( ONOSIntents[i] ),
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                else:
+                    main.log.warn( nodes[ i ].name + " intents match ONOS" +
+                                   str( n ) + " intents" )
+        elif intentsResults and consistentIntents:
+            intentCheck = main.TRUE
+            intentState = ONOSIntents[ 0 ]
+
         main.step( "Get the flows from each controller" )
         global flowState
         flowState = []
-        ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
-        ONOS2Flows = main.ONOScli2.flows( jsonFormat=True )
-        ONOS3Flows = main.ONOScli3.flows( jsonFormat=True )
-        ONOS4Flows = main.ONOScli4.flows( jsonFormat=True )
-        ONOS5Flows = main.ONOScli5.flows( jsonFormat=True )
-        ONOS6Flows = main.ONOScli6.flows( jsonFormat=True )
-        ONOS7Flows = main.ONOScli7.flows( jsonFormat=True )
-        ONOS1FlowsJson = json.loads( ONOS1Flows )
-        ONOS2FlowsJson = json.loads( ONOS2Flows )
-        ONOS3FlowsJson = json.loads( ONOS3Flows )
-        ONOS4FlowsJson = json.loads( ONOS4Flows )
-        ONOS5FlowsJson = json.loads( ONOS5Flows )
-        ONOS6FlowsJson = json.loads( ONOS6Flows )
-        ONOS7FlowsJson = json.loads( ONOS7Flows )
+        ONOSFlows = []
+        ONOSFlowsJson = []
         flowCheck = main.FALSE
-        if "Error" in ONOS1Flows or not ONOS1Flows\
-                or "Error" in ONOS2Flows or not ONOS2Flows\
-                or "Error" in ONOS3Flows or not ONOS3Flows\
-                or "Error" in ONOS4Flows or not ONOS4Flows\
-                or "Error" in ONOS5Flows or not ONOS5Flows\
-                or "Error" in ONOS6Flows or not ONOS6Flows\
-                or "Error" in ONOS7Flows or not ONOS7Flows:
-            main.log.report( "Error in getting ONOS intents" )
-            main.log.warn( "ONOS1 flows repsponse: " + ONOS1Flows )
-            main.log.warn( "ONOS2 flows repsponse: " + ONOS2Flows )
-            main.log.warn( "ONOS3 flows repsponse: " + ONOS3Flows )
-            main.log.warn( "ONOS4 flows repsponse: " + ONOS4Flows )
-            main.log.warn( "ONOS5 flows repsponse: " + ONOS5Flows )
-            main.log.warn( "ONOS6 flows repsponse: " + ONOS6Flows )
-            main.log.warn( "ONOS7 flows repsponse: " + ONOS7Flows )
-        elif len( ONOS1FlowsJson ) == len( ONOS2FlowsJson )\
-                and len( ONOS1FlowsJson ) == len( ONOS3FlowsJson )\
-                and len( ONOS1FlowsJson ) == len( ONOS4FlowsJson )\
-                and len( ONOS1FlowsJson ) == len( ONOS5FlowsJson )\
-                and len( ONOS1FlowsJson ) == len( ONOS6FlowsJson )\
-                and len( ONOS1FlowsJson ) == len( ONOS7FlowsJson ):
-                # TODO: Do a better check, maybe compare flows on switches?
-            flowState = ONOS1Flows
-            flowCheck = main.TRUE
+        consistentFlows = True
+        flowsResults = True
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].flows,
+                             name="flows-" + str( i ),
+                             args=[],
+                             kwargs={ 'jsonFormat': True } )
+            threads.append( t )
+            t.start()
+
+        time.sleep(30)
+        for t in threads:
+            t.join()
+            result = t.result
+            ONOSFlows.append( result )
+
+        for i in range( numControllers ):
+            num = str( i + 1 )
+            if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
+                main.log.report( "Error in getting ONOS" + num + " flows" )
+                main.log.warn( "ONOS" + num + " flows response: " +
+                               repr( ONOSFlows[ i ] ) )
+                flowsResults = False
+                ONOSFlowsJson.append( None )
+            else:
+                try:
+                    ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
+                except ( ValueError, TypeError ):
+                    # FIXME: change this to log.error?
+                    main.log.exception( "Error in parsing ONOS" + num +
+                                        " response as json." )
+                    main.log.error( repr( ONOSFlows[ i ] ) )
+                    ONOSFlowsJson.append( None )
+                    flowsResults = False
+        utilities.assert_equals(
+            expect=True,
+            actual=flowsResults,
+            onpass="No error in reading flows output",
+            onfail="Error in reading flows from ONOS" )
+
+        main.step( "Check for consistency in Flows from each controller" )
+        tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
+        if all( tmp ):
             main.log.report( "Flow count is consistent across all ONOS nodes" )
         else:
-            main.log.warn( "ONOS1 flows: " +
-                           json.dumps( ONOS1FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS2 flows: " +
-                           json.dumps( ONOS2FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS3 flows: " +
-                           json.dumps( ONOS3FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS4 flows: " +
-                           json.dumps( ONOS4FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS5 flows: " +
-                           json.dumps( ONOS5FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS6 flows: " +
-                           json.dumps( ONOS6FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS7 flows: " +
-                           json.dumps( ONOS7FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
+            consistentFlows = False
         utilities.assert_equals(
-            expect=main.TRUE,
-            actual=flowCheck,
+            expect=True,
+            actual=consistentFlows,
             onpass="The flow count is consistent across all ONOS nodes",
             onfail="ONOS nodes have different flow counts" )
 
+        if flowsResults and not consistentFlows:
+            for i in range( numControllers ):
+                try:
+                    main.log.warn(
+                        "ONOS" + str( i + 1 ) + " flows: " +
+                        json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
+                                    indent=4, separators=( ',', ': ' ) ) )
+                except ( ValueError, TypeError ):
+                    main.log.warn(
+                        "ONOS" + str( i + 1 ) + " flows: " +
+                        repr( ONOSFlows[ i ] ) )
+        elif flowsResults and consistentFlows:
+            flowCheck = main.TRUE
+            flowState = ONOSFlows[ 0 ]
+
         main.step( "Get the OF Table entries" )
         global flows
         flows = []
         for i in range( 1, 29 ):
             flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
-
+        if flowCheck == main.FALSE:
+            for table in flows:
+                main.log.warn( table )
         # TODO: Compare switch flow tables with ONOS flow tables
 
         main.step( "Start continuous pings" )
@@ -907,64 +1177,80 @@
 
         main.step( "Create TestONTopology object" )
         ctrls = []
-        count = 1
-        while True:
-            temp = ()
-            if ( 'ip' + str( count ) ) in main.params[ 'CTRL' ]:
-                temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
-                temp = temp + ( "ONOS" + str( count ), )
-                temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
-                temp = temp + \
-                    ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
-                ctrls.append( temp )
-                count = count + 1
-            else:
-                break
-        MNTopo = TestONTopology(
-            main.Mininet1,
-            ctrls )  # can also add Intent API info for intent operations
+        for node in nodes:
+            temp = ( node, node.name, node.ip_address, 6633 )
+            ctrls.append( temp )
+        MNTopo = TestONTopology( main.Mininet1, ctrls )
 
         main.step( "Collecting topology information from ONOS" )
         devices = []
-        devices.append( main.ONOScli1.devices() )
-        devices.append( main.ONOScli2.devices() )
-        devices.append( main.ONOScli3.devices() )
-        devices.append( main.ONOScli4.devices() )
-        devices.append( main.ONOScli5.devices() )
-        devices.append( main.ONOScli6.devices() )
-        devices.append( main.ONOScli7.devices() )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].devices,
+                             name="devices-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            devices.append( t.result )
         hosts = []
-        hosts.append( main.ONOScli1.hosts() )
-        hosts.append( main.ONOScli2.hosts() )
-        hosts.append( main.ONOScli3.hosts() )
-        hosts.append( main.ONOScli4.hosts() )
-        hosts.append( main.ONOScli5.hosts() )
-        hosts.append( main.ONOScli6.hosts() )
-        hosts.append( main.ONOScli7.hosts() )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].hosts,
+                             name="hosts-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            try:
+                hosts.append( json.loads( t.result ) )
+            except ( ValueError, TypeError ):
+                # FIXME: better handling of this, print which node
+                #        Maybe use thread name?
+                main.log.exception( "Error parsing json output of hosts" )
+                # FIXME: should this be an empty json object instead?
+                hosts.append( None )
+
         ports = []
-        ports.append( main.ONOScli1.ports() )
-        ports.append( main.ONOScli2.ports() )
-        ports.append( main.ONOScli3.ports() )
-        ports.append( main.ONOScli4.ports() )
-        ports.append( main.ONOScli5.ports() )
-        ports.append( main.ONOScli6.ports() )
-        ports.append( main.ONOScli7.ports() )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].ports,
+                             name="ports-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            ports.append( t.result )
         links = []
-        links.append( main.ONOScli1.links() )
-        links.append( main.ONOScli2.links() )
-        links.append( main.ONOScli3.links() )
-        links.append( main.ONOScli4.links() )
-        links.append( main.ONOScli5.links() )
-        links.append( main.ONOScli6.links() )
-        links.append( main.ONOScli7.links() )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].links,
+                             name="links-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            links.append( t.result )
         clusters = []
-        clusters.append( main.ONOScli1.clusters() )
-        clusters.append( main.ONOScli2.clusters() )
-        clusters.append( main.ONOScli3.clusters() )
-        clusters.append( main.ONOScli4.clusters() )
-        clusters.append( main.ONOScli5.clusters() )
-        clusters.append( main.ONOScli6.clusters() )
-        clusters.append( main.ONOScli7.clusters() )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].clusters,
+                             name="clusters-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            clusters.append( t.result )
         # Compare json objects for hosts and dataplane clusters
 
         # hosts
@@ -994,15 +1280,29 @@
             onpass="Hosts view is consistent across all ONOS nodes",
             onfail="ONOS nodes have different views of hosts" )
 
+        ipResult = main.TRUE
+        for controller in range( 0, len( hosts ) ):
+            controllerStr = str( controller + 1 )
+            for host in hosts[ controller ]:
+                if not host.get( 'ips', [ ] ):
+                    main.log.error( "DEBUG:Error with host ips on controller" +
+                                    controllerStr + ": " + str( host ) )
+                    ipResult = main.FALSE
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=ipResult,
+            onpass="The ips of the hosts aren't empty",
+            onfail="The ip of at least one host is missing" )
+
         # Strongly connected clusters of devices
         consistentClustersResult = main.TRUE
         for controller in range( len( clusters ) ):
+            controllerStr = str( controller + 1 )
             if "Error" not in clusters[ controller ]:
                 if clusters[ controller ] == clusters[ 0 ]:
                     continue
                 else:  # clusters not consistent
-                    main.log.report( "clusters from ONOS" +
-                                     controllerStr +
+                    main.log.report( "clusters from ONOS" + controllerStr +
                                      " is inconsistent with ONOS1" )
                     consistentClustersResult = main.FALSE
 
@@ -1019,14 +1319,19 @@
             onpass="Clusters view is consistent across all ONOS nodes",
             onfail="ONOS nodes have different views of clusters" )
         # there should always only be one cluster
-        numClusters = len( json.loads( clusters[ 0 ] ) )
+        try:
+            numClusters = len( json.loads( clusters[ 0 ] ) )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing clusters[0]: " +
+                                repr( clusters[ 0 ] ) )
+        clusterResults = main.FALSE
+        if numClusters == 1:
+            clusterResults = main.TRUE
         utilities.assert_equals(
             expect=1,
             actual=numClusters,
             onpass="ONOS shows 1 SCC",
-            onfail="ONOS shows " +
-            str( numClusters ) +
-            " SCCs" )
+            onfail="ONOS shows " + str( numClusters ) + " SCCs" )
 
         main.step( "Comparing ONOS topology to MN" )
         devicesResults = main.TRUE
@@ -1037,90 +1342,95 @@
             if devices[ controller ] or "Error" not in devices[ controller ]:
                 currentDevicesResult = main.Mininet1.compareSwitches(
                     MNTopo,
-                    json.loads(
-                        devices[ controller ] ) )
+                    json.loads( devices[ 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" )
+                                     actual=currentDevicesResult,
+                                     onpass="ONOS" + controllerStr +
+                                     " Switches view is correct",
+                                     onfail="ONOS" + controllerStr +
+                                     " Switches view is incorrect" )
 
             if ports[ controller ] or "Error" not in ports[ controller ]:
                 currentPortsResult = main.Mininet1.comparePorts(
                     MNTopo,
-                    json.loads(
-                        ports[ controller ] ) )
+                    json.loads( ports[ controller ] ) )
             else:
                 currentPortsResult = main.FALSE
             utilities.assert_equals( expect=main.TRUE,
-                                    actual=currentPortsResult,
-                                    onpass="ONOS" + controllerStr +
-                                    " ports view is correct",
-                                    onfail="ONOS" + controllerStr +
-                                    " ports view is incorrect" )
+                                     actual=currentPortsResult,
+                                     onpass="ONOS" + controllerStr +
+                                     " ports view is correct",
+                                     onfail="ONOS" + controllerStr +
+                                     " ports view is incorrect" )
 
             if links[ controller ] or "Error" not in links[ controller ]:
                 currentLinksResult = main.Mininet1.compareLinks(
                     MNTopo,
-                    json.loads(
-                        links[ controller ] ) )
+                    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" )
+                                     actual=currentLinksResult,
+                                     onpass="ONOS" + controllerStr +
+                                     " links view is correct",
+                                     onfail="ONOS" + controllerStr +
+                                     " links view is incorrect" )
 
             devicesResults = devicesResults and currentDevicesResult
             portsResults = portsResults and currentPortsResult
             linksResults = linksResults and currentLinksResult
 
-        topoResult = devicesResults and portsResults and linksResults\
-            and consistentHostsResult and consistentClustersResult
+        topoResult = ( devicesResults and portsResults and linksResults
+                       and consistentHostsResult and consistentClustersResult
+                       and clusterResults and ipResult )
         utilities.assert_equals( expect=main.TRUE, actual=topoResult,
-                                onpass="Topology Check Test successful",
-                                onfail="Topology Check Test NOT successful" )
+                                 onpass="Topology Check Test successful",
+                                 onfail="Topology Check Test NOT successful" )
 
         finalAssert = main.TRUE
-        finalAssert = finalAssert and topoResult and flowCheck \
-            and intentCheck and consistentMastership and rolesNotNull
+        finalAssert = ( finalAssert and topoResult and flowCheck
+                        and intentCheck and consistentMastership
+                        and rolesNotNull )
         utilities.assert_equals( expect=main.TRUE, actual=finalAssert,
-                                onpass="State check successful",
-                                onfail="State check NOT successful" )
+                                 onpass="State check successful",
+                                 onfail="State check NOT successful" )
 
     def CASE6( self, main ):
         """
         The Failure case.
         """
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         main.log.report( "Killing 3 ONOS nodes" )
-        main.log.case( "Restart minority of ONOS nodes" )
+        main.case( "Restart minority of ONOS nodes" )
         # TODO: Randomize these nodes
-        main.ONOSbench.onosKill( ONOS1Ip )
+        # TODO: use threads in this case
+        main.ONOSbench.onosKill( nodes[0].ip_address )
         time.sleep( 10 )
-        main.ONOSbench.onosKill( ONOS2Ip )
+        main.ONOSbench.onosKill( nodes[1].ip_address )
         time.sleep( 10 )
-        main.ONOSbench.onosKill( ONOS3Ip )
+        main.ONOSbench.onosKill( nodes[2].ip_address )
 
         main.step( "Checking if ONOS is up yet" )
         count = 0
         onosIsupResult = main.FALSE
         while onosIsupResult == main.FALSE and count < 10:
-            onos1Isup = main.ONOSbench.isup( ONOS1Ip )
-            onos2Isup = main.ONOSbench.isup( ONOS2Ip )
-            onos3Isup = main.ONOSbench.isup( ONOS3Ip )
+            onos1Isup = main.ONOSbench.isup( nodes[0].ip_address )
+            onos2Isup = main.ONOSbench.isup( nodes[1].ip_address )
+            onos3Isup = main.ONOSbench.isup( nodes[2].ip_address )
             onosIsupResult = onos1Isup and onos2Isup and onos3Isup
             count = count + 1
         # TODO: if it becomes an issue, we can retry this step  a few times
 
-        cliResult1 = main.ONOScli1.startOnosCli( ONOS1Ip )
-        cliResult2 = main.ONOScli2.startOnosCli( ONOS2Ip )
-        cliResult3 = main.ONOScli3.startOnosCli( ONOS3Ip )
+        cliResult1 = main.ONOScli1.startOnosCli( nodes[0].ip_address )
+        cliResult2 = main.ONOScli2.startOnosCli( nodes[1].ip_address )
+        cliResult3 = main.ONOScli3.startOnosCli( nodes[2].ip_address )
         cliResults = cliResult1 and cliResult2 and cliResult3
 
         # Grab the time of restart so we chan check how long the gossip
@@ -1128,115 +1438,111 @@
         main.restartTime = time.time()
         caseResults = main.TRUE and onosIsupResult and cliResults
         utilities.assert_equals( expect=main.TRUE, actual=caseResults,
-                                onpass="ONOS restart successful",
-                                onfail="ONOS restart NOT successful" )
+                                 onpass="ONOS restart successful",
+                                 onfail="ONOS restart NOT successful" )
 
     def CASE7( self, main ):
         """
         Check state after ONOS failure
         """
         import json
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         main.case( "Running ONOS Constant State Tests" )
 
+        main.step( "Check that each switch has a master" )
         # Assert that each device has a master
-        ONOS1MasterNotNull = main.ONOScli1.rolesNotNull()
-        ONOS2MasterNotNull = main.ONOScli2.rolesNotNull()
-        ONOS3MasterNotNull = main.ONOScli3.rolesNotNull()
-        ONOS4MasterNotNull = main.ONOScli4.rolesNotNull()
-        ONOS5MasterNotNull = main.ONOScli5.rolesNotNull()
-        ONOS6MasterNotNull = main.ONOScli6.rolesNotNull()
-        ONOS7MasterNotNull = main.ONOScli7.rolesNotNull()
-        rolesNotNull = ONOS1MasterNotNull and ONOS2MasterNotNull and\
-            ONOS3MasterNotNull and ONOS4MasterNotNull and\
-            ONOS5MasterNotNull and ONOS6MasterNotNull and\
-            ONOS7MasterNotNull
+        rolesNotNull = main.TRUE
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].rolesNotNull,
+                             name="rolesNotNull-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            rolesNotNull = rolesNotNull and t.result
         utilities.assert_equals(
             expect=main.TRUE,
             actual=rolesNotNull,
             onpass="Each device has a master",
             onfail="Some devices don't have a master assigned" )
 
-        main.step( "Check if switch roles are consistent across all nodes" )
-        ONOS1Mastership = main.ONOScli1.roles()
-        ONOS2Mastership = main.ONOScli2.roles()
-        ONOS3Mastership = main.ONOScli3.roles()
-        ONOS4Mastership = main.ONOScli4.roles()
-        ONOS5Mastership = main.ONOScli5.roles()
-        ONOS6Mastership = main.ONOScli6.roles()
-        ONOS7Mastership = main.ONOScli7.roles()
-        if "Error" in ONOS1Mastership or not ONOS1Mastership\
-                or "Error" in ONOS2Mastership or not ONOS2Mastership\
-                or "Error" in ONOS3Mastership or not ONOS3Mastership\
-                or "Error" in ONOS4Mastership or not ONOS4Mastership\
-                or "Error" in ONOS5Mastership or not ONOS5Mastership\
-                or "Error" in ONOS6Mastership or not ONOS6Mastership\
-                or "Error" in ONOS7Mastership or not ONOS7Mastership:
-            main.log.error( "Error in getting ONOS mastership" )
-            main.log.warn( "ONOS1 mastership response: " +
-                           repr( ONOS1Mastership ) )
-            main.log.warn( "ONOS2 mastership response: " +
-                           repr( ONOS2Mastership ) )
-            main.log.warn( "ONOS3 mastership response: " +
-                           repr( ONOS3Mastership ) )
-            main.log.warn( "ONOS4 mastership response: " +
-                           repr( ONOS4Mastership ) )
-            main.log.warn( "ONOS5 mastership response: " +
-                           repr( ONOS5Mastership ) )
-            main.log.warn( "ONOS6 mastership response: " +
-                           repr( ONOS6Mastership ) )
-            main.log.warn( "ONOS7 mastership response: " +
-                           repr( ONOS7Mastership ) )
-            consistentMastership = main.FALSE
-        elif ONOS1Mastership == ONOS2Mastership\
-                and ONOS1Mastership == ONOS3Mastership\
-                and ONOS1Mastership == ONOS4Mastership\
-                and ONOS1Mastership == ONOS5Mastership\
-                and ONOS1Mastership == ONOS6Mastership\
-                and ONOS1Mastership == ONOS7Mastership:
-            consistentMastership = main.TRUE
+        ONOSMastership = []
+        mastershipCheck = main.FALSE
+        consistentMastership = True
+        rolesResults = True
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].roles,
+                             name="roles-" + str( i ),
+                             args=[] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            ONOSMastership.append( t.result )
+
+        for i in range( numControllers ):
+            if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
+                main.log.report( "Error in getting ONOS" + str( i + 1 ) +
+                                 " roles" )
+                main.log.warn(
+                    "ONOS" + str( i + 1 ) + " mastership response: " +
+                    repr( ONOSMastership[i] ) )
+                rolesResults = False
+        utilities.assert_equals(
+            expect=True,
+            actual=rolesResults,
+            onpass="No error in reading roles output",
+            onfail="Error in reading roles from ONOS" )
+
+        main.step( "Check for consistency in roles from each controller" )
+        if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
             main.log.report(
                 "Switch roles are consistent across all ONOS nodes" )
         else:
-            main.log.warn( "ONOS1 roles: ", json.dumps(
-                json.loads( ONOS1Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS2 roles: ", json.dumps(
-                json.loads( ONOS2Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS3 roles: ", json.dumps(
-                json.loads( ONOS3Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS4 roles: ", json.dumps(
-                json.loads( ONOS4Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS5 roles: ", json.dumps(
-                json.loads( ONOS5Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS6 roles: ", json.dumps(
-                json.loads( ONOS6Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS7 roles: ", json.dumps(
-                json.loads( ONOS7Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            consistentMastership = main.FALSE
+            consistentMastership = False
         utilities.assert_equals(
-            expect=main.TRUE,
+            expect=True,
             actual=consistentMastership,
             onpass="Switch roles are consistent across all ONOS nodes",
             onfail="ONOS nodes have different views of switch roles" )
 
+        if rolesResults and not consistentMastership:
+            for i in range( numControllers ):
+                main.log.warn(
+                    "ONOS" + str( i + 1 ) + " roles: ",
+                    json.dumps(
+                        json.loads( ONOSMastership[ i ] ),
+                        sort_keys=True,
+                        indent=4,
+                        separators=( ',', ': ' ) ) )
+        elif rolesResults and not consistentMastership:
+            mastershipCheck = main.TRUE
+
         description2 = "Compare switch roles from before failure"
         main.step( description2 )
-
-        currentJson = json.loads( ONOS1Mastership )
-        oldJson = json.loads( mastershipState )
+        try:
+            currentJson = json.loads( ONOSMastership[0] )
+            oldJson = json.loads( mastershipState )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Something is wrong with parsing " +
+                                "ONOSMastership[0] or mastershipState" )
+            main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
+            main.log.error( "mastershipState" + repr( mastershipState ) )
+            main.cleanup()
+            main.exit()
         mastershipCheck = main.TRUE
         for i in range( 1, 29 ):
             switchDPID = str(
-                main.Mininet1.getSwitchDPID(
-                    switch="s" +
-                    str( i ) ) )
-
+                main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
             current = [ switch[ 'master' ] for switch in currentJson
                         if switchDPID in switch[ 'id' ] ]
             old = [ switch[ 'master' ] for switch in oldJson
@@ -1256,156 +1562,128 @@
         # NOTE: we expect mastership to change on controller failure
         mastershipCheck = consistentMastership
 
-        while True:
-            whileTime = time.time() - main.restartTime
-            # Gossip store
-            main.step( "Get the intents and compare across all nodes" )
-            ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
-            ONOS2Intents = main.ONOScli2.intents( jsonFormat=True )
-            ONOS3Intents = main.ONOScli3.intents( jsonFormat=True )
-            ONOS4Intents = main.ONOScli4.intents( jsonFormat=True )
-            ONOS5Intents = main.ONOScli5.intents( jsonFormat=True )
-            ONOS6Intents = main.ONOScli6.intents( jsonFormat=True )
-            ONOS7Intents = main.ONOScli7.intents( jsonFormat=True )
-            intentCheck = main.FALSE
-            if "Error" in ONOS1Intents or not ONOS1Intents\
-                    or "Error" in ONOS2Intents or not ONOS2Intents\
-                    or "Error" in ONOS3Intents or not ONOS3Intents\
-                    or "Error" in ONOS4Intents or not ONOS4Intents\
-                    or "Error" in ONOS5Intents or not ONOS5Intents\
-                    or "Error" in ONOS6Intents or not ONOS6Intents\
-                    or "Error" in ONOS7Intents or not ONOS7Intents:
-                main.log.report( "Error in getting ONOS intents" )
-                main.log.warn( "ONOS1 intents response: " +
-                               repr( ONOS1Intents ) )
-                main.log.warn( "ONOS2 intents response: " +
-                               repr( ONOS2Intents ) )
-                main.log.warn( "ONOS3 intents response: " +
-                               repr( ONOS3Intents ) )
-                main.log.warn( "ONOS4 intents response: " +
-                               repr( ONOS4Intents ) )
-                main.log.warn( "ONOS5 intents response: " +
-                               repr( ONOS5Intents ) )
-                main.log.warn( "ONOS6 intents response: " +
-                               repr( ONOS6Intents ) )
-                main.log.warn( "ONOS7 intents response: " +
-                               repr( ONOS7Intents ) )
-            elif ONOS1Intents == ONOS2Intents\
-                    and ONOS1Intents == ONOS3Intents\
-                    and ONOS1Intents == ONOS4Intents\
-                    and ONOS1Intents == ONOS5Intents\
-                    and ONOS1Intents == ONOS6Intents\
-                    and ONOS1Intents == ONOS7Intents:
-                intentCheck = main.TRUE
-                main.log.report( "Intents are consistent across all" +
-                                 " ONOS nodes" )
-            else:
-                main.log.warn( "ONOS1 intents: " )
-                print json.dumps( json.loads( ONOS1Intents ), sort_keys=True,
-                                  indent=4, separators=( ',', ': ' ) )
-                main.log.warn( "ONOS2 intents: " )
-                print json.dumps( json.loads( ONOS2Intents ), sort_keys=True,
-                                  indent=4, separators=( ',', ': ' ) )
-                main.log.warn( "ONOS3 intents: " )
-                print json.dumps( json.loads( ONOS3Intents ), sort_keys=True,
-                                  indent=4, separators=( ',', ': ' ) )
-                main.log.warn( "ONOS4 intents: " )
-                print json.dumps( json.loads( ONOS4Intents ), sort_keys=True,
-                                  indent=4, separators=( ',', ': ' ) )
-                main.log.warn( "ONOS5 intents: " )
-                print json.dumps( json.loads( ONOS5Intents ), sort_keys=True,
-                                  indent=4, separators=( ',', ': ' ) )
-                main.log.warn( "ONOS6 intents: " )
-                print json.dumps( json.loads( ONOS6Intents ), sort_keys=True,
-                                  indent=4, separators=( ',', ': ' ) )
-                main.log.warn( "ONOS7 intents: " )
-                print json.dumps( json.loads( ONOS7Intents ), sort_keys=True,
-                                  indent=4, separators=( ',', ': ' ) )
-            utilities.assert_equals(
-                expect=main.TRUE,
-                actual=intentCheck,
-                onpass="Intents are consistent across all ONOS nodes",
-                onfail="ONOS nodes have different views of intents" )
-            # Print the intent states
-            intents = []
-            intents.append( ONOS1Intents )
-            intents.append( ONOS2Intents )
-            intents.append( ONOS3Intents )
-            intents.append( ONOS4Intents )
-            intents.append( ONOS5Intents )
-            intents.append( ONOS6Intents )
-            intents.append( ONOS7Intents )
-            intentStates = []
-            for node in intents:  # Iter through ONOS nodes
-                nodeStates = []
-                # Iter through intents of a node
+        main.step( "Get the intents and compare across all nodes" )
+        ONOSIntents = []
+        intentCheck = main.FALSE
+        consistentIntents = True
+        intentsResults = True
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].intents,
+                             name="intents-" + str( i ),
+                             args=[],
+                             kwargs={ 'jsonFormat': True } )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            ONOSIntents.append( t.result )
+
+        for i in range( numControllers ):
+            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
+                main.log.report( "Error in getting ONOS" + str( i + 1 ) +
+                                 " intents" )
+                main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
+                               repr( ONOSIntents[ i ] ) )
+                intentsResults = False
+        utilities.assert_equals(
+            expect=True,
+            actual=intentsResults,
+            onpass="No error in reading intents output",
+            onfail="Error in reading intents from ONOS" )
+
+        main.step( "Check for consistency in Intents from each controller" )
+        if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
+            main.log.report( "Intents are consistent across all ONOS " +
+                             "nodes" )
+        else:
+            consistentIntents = False
+        utilities.assert_equals(
+            expect=True,
+            actual=consistentIntents,
+            onpass="Intents are consistent across all ONOS nodes",
+            onfail="ONOS nodes have different views of intents" )
+        intentStates = []
+        for node in ONOSIntents:  # Iter through ONOS nodes
+            nodeStates = []
+            # Iter through intents of a node
+            try:
                 for intent in json.loads( node ):
                     nodeStates.append( intent[ 'state' ] )
-                intentStates.append( nodeStates )
-                out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
-                main.log.info( dict( out ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error in parsing intents" )
+                main.log.error( repr( node ) )
+            intentStates.append( nodeStates )
+            out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
+            main.log.info( dict( out ) )
 
+        if intentsResults and not consistentIntents:
+            for i in range( numControllers ):
+                main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
+                main.log.warn( json.dumps(
+                    json.loads( ONOSIntents[ i ] ),
+                    sort_keys=True,
+                    indent=4,
+                    separators=( ',', ': ' ) ) )
+        elif intentsResults and consistentIntents:
+            intentCheck = main.TRUE
 
-            # NOTE: Store has no durability, so intents are lost across system
-            # restarts
-            main.step( "Compare current intents with intents before the failure" )
-            # NOTE: this requires case 5 to pass for intentState to be set.
-            #      maybe we should stop the test if that fails?
+        # NOTE: Store has no durability, so intents are lost across system
+        #       restarts
+        main.step( "Compare current intents with intents before the failure" )
+        # NOTE: this requires case 5 to pass for intentState to be set.
+        #      maybe we should stop the test if that fails?
+        sameIntents = main.TRUE
+        if intentState and intentState == ONOSIntents[ 0 ]:
             sameIntents = main.TRUE
-            if intentState and intentState == ONOS1Intents:
-                sameIntents = main.TRUE
-                main.log.report( "Intents are consistent with before failure" )
-            # TODO: possibly the states have changed? we may need to figure out
-            # what the aceptable states are
-            else:
-                try:
-                    main.log.warn( "ONOS1 intents: " )
-                    print json.dumps( json.loads( ONOS1Intents ),
-                                      sort_keys=True, indent=4,
-                                      separators=( ',', ': ' ) )
-                except:
-                    pass
-                sameIntents = main.FALSE
-            utilities.assert_equals(
-                expect=main.TRUE,
-                actual=sameIntents,
-                onpass="Intents are consistent with before failure",
-                onfail="The Intents changed during failure" )
-            intentCheck = intentCheck and sameIntents
+            main.log.report( "Intents are consistent with before failure" )
+        # TODO: possibly the states have changed? we may need to figure out
+        #       what the acceptable states are
+        else:
+            try:
+                main.log.warn( "ONOS intents: " )
+                main.log.warn( json.dumps( json.loads( ONOSIntents[ 0 ] ),
+                                           sort_keys=True, indent=4,
+                                           separators=( ',', ': ' ) ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Exception printing intents" )
+                main.log.warn( repr( ONOSIntents[0] ) )
+            sameIntents = main.FALSE
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=sameIntents,
+            onpass="Intents are consistent with before failure",
+            onfail="The Intents changed during failure" )
+        intentCheck = intentCheck and sameIntents
 
-            main.step( "Get the OF Table entries and compare to before " +
-                       "component failure" )
-            FlowTables = main.TRUE
-            flows2 = []
-            for i in range( 28 ):
-                main.log.info( "Checking flow table on s" + str( i + 1 ) )
-                tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
-                flows2.append( tmpFlows )
-                tempResult = main.Mininet2.flowComp(
-                    flow1=flows[ i ],
-                    flow2=tmpFlows )
-                FlowTables = FlowTables and tempResult
-                if FlowTables == main.FALSE:
-                    main.log.info( "Differences in flow table for switch: s" +
-                                   str( i + 1 ) )
-            if FlowTables == main.TRUE:
-                main.log.report( "No changes were found in the flow tables" )
-            utilities.assert_equals(
-                expect=main.TRUE,
-                actual=FlowTables,
-                onpass="No changes were found in the flow tables",
-                onfail="Changes were found in the flow tables" )
-            if topoResult == main.TRUE or ( whileTime  > 10 ) :
-                break
+        main.step( "Get the OF Table entries and compare to before " +
+                   "component failure" )
+        FlowTables = main.TRUE
+        flows2 = []
+        for i in range( 28 ):
+            main.log.info( "Checking flow table on s" + str( i + 1 ) )
+            tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
+            flows2.append( tmpFlows )
+            tempResult = main.Mininet2.flowComp(
+                flow1=flows[ i ],
+                flow2=tmpFlows )
+            FlowTables = FlowTables and tempResult
+            if FlowTables == main.FALSE:
+                main.log.info( "Differences in flow table for switch: s" +
+                               str( i + 1 ) )
+        if FlowTables == main.TRUE:
+            main.log.report( "No changes were found in the flow tables" )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=FlowTables,
+            onpass="No changes were found in the flow tables",
+            onfail="Changes were found in the flow tables" )
 
         main.step( "Check the continuous pings to ensure that no packets " +
                    "were dropped during component failure" )
-        # FIXME: This check is always failing. Investigate cause
-        # NOTE:  this may be something to do with file permsissions
-        #       or slight change in format
-        main.Mininet2.pingKill(
-            main.params[ 'TESTONUSER' ],
-            main.params[ 'TESTONIP' ] )
+        main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
+                                main.params[ 'TESTONIP' ] )
         LossInPings = main.FALSE
         # NOTE: checkForLoss returns main.FALSE with 0% packet loss
         for i in range( 8, 18 ):
@@ -1430,11 +1708,13 @@
 
         # Test of LeadershipElection
         leaderList = []
+        # FIXME: make sure this matches nodes that were restarted
+        restarted = [ nodes[0].ip_address, nodes[1].ip_address,
+                      nodes[2].ip_address ]
+            
         leaderResult = main.TRUE
-        for controller in range( 1, numControllers + 1 ):
-            # loop through ONOScli handlers
-            node = getattr( main, ( 'ONOScli' + str( controller ) ) )
-            leaderN = node.electionTestLeader()
+        for cli in CLIs:
+            leaderN = cli.electionTestLeader()
             leaderList.append( leaderN )
             if leaderN == main.FALSE:
                 # error in  response
@@ -1443,14 +1723,12 @@
                                  " error logs" )
                 leaderResult = main.FALSE
             elif leaderN is None:
-                main.log.report( "ONOS" + str( controller ) +
+                main.log.report( cli.name +
                                  " shows no leader for the election-app was" +
                                  " elected after the old one died" )
                 leaderResult = main.FALSE
-            elif leaderN == ONOS1Ip or leaderN == ONOS2Ip or\
-                    leaderN == ONOS3Ip:
-                main.log.report( "ONOS" + str( controller ) +
-                                 " shows " + str( leaderN ) +
+            elif leaderN in restarted:
+                main.log.report( cli.name + " shows " + str( leaderN ) +
                                  " as leader for the election-app, but it " +
                                  "was restarted" )
                 leaderResult = main.FALSE
@@ -1469,14 +1747,14 @@
             onpass="Leadership election passed",
             onfail="Something went wrong with Leadership election" )
 
-        result = mastershipCheck and intentCheck and FlowTables and\
-            ( not LossInPings ) and rolesNotNull and leaderResult
+        result = ( mastershipCheck and intentCheck and FlowTables and
+                   ( not LossInPings ) and rolesNotNull and leaderResult )
         result = int( result )
         if result == main.TRUE:
             main.log.report( "Constant State Tests Passed" )
         utilities.assert_equals( expect=main.TRUE, actual=result,
-                                onpass="Constant State Tests Passed",
-                                onfail="Constant state tests failed" )
+                                 onpass="Constant State Tests Passed",
+                                 onfail="Constant state tests failed" )
 
     def CASE8( self, main ):
         """
@@ -1489,33 +1767,27 @@
         from sts.topology.teston_topology import TestONTopology
         import json
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
 
         description = "Compare ONOS Topology view to Mininet topology"
         main.case( description )
         main.log.report( description )
         main.step( "Create TestONTopology object" )
         ctrls = []
-        count = 1
-        while True:
-            temp = ()
-            if ( 'ip' + str( count ) ) in main.params[ 'CTRL' ]:
-                temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
-                temp = temp + ( "ONOS" + str( count ), )
-                temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
-                temp = temp + \
-                    ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
-                ctrls.append( temp )
-                count = count + 1
-            else:
-                break
-        MNTopo = TestONTopology(
-            main.Mininet1,
-            ctrls )  # can also add Intent API info for intent operations
+        for node in nodes:
+            temp = ( node, node.name, node.ip_address, 6633 )
+            ctrls.append( temp )
+        MNTopo = TestONTopology( main.Mininet1, ctrls )
 
         main.step( "Comparing ONOS topology to MN" )
         devicesResults = main.TRUE
         portsResults = main.TRUE
         linksResults = main.TRUE
+        hostsResults = main.TRUE
         topoResult = main.FALSE
         elapsed = 0
         count = 0
@@ -1523,60 +1795,84 @@
         startTime = time.time()
         # Give time for Gossip to work
         while topoResult == main.FALSE and elapsed < 60:
-            count = count + 1
+            count += 1
             if count > 1:
-                # TODO: Depricate STS usage
-                MNTopo = TestONTopology(
-                    main.Mininet1,
-                    ctrls )
+                # TODO: Deprecate STS usage
+                MNTopo = TestONTopology( main.Mininet1, ctrls )
             cliStart = time.time()
             devices = []
-            devices.append( main.ONOScli1.devices() )
-            devices.append( main.ONOScli2.devices() )
-            devices.append( main.ONOScli3.devices() )
-            devices.append( main.ONOScli4.devices() )
-            devices.append( main.ONOScli5.devices() )
-            devices.append( main.ONOScli6.devices() )
-            devices.append( main.ONOScli7.devices() )
+            threads = []
+            for i in range( numControllers ):
+                t = main.Thread( target=CLIs[i].devices,
+                                 name="devices-" + str( i ),
+                                 args=[ ] )
+                threads.append( t )
+                t.start()
+
+            for t in threads:
+                t.join()
+                devices.append( t.result )
             hosts = []
-            hosts.append( json.loads( main.ONOScli1.hosts() ) )
-            hosts.append( json.loads( main.ONOScli2.hosts() ) )
-            hosts.append( json.loads( main.ONOScli3.hosts() ) )
-            hosts.append( json.loads( main.ONOScli4.hosts() ) )
-            hosts.append( json.loads( main.ONOScli5.hosts() ) )
-            hosts.append( json.loads( main.ONOScli6.hosts() ) )
-            hosts.append( json.loads( main.ONOScli7.hosts() ) )
+            ipResult = main.TRUE
+            threads = []
+            for i in range( numControllers ):
+                t = main.Thread( target=CLIs[i].hosts,
+                                 name="hosts-" + str( i ),
+                                 args=[ ] )
+                threads.append( t )
+                t.start()
+
+            for t in threads:
+                t.join()
+                try:
+                    hosts.append( json.loads( t.result ) )
+                except ( ValueError, TypeError ):
+                    main.log.exception( "Error parsing hosts results" )
+                    main.log.error( repr( t.result ) )
             for controller in range( 0, len( hosts ) ):
                 controllerStr = str( controller + 1 )
                 for host in hosts[ controller ]:
-                    if host[ 'ips' ] == []:
+                    if host is None or host.get( 'ips', [] ) == []:
                         main.log.error(
                             "DEBUG:Error with host ips on controller" +
                             controllerStr + ": " + str( host ) )
+                        ipResult = main.FALSE
             ports = []
-            ports.append( main.ONOScli1.ports() )
-            ports.append( main.ONOScli2.ports() )
-            ports.append( main.ONOScli3.ports() )
-            ports.append( main.ONOScli4.ports() )
-            ports.append( main.ONOScli5.ports() )
-            ports.append( main.ONOScli6.ports() )
-            ports.append( main.ONOScli7.ports() )
+            threads = []
+            for i in range( numControllers ):
+                t = main.Thread( target=CLIs[i].ports,
+                                 name="ports-" + str( i ),
+                                 args=[ ] )
+                threads.append( t )
+                t.start()
+
+            for t in threads:
+                t.join()
+                ports.append( t.result )
             links = []
-            links.append( main.ONOScli1.links() )
-            links.append( main.ONOScli2.links() )
-            links.append( main.ONOScli3.links() )
-            links.append( main.ONOScli4.links() )
-            links.append( main.ONOScli5.links() )
-            links.append( main.ONOScli6.links() )
-            links.append( main.ONOScli7.links() )
+            threads = []
+            for i in range( numControllers ):
+                t = main.Thread( target=CLIs[i].links,
+                                 name="links-" + str( i ),
+                                 args=[ ] )
+                threads.append( t )
+                t.start()
+
+            for t in threads:
+                t.join()
+                links.append( t.result )
             clusters = []
-            clusters.append( main.ONOScli1.clusters() )
-            clusters.append( main.ONOScli2.clusters() )
-            clusters.append( main.ONOScli3.clusters() )
-            clusters.append( main.ONOScli4.clusters() )
-            clusters.append( main.ONOScli5.clusters() )
-            clusters.append( main.ONOScli6.clusters() )
-            clusters.append( main.ONOScli7.clusters() )
+            threads = []
+            for i in range( numControllers ):
+                t = main.Thread( target=CLIs[i].clusters,
+                                 name="clusters-" + str( i ),
+                                 args=[ ] )
+                threads.append( t )
+                t.start()
+
+            for t in threads:
+                t.join()
+                clusters.append( t.result )
 
             elapsed = time.time() - startTime
             cliTime = time.time() - cliStart
@@ -1588,47 +1884,58 @@
                         controller ]:
                     currentDevicesResult = main.Mininet1.compareSwitches(
                         MNTopo,
-                        json.loads(
-                            devices[ controller ] ) )
+                        json.loads( devices[ 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" )
+                                         actual=currentDevicesResult,
+                                         onpass="ONOS" + controllerStr +
+                                         " Switches view is correct",
+                                         onfail="ONOS" + controllerStr +
+                                         " Switches view is incorrect" )
 
                 if ports[ controller ] or "Error" not in ports[ controller ]:
                     currentPortsResult = main.Mininet1.comparePorts(
                         MNTopo,
-                        json.loads(
-                            ports[ controller ] ) )
+                        json.loads( ports[ controller ] ) )
                 else:
                     currentPortsResult = main.FALSE
                 utilities.assert_equals( expect=main.TRUE,
-                                        actual=currentPortsResult,
-                                        onpass="ONOS" + controllerStr +
-                                        " ports view is correct",
-                                        onfail="ONOS" + controllerStr +
-                                        " ports view is incorrect" )
+                                         actual=currentPortsResult,
+                                         onpass="ONOS" + controllerStr +
+                                         " ports view is correct",
+                                         onfail="ONOS" + controllerStr +
+                                         " ports view is incorrect" )
 
                 if links[ controller ] or "Error" not in links[ controller ]:
                     currentLinksResult = main.Mininet1.compareLinks(
                         MNTopo,
-                        json.loads(
-                            links[ controller ] ) )
+                        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" )
-            devicesResults = devicesResults and currentDevicesResult
-            portsResults = portsResults and currentPortsResult
-            linksResults = linksResults and currentLinksResult
+                                         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(
+                        MNTopo, 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" )
+
+                devicesResults = devicesResults and currentDevicesResult
+                portsResults = portsResults and currentPortsResult
+                linksResults = linksResults and currentLinksResult
+                hostsResults = hostsResults and currentHostsResult
 
             # Compare json objects for hosts and dataplane clusters
 
@@ -1684,18 +1991,24 @@
                 onpass="Clusters view is consistent across all ONOS nodes",
                 onfail="ONOS nodes have different views of clusters" )
             # there should always only be one cluster
-            numClusters = len( json.loads( clusters[ 0 ] ) )
+            try:
+                numClusters = len( json.loads( clusters[ 0 ] ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing clusters[0]: " +
+                                    repr( clusters[0] ) )
+            clusterResults = main.FALSE
+            if numClusters == 1:
+                clusterResults = main.TRUE
             utilities.assert_equals(
                 expect=1,
                 actual=numClusters,
                 onpass="ONOS shows 1 SCC",
-                onfail="ONOS shows " +
-                str( numClusters ) +
-                " SCCs" )
+                onfail="ONOS shows " + str( numClusters ) + " SCCs" )
 
             topoResult = ( devicesResults and portsResults and linksResults
-                           and consistentHostsResult
-                           and consistentClustersResult )
+                           and hostsResults and consistentHostsResult
+                           and consistentClustersResult and clusterResults
+                           and ipResult )
 
         topoResult = topoResult and int( count <= 2 )
         note = "note it takes about " + str( int( cliTime ) ) + \
@@ -1706,8 +2019,8 @@
             str( note ) + " ): " + str( elapsed ) + " seconds, " +
             str( count ) + " tries" )
         utilities.assert_equals( expect=main.TRUE, actual=topoResult,
-                                onpass="Topology Check Test successful",
-                                onfail="Topology Check Test NOT successful" )
+                                 onpass="Topology Check Test successful",
+                                 onfail="Topology Check Test NOT successful" )
         if topoResult == main.TRUE:
             main.log.report( "ONOS topology view matches Mininet topology" )
 
@@ -1716,25 +2029,28 @@
         Link s3-s28 down
         """
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         # NOTE: You should probably run a topology check after this
 
         linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
 
         description = "Turn off a link to ensure that Link Discovery " +\
-            "is working properly"
+                      "is working properly"
         main.log.report( description )
         main.case( description )
 
         main.step( "Kill Link between s3 and s28" )
         LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
-        main.log.info(
-            "Waiting " +
-            str( linkSleep ) +
-            " seconds for link down to be discovered" )
+        main.log.info( "Waiting " + str( linkSleep ) +
+                       " seconds for link down to be discovered" )
         time.sleep( linkSleep )
         utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
-                                onpass="Link down succesful",
-                                onfail="Failed to bring link down" )
+                                 onpass="Link down successful",
+                                 onfail="Failed to bring link down" )
         # TODO do some sort of check here
 
     def CASE10( self, main ):
@@ -1742,25 +2058,28 @@
         Link s3-s28 up
         """
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         # NOTE: You should probably run a topology check after this
 
         linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
 
         description = "Restore a link to ensure that Link Discovery is " + \
-            "working properly"
+                      "working properly"
         main.log.report( description )
         main.case( description )
 
         main.step( "Bring link between s3 and s28 back up" )
         LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
-        main.log.info(
-            "Waiting " +
-            str( linkSleep ) +
-            " seconds for link up to be discovered" )
+        main.log.info( "Waiting " + str( linkSleep ) +
+                       " seconds for link up to be discovered" )
         time.sleep( linkSleep )
         utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
-                                onpass="Link up succesful",
-                                onfail="Failed to bring link up" )
+                                 onpass="Link up successful",
+                                 onfail="Failed to bring link up" )
         # TODO do some sort of check here
 
     def CASE11( self, main ):
@@ -1769,6 +2088,11 @@
         """
         # NOTE: You should probably run a topology check after this
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
 
         switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
 
@@ -1792,8 +2116,8 @@
         if device and device[ 'available' ] is False:
             result = main.TRUE
         utilities.assert_equals( expect=main.TRUE, actual=result,
-                                onpass="Kill switch succesful",
-                                onfail="Failed to kill switch?" )
+                                 onpass="Kill switch successful",
+                                 onfail="Failed to kill switch?" )
 
     def CASE12( self, main ):
         """
@@ -1801,6 +2125,18 @@
         """
         # NOTE: You should probably run a topology check after this
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
+        assert ONOS1Port, "ONOS1Port not defined"
+        assert ONOS2Port, "ONOS2Port not defined"
+        assert ONOS3Port, "ONOS3Port not defined"
+        assert ONOS4Port, "ONOS4Port not defined"
+        assert ONOS5Port, "ONOS5Port not defined"
+        assert ONOS6Port, "ONOS6Port not defined"
+        assert ONOS7Port, "ONOS7Port not defined"
 
         switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
         switch = main.params[ 'kill' ][ 'switch' ]
@@ -1813,30 +2149,26 @@
         main.step( "Add back " + switch )
         main.log.report( "Adding back " + switch )
         main.Mininet1.addSwitch( switch, dpid=switchDPID )
-        # TODO: New dpid or same? Ask Thomas?
         for peer in links:
             main.Mininet1.addLink( switch, peer )
-        main.Mininet1.assignSwController(
-            sw=switch.split( 's' )[ 1 ],
-            count=numControllers,
-            ip1=ONOS1Ip,
-            port1=ONOS1Port,
-            ip2=ONOS2Ip,
-            port2=ONOS2Port,
-            ip3=ONOS3Ip,
-            port3=ONOS3Port,
-            ip4=ONOS4Ip,
-            port4=ONOS4Port,
-            ip5=ONOS5Ip,
-            port5=ONOS5Port,
-            ip6=ONOS6Ip,
-            port6=ONOS6Port,
-            ip7=ONOS7Ip,
-            port7=ONOS7Port )
-        main.log.info(
-            "Waiting " +
-            str( switchSleep ) +
-            " seconds for switch up to be discovered" )
+        main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
+                                          count=numControllers,
+                                          ip1=nodes[ 0 ].ip_address,
+                                          port1=ONOS1Port,
+                                          ip2=nodes[ 1 ].ip_address,
+                                          port2=ONOS2Port,
+                                          ip3=nodes[ 2 ].ip_address,
+                                          port3=ONOS3Port,
+                                          ip4=nodes[ 3 ].ip_address,
+                                          port4=ONOS4Port,
+                                          ip5=nodes[ 4 ].ip_address,
+                                          port5=ONOS5Port,
+                                          ip6=nodes[ 5 ].ip_address,
+                                          port6=ONOS6Port,
+                                          ip7=nodes[ 6 ].ip_address,
+                                          port7=ONOS7Port )
+        main.log.info( "Waiting " + str( switchSleep ) +
+                       " seconds for switch up to be discovered" )
         time.sleep( switchSleep )
         device = main.ONOScli1.getDevice( dpid=switchDPID )
         # Peek at the deleted switch
@@ -1845,8 +2177,8 @@
         if device and device[ 'available' ]:
             result = main.TRUE
         utilities.assert_equals( expect=main.TRUE, actual=result,
-                                onpass="add switch succesful",
-                                onfail="Failed to add switch?" )
+                                 onpass="add switch successful",
+                                 onfail="Failed to add switch?" )
 
     def CASE13( self, main ):
         """
@@ -1854,37 +2186,22 @@
         """
         import os
         import time
-        # TODO: make use of this elsewhere
-        ips = []
-        ips.append( ONOS1Ip )
-        ips.append( ONOS2Ip )
-        ips.append( ONOS3Ip )
-        ips.append( ONOS4Ip )
-        ips.append( ONOS5Ip )
-        ips.append( ONOS6Ip )
-        ips.append( ONOS7Ip )
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
 
         # printing colors to terminal
-        colors = {}
-        colors[ 'cyan' ] = '\033[96m'
-        colors[ 'purple' ] = '\033[95m'
-        colors[ 'blue' ] = '\033[94m'
-        colors[ 'green' ] = '\033[92m'
-        colors[ 'yellow' ] = '\033[93m'
-        colors[ 'red' ] = '\033[91m'
-        colors[ 'end' ] = '\033[0m'
+        colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
+                   'blue': '\033[94m', 'green': '\033[92m',
+                   'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
         description = "Test Cleanup"
         main.log.report( description )
         main.case( description )
         main.step( "Killing tcpdumps" )
         main.Mininet2.stopTcpdump()
 
-        main.step( "Checking ONOS Logs for errors" )
-        for i in range( 7 ):
-            print colors[ 'purple' ] + "Checking logs for errors on " + \
-                "ONOS" + str( i + 1 ) + ":" + colors[ 'end' ]
-            print main.ONOSbench.checkLogs( ips[ i ] )
-
         main.step( "Copying MN pcap and ONOS log files to test station" )
         testname = main.TEST
         teststationUser = main.params[ 'TESTONUSER' ]
@@ -1900,14 +2217,15 @@
         # NOTE: must end in /
         dstDir = "~/packet_captures/"
         for f in logFiles:
-            for i in range( 7 ):
-                main.ONOSbench.handle.sendline( "scp sdn@" + ips[ i ] + ":" +
-                                                logFolder + f + " " +
+            for node in nodes:
+                main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
+                                                ":" + logFolder + f + " " +
                                                 teststationUser + "@" +
                                                 teststationIP + ":" +
                                                 dstDir + str( testname ) +
-                                                "-ONOS" + str( i + 1 ) + "-" +
-                                                f )
+                                                "-" + node.name + "-" + f )
+                main.ONOSbench.handle.expect( "\$" )
+
         # std*.log's
         # NOTE: must end in /
         logFolder = "/opt/onos/var/"
@@ -1915,67 +2233,88 @@
         # NOTE: must end in /
         dstDir = "~/packet_captures/"
         for f in logFiles:
-            for i in range( 7 ):
-                main.ONOSbench.handle.sendline( "scp sdn@" + ips[ i ] + ":" +
-                                                logFolder + f + " " +
+            for node in nodes:
+                main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
+                                                ":" + logFolder + f + " " +
                                                 teststationUser + "@" +
                                                 teststationIP + ":" +
                                                 dstDir + str( testname ) +
-                                                "-ONOS" + str( i + 1 ) + "-" +
-                                                f )
+                                                "-" + node.name + "-" + f )
+                main.ONOSbench.handle.expect( "\$" )
         # sleep so scp can finish
         time.sleep( 10 )
+
+        main.step( "Stopping Mininet" )
+        main.Mininet1.stopNet()
+
+        main.step( "Checking ONOS Logs for errors" )
+        for node in nodes:
+            print colors[ 'purple' ] + "Checking logs for errors on " + \
+                node.name + ":" + colors[ 'end' ]
+            print main.ONOSbench.checkLogs( node.ip_address )
+
         main.step( "Packing and rotating pcap archives" )
         os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
 
         # TODO: actually check something here
         utilities.assert_equals( expect=main.TRUE, actual=main.TRUE,
-                                onpass="Test cleanup successful",
-                                onfail="Test cleanup NOT successful" )
+                                 onpass="Test cleanup successful",
+                                 onfail="Test cleanup NOT successful" )
 
     def CASE14( self, main ):
         """
         start election app on all onos nodes
         """
+        import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
+
         leaderResult = main.TRUE
         # install app on onos 1
         main.log.info( "Install leadership election app" )
         main.ONOScli1.featureInstall( "onos-app-election" )
+        leader = nodes[0].ip_address
         # wait for election
         # check for leader
-        leader = main.ONOScli1.electionTestLeader()
-        # verify leader is ONOS1
-        if leader == ONOS1Ip:
-            # all is well
-            pass
-        elif leader is None:
-            # No leader elected
-            main.log.report( "No leader was elected" )
-            leaderResult = main.FALSE
-        elif leader == main.FALSE:
-            # error in  response
-            # TODO: add check for "Command not found:" in the driver, this
-            # means the app isn't loaded
-            main.log.report( "Something is wrong with electionTestLeader" +
-                             " function, check the error logs" )
-            leaderResult = main.FALSE
-        else:
-            # error in  response
-            main.log.report(
-                "Unexpected response from electionTestLeader function:'" +
-                str( leader ) +
-                "'" )
-            leaderResult = main.FALSE
-
-        # install on other nodes and check for leader.
-        # Should be onos1 and each app should show the same leader
-        for controller in range( 2, numControllers + 1 ):
-            # loop through ONOScli handlers
-            node = getattr( main, ( 'ONOScli' + str( controller ) ) )
-            node.featureInstall( "onos-app-election" )
-            leaderN = node.electionTestLeader()
+        for i in range(2):  # try this twice
+            leader1 = main.ONOScli1.electionTestLeader()
             # verify leader is ONOS1
-            if leaderN == ONOS1Ip:
+            if leader1 == leader:
+                # all is well
+                # pass
+                if i > 0:
+                    main.log.warn( "It took ONOS sometime for leader to be" +
+                                   "elected" )
+                    main.log.debug( "I don't think this should be happening" )
+                break
+            elif leader1 is None:
+                # No leader elected
+                main.log.report( "No leader was elected" )
+                leaderResult = main.FALSE
+            elif leader1 == main.FALSE:
+                # error in  response
+                # TODO: add check for "Command not found:" in the driver, this
+                # means the app isn't loaded
+                main.log.report( "Something is wrong with electionTestLeader" +
+                                 " function, check the error logs" )
+                leaderResult = main.FALSE
+            else:
+                # error in  response
+                main.log.report(
+                    "Unexpected response from electionTestLeader function:'" +
+                    str( leader1 ) + "'" )
+                leaderResult = main.FALSE
+            time.sleep(2)
+        # install on other nodes and check for leader.
+        # Leader should be ONOS1 and each app should show the same leader
+        for cli in CLIs[ 1: ]:
+            cli.featureInstall( "onos-app-election" )
+            leaderN = cli.electionTestLeader()
+            # verify leader is ONOS1
+            if leaderN == leader:
                 # all is well
                 pass
             elif leaderN == main.FALSE:
@@ -1988,8 +2327,7 @@
                 leaderResult = main.FALSE
             elif leader != leaderN:
                 leaderResult = main.FALSE
-                main.log.report( "ONOS" + str( controller ) + " sees " +
-                                 str( leaderN ) +
+                main.log.report( cli.name + " sees " + str( leaderN ) +
                                  " as the leader of the election app. Leader" +
                                  " should be " +
                                  str( leader ) )
@@ -2007,6 +2345,12 @@
         """
         Check that Leadership Election is still functional
         """
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
+
         leaderResult = main.TRUE
         description = "Check that Leadership Election is still functional"
         main.log.report( description )
@@ -2015,28 +2359,20 @@
         leader = main.ONOScli1.electionTestLeader()
         # TODO: do some sanity checking on leader before using it
         withdrawResult = main.FALSE
-        if leader == ONOS1Ip:
-            oldLeader = getattr( main, "ONOScli1" )
-        elif leader == ONOS2Ip:
-            oldLeader = getattr( main, "ONOScli2" )
-        elif leader == ONOS3Ip:
-            oldLeader = getattr( main, "ONOScli3" )
-        elif leader == ONOS4Ip:
-            oldLeader = getattr( main, "ONOScli4" )
-        elif leader == ONOS5Ip:
-            oldLeader = getattr( main, "ONOScli5" )
-        elif leader == ONOS6Ip:
-            oldLeader = getattr( main, "ONOScli6" )
-        elif leader == ONOS7Ip:
-            oldLeader = getattr( main, "ONOScli7" )
-        elif leader is None or leader == main.FALSE:
+        if leader is None or leader == main.FALSE:
             main.log.report(
                 "Leader for the election app should be an ONOS node," +
-                "instead got '" +
-                str( leader ) +
-                "'" )
+                "instead got '" + str( leader ) + "'" )
             leaderResult = main.FALSE
-        withdrawResult = oldLeader.electionTestWithdraw()
+            oldLeader = None
+        for i in range( len( CLIs ) ):
+            if leader == nodes[ i ].ip_address:
+                oldLeader = CLIs[ i ]
+                break
+        else:
+            main.log.error( "Leader election, could not find current leader" )
+        if oldLeader:
+            withdrawResult = oldLeader.electionTestWithdraw()
         utilities.assert_equals(
             expect=main.TRUE,
             actual=withdrawResult,
@@ -2045,23 +2381,17 @@
 
         main.step( "Make sure new leader is elected" )
         leaderList = []
-        for controller in range( 1, numControllers + 1 ):
-            # loop through ONOScli handlers
-            node = getattr( main, ( 'ONOScli' + str( controller ) ) )
-            leaderList.append( node.electionTestLeader() )
-        for leaderN in leaderList:
+        for cli in CLIs:
+            leaderN = cli.electionTestLeader()
+            leaderList.append( leaderN )
             if leaderN == leader:
-                main.log.report(
-                    "ONOS" +
-                    str( controller ) +
-                    " still sees " +
-                    str( leader ) +
-                    " as leader after they withdrew" )
+                main.log.report(  cli.name + " still sees " + str( leader ) +
+                                  " as leader after they withdrew" )
                 leaderResult = main.FALSE
             elif leaderN == main.FALSE:
                 # error in  response
                 # TODO: add check for "Command not found:" in the driver, this
-                # means the app isn't loaded
+                #       means the app isn't loaded
                 main.log.report( "Something is wrong with " +
                                  "electionTestLeader function, " +
                                  "check the error logs" )
@@ -2078,6 +2408,7 @@
             for n in range( len( leaderList ) ):
                 main.log.report( "ONOS" + str( n + 1 ) + " response: " +
                                  str( leaderList[ n ] ) )
+        leaderResult = leaderResult and consistentLeader
         if leaderResult:
             main.log.report( "Leadership election tests passed( consistent " +
                              "view of leader across listeners and a new " +
@@ -2089,9 +2420,12 @@
             onpass="Leadership election passed",
             onfail="Something went wrong with Leadership election" )
 
-        main.step(
-            "Run for election on old leader( just so everyone is in the hat )" )
-        runResult = oldLeader.electionTestRun()
+        main.step( "Run for election on old leader( just so everyone " +
+                   "is in the hat )" )
+        if oldLeader:
+            runResult = oldLeader.electionTestRun()
+        else:
+            runResult = main.FALSE
         utilities.assert_equals(
             expect=main.TRUE,
             actual=runResult,
diff --git a/TestON/tests/HATestNetworkPartition/HATestNetworkPartition.params b/TestON/tests/HATestNetworkPartition/HATestNetworkPartition.params
new file mode 100644
index 0000000..e1421cd
--- /dev/null
+++ b/TestON/tests/HATestNetworkPartition/HATestNetworkPartition.params
@@ -0,0 +1,89 @@
+<PARAMS>
+
+#List of test cases:
+#CASE1: Compile ONOS and push it to the test machines
+#CASE2: Assign mastership to controllers
+#CASE3: Assign intents
+#CASE4: Ping across added host intents
+#CASE5: Reading state of ONOS
+#CASE6: The Failure case. We will create IPTables rules here.
+#CASE7: Check state after control plane partition.
+#CASE8: Compare topo
+#CASE9: Link s3-s28 down
+#CASE10: Link s3-s28 up
+#CASE11: Switch down
+#CASE12: Switch up
+#CASE13: Clean up
+#CASE14: start election app on all onos nodes
+#CASE15: Check that Leadership Election is still functional
+#CASE16: Repair network partition
+              #1,2,8,3,4,5,14,[6],8,7,4,15,9,8,4,10,8,4,11,8,4,12,8,4,13
+    <testcases>1,2,5,14,[6],8,7,4,15,9,8,4,10,8,4,11,8,4,12,8,4,16,13</testcases>
+    <ENV>
+        <cellName>HA</cellName>
+    </ENV>
+    <Git> False </Git>
+    <branch> master </branch>
+    <num_controllers> 7 </num_controllers>
+
+    <CTRL>
+        <ip1>10.128.30.11</ip1>
+        <port1>6633</port1>
+
+        <ip2>10.128.30.12</ip2>
+        <port2>6633</port2>
+
+        <ip3>10.128.30.13</ip3>
+        <port3>6633</port3>
+
+        <ip4>10.128.30.14</ip4>
+        <port4>6633</port4>
+
+        <ip5>10.128.30.15</ip5>
+        <port5>6633</port5>
+
+        <ip6>10.128.30.16</ip6>
+        <port6>6633</port6>
+
+        <ip7>10.128.30.17</ip7>
+        <port7>6633</port7>
+    </CTRL>
+    <TESTONUSER>admin</TESTONUSER>
+    <TESTONIP>10.128.30.9</TESTONIP>
+    <PING>
+        <source1>h8</source1>
+        <source2>h9</source2>
+        <source3>h10</source3>
+        <source4>h11</source4>
+        <source5>h12</source5>
+        <source6>h13</source6>
+        <source7>h14</source7>
+        <source8>h15</source8>
+        <source9>h16</source9>
+        <source10>h17</source10>
+        <target1>10.0.0.18</target1>
+        <target2>10.0.0.19</target2>
+        <target3>10.0.0.20</target3>
+        <target4>10.0.0.21</target4>
+        <target5>10.0.0.22</target5>
+        <target6>10.0.0.23</target6>
+        <target7>10.0.0.24</target7>
+        <target8>10.0.0.25</target8>
+        <target9>10.0.0.26</target9>
+        <target10>10.0.0.27</target10>
+    </PING>
+    <timers>
+        <LinkDiscovery>.2</LinkDiscovery>
+        <SwitchDiscovery>.2</SwitchDiscovery>
+    </timers>
+    <kill>
+        <switch> s5 </switch>
+        <dpid> 0000000000005000 </dpid>
+        <links> h5 s2 s1 s6 </links>
+    </kill>
+    <MNtcpdump>
+        <intf>eth0</intf>
+        <port> </port>
+        <folder>~/packet_captures/</folder>
+    </MNtcpdump>
+</PARAMS>
diff --git a/TestON/tests/HATestNetworkPartition/HATestNetworkPartition.py b/TestON/tests/HATestNetworkPartition/HATestNetworkPartition.py
new file mode 100644
index 0000000..332dd47
--- /dev/null
+++ b/TestON/tests/HATestNetworkPartition/HATestNetworkPartition.py
@@ -0,0 +1,1989 @@
+"""
+Description: This test is to determine how ONOS behaves in a control network
+             partion. ONOS 1,2,3 will be split into a sub cluster and ONOS
+             4,5,6,7 will be in another sub-cluster.
+
+List of test cases:
+CASE1: Compile ONOS and push it to the test machines
+CASE2: Assign mastership to controllers
+CASE3: Assign intents
+CASE4: Ping across added host intents
+CASE5: Reading state of ONOS
+CASE6: The Failure case. We will create IPTables rules here.
+CASE7: Check state after control plane partition.
+CASE8: Compare topo
+CASE9: Link s3-s28 down
+CASE10: Link s3-s28 up
+CASE11: Switch down
+CASE12: Switch up
+CASE13: Clean up
+CASE14: start election app on all onos nodes
+CASE15: Check that Leadership Election is still functional
+CASE16: Repair network partition
+"""
+# FIXME: Add new comparison case for during the failure?
+class HATestNetworkPartition:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):
+        """
+        CASE1 is to compile ONOS and push it to the test machines
+
+        Startup sequence:
+        cell <name>
+        onos-verify-cell
+        NOTE: temporary - onos-remove-raft-logs
+        onos-uninstall
+        start mininet
+        git pull
+        mvn clean install
+        onos-package
+        onos-install -f
+        onos-wait-for-start
+        start cli sessions
+        start tcpdump
+        """
+        main.log.report( "ONOS HA test: Network partition - initialization" )
+        main.log.report( "This test will partition a 7 node cluster into " +
+                         "3 node and 4 node sub clusters by blocking " +
+                         "communication between nodes." )
+        main.case( "Setting up test environment" )
+        # TODO: save all the timers and output them for plotting
+
+        # load some vairables from the params file
+        PULLCODE = False
+        if main.params[ 'Git' ] == 'True':
+            PULLCODE = True
+        gitBranch = main.params[ 'branch' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+
+        # set global variables
+        global ONOS1Ip
+        global ONOS1Port
+        global ONOS2Ip
+        global ONOS2Port
+        global ONOS3Ip
+        global ONOS3Port
+        global ONOS4Ip
+        global ONOS4Port
+        global ONOS5Ip
+        global ONOS5Port
+        global ONOS6Ip
+        global ONOS6Port
+        global ONOS7Ip
+        global ONOS7Port
+        global numControllers
+
+        ONOS1Ip = main.params[ 'CTRL' ][ 'ip1' ]
+        ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
+        ONOS2Ip = main.params[ 'CTRL' ][ 'ip2' ]
+        ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
+        ONOS3Ip = main.params[ 'CTRL' ][ 'ip3' ]
+        ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
+        ONOS4Ip = main.params[ 'CTRL' ][ 'ip4' ]
+        ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
+        ONOS5Ip = main.params[ 'CTRL' ][ 'ip5' ]
+        ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
+        ONOS6Ip = main.params[ 'CTRL' ][ 'ip6' ]
+        ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
+        ONOS7Ip = main.params[ 'CTRL' ][ 'ip7' ]
+        ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
+        numControllers = int( main.params[ 'num_controllers' ] )
+
+        main.step( "Applying cell variable to environment" )
+        cellResult = main.ONOSbench.setCell( cellName )
+        verifyResult = main.ONOSbench.verifyCell()
+
+        # FIXME:this is short term fix
+        main.log.report( "Removing raft logs" )
+        main.ONOSbench.onosRemoveRaftLogs()
+        main.log.report( "Uninstalling ONOS" )
+        main.ONOSbench.onosUninstall( ONOS1Ip )
+        main.ONOSbench.onosUninstall( ONOS2Ip )
+        main.ONOSbench.onosUninstall( ONOS3Ip )
+        main.ONOSbench.onosUninstall( ONOS4Ip )
+        main.ONOSbench.onosUninstall( ONOS5Ip )
+        main.ONOSbench.onosUninstall( ONOS6Ip )
+        main.ONOSbench.onosUninstall( ONOS7Ip )
+
+        cleanInstallResult = main.TRUE
+        gitPullResult = main.TRUE
+
+        main.step( "Starting Mininet" )
+        main.Mininet1.startNet( )
+
+        main.step( "Compiling the latest version of ONOS" )
+        if PULLCODE:
+            main.step( "Git checkout and pull " + gitBranch )
+            main.ONOSbench.gitCheckout( gitBranch )
+            gitPullResult = main.ONOSbench.gitPull()
+
+            main.step( "Using mvn clean & install" )
+            cleanInstallResult = main.ONOSbench.cleanInstall()
+        else:
+            main.log.warn( "Did not pull new code so skipping mvn " +
+                           "clean install" )
+        main.ONOSbench.getVersion( report=True )
+
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.onosPackage()
+
+        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 )
+        onos4InstallResult = main.ONOSbench.onosInstall( options="-f",
+                                                           node=ONOS4Ip )
+        onos5InstallResult = main.ONOSbench.onosInstall( options="-f",
+                                                           node=ONOS5Ip )
+        onos6InstallResult = main.ONOSbench.onosInstall( options="-f",
+                                                           node=ONOS6Ip )
+        onos7InstallResult = main.ONOSbench.onosInstall( options="-f",
+                                                           node=ONOS7Ip )
+        onosInstallResult = onos1InstallResult and onos2InstallResult\
+            and onos3InstallResult and onos4InstallResult\
+            and onos5InstallResult and onos6InstallResult\
+            and onos7InstallResult
+
+        main.step( "Checking if ONOS is up yet" )
+        for i in range( 2 ):
+            onos1Isup = main.ONOSbench.isup( ONOS1Ip )
+            if not onos1Isup:
+                main.log.report( "ONOS1 didn't start!" )
+                main.ONOSbench.onosStop( ONOS1Ip )
+                main.ONOSbench.onosStart( ONOS1Ip )
+            onos2Isup = main.ONOSbench.isup( ONOS2Ip )
+            if not onos2Isup:
+                main.log.report( "ONOS2 didn't start!" )
+                main.ONOSbench.onosStop( ONOS2Ip )
+                main.ONOSbench.onosStart( ONOS2Ip )
+            onos3Isup = main.ONOSbench.isup( ONOS3Ip )
+            if not onos3Isup:
+                main.log.report( "ONOS3 didn't start!" )
+                main.ONOSbench.onosStop( ONOS3Ip )
+                main.ONOSbench.onosStart( ONOS3Ip )
+            onos4Isup = main.ONOSbench.isup( ONOS4Ip )
+            if not onos4Isup:
+                main.log.report( "ONOS4 didn't start!" )
+                main.ONOSbench.onosStop( ONOS4Ip )
+                main.ONOSbench.onosStart( ONOS4Ip )
+            onos5Isup = main.ONOSbench.isup( ONOS5Ip )
+            if not onos5Isup:
+                main.log.report( "ONOS5 didn't start!" )
+                main.ONOSbench.onosStop( ONOS5Ip )
+                main.ONOSbench.onosStart( ONOS5Ip )
+            onos6Isup = main.ONOSbench.isup( ONOS6Ip )
+            if not onos6Isup:
+                main.log.report( "ONOS6 didn't start!" )
+                main.ONOSbench.onosStop( ONOS6Ip )
+                main.ONOSbench.onosStart( ONOS6Ip )
+            onos7Isup = main.ONOSbench.isup( ONOS7Ip )
+            if not onos7Isup:
+                main.log.report( "ONOS7 didn't start!" )
+                main.ONOSbench.onosStop( ONOS7Ip )
+                main.ONOSbench.onosStart( ONOS7Ip )
+            onosIsupResult = onos1Isup and onos2Isup and onos3Isup\
+                and onos4Isup and onos5Isup and onos6Isup and onos7Isup
+            if onosIsupResult == main.TRUE:
+                break
+
+        cliResult1 = main.ONOScli1.startOnosCli( ONOS1Ip )
+        cliResult2 = main.ONOScli2.startOnosCli( ONOS2Ip )
+        cliResult3 = main.ONOScli3.startOnosCli( ONOS3Ip )
+        cliResult4 = main.ONOScli4.startOnosCli( ONOS4Ip )
+        cliResult5 = main.ONOScli5.startOnosCli( ONOS5Ip )
+        cliResult6 = main.ONOScli6.startOnosCli( ONOS6Ip )
+        cliResult7 = main.ONOScli7.startOnosCli( ONOS7Ip )
+        cliResults = cliResult1 and cliResult2 and cliResult3 and\
+            cliResult4 and cliResult5 and cliResult6 and cliResult7
+
+        main.step( "Start Packet Capture MN" )
+        main.Mininet2.startTcpdump(
+            str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
+            + "-MN.pcap",
+            intf=main.params[ 'MNtcpdump' ][ 'intf' ],
+            port=main.params[ 'MNtcpdump' ][ 'port' ] )
+
+        case1Result = ( cleanInstallResult and packageResult and
+                        cellResult and verifyResult and onosInstallResult
+                        and onosIsupResult and cliResults )
+
+        utilities.assert_equals( expect=main.TRUE, actual=case1Result,
+                                 onpass="Test startup successful",
+                                 onfail="Test startup NOT successful" )
+
+        if case1Result == main.FALSE:
+            main.cleanup()
+            main.exit()
+
+    def CASE2( self, main ):
+        """
+        Assign mastership to controllers
+        """
+        import re
+
+        main.log.report( "Assigning switches to controllers" )
+        main.case( "Assigning Controllers" )
+        main.step( "Assign switches to controllers" )
+
+        for i in range( 1, 29 ):
+            main.Mininet1.assignSwController(
+                sw=str( i ),
+                count=numControllers,
+                ip1=ONOS1Ip, port1=ONOS1Port,
+                ip2=ONOS2Ip, port2=ONOS2Port,
+                ip3=ONOS3Ip, port3=ONOS3Port,
+                ip4=ONOS4Ip, port4=ONOS4Port,
+                ip5=ONOS5Ip, port5=ONOS5Port,
+                ip6=ONOS6Ip, port6=ONOS6Port,
+                ip7=ONOS7Ip, port7=ONOS7Port )
+
+        mastershipCheck = main.TRUE
+        for i in range( 1, 29 ):
+            response = main.Mininet1.getSwController( "s" + str( i ) )
+            try:
+                main.log.info( str( response ) )
+            except:
+                main.log.info( repr( response ) )
+            if re.search( "tcp:" + ONOS1Ip, response )\
+                    and re.search( "tcp:" + ONOS2Ip, response )\
+                    and re.search( "tcp:" + ONOS3Ip, response )\
+                    and re.search( "tcp:" + ONOS4Ip, response )\
+                    and re.search( "tcp:" + ONOS5Ip, response )\
+                    and re.search( "tcp:" + ONOS6Ip, response )\
+                    and re.search( "tcp:" + ONOS7Ip, response ):
+                mastershipCheck = mastershipCheck and main.TRUE
+            else:
+                mastershipCheck = main.FALSE
+        if mastershipCheck == main.TRUE:
+            main.log.report( "Switch mastership assigned correctly" )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=mastershipCheck,
+            onpass="Switch mastership assigned correctly",
+            onfail="Switches not assigned correctly to controllers" )
+
+        # Manually assign mastership to the controller we want
+        roleCall = main.TRUE
+        roleCheck = main.TRUE
+
+        # Assign switch
+        deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
+        roleCall = roleCall and main.ONOScli1.deviceRole(
+            deviceId,
+            ONOS1Ip )
+        # Check assignment
+        if ONOS1Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+            roleCheck = roleCheck and main.TRUE
+        else:
+            roleCheck = roleCheck and main.FALSE
+
+        # Assign switch
+        deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
+        roleCall = roleCall and main.ONOScli1.deviceRole(
+            deviceId,
+            ONOS1Ip )
+        # Check assignment
+        if ONOS1Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+            roleCheck = roleCheck and main.TRUE
+        else:
+            roleCheck = roleCheck and main.FALSE
+
+        # Assign switch
+        deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
+        roleCall = roleCall and main.ONOScli1.deviceRole(
+            deviceId,
+            ONOS2Ip )
+        # Check assignment
+        if ONOS2Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+            roleCheck = roleCheck and main.TRUE
+        else:
+            roleCheck = roleCheck and main.FALSE
+
+        # Assign switch
+        deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
+        roleCall = roleCall and main.ONOScli1.deviceRole(
+            deviceId,
+            ONOS2Ip )
+        # Check assignment
+        if ONOS2Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+            roleCheck = roleCheck and main.TRUE
+        else:
+            roleCheck = roleCheck and main.FALSE
+
+        # Assign switch
+        deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
+        roleCall = roleCall and main.ONOScli1.deviceRole(
+            deviceId,
+            ONOS3Ip )
+        # Check assignment
+        if ONOS3Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+            roleCheck = roleCheck and main.TRUE
+        else:
+            roleCheck = roleCheck and main.FALSE
+
+        # Assign switch
+        deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
+        roleCall = roleCall and main.ONOScli1.deviceRole(
+            deviceId,
+            ONOS3Ip )
+        # Check assignment
+        if ONOS3Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+            roleCheck = roleCheck and main.TRUE
+        else:
+            roleCheck = roleCheck and main.FALSE
+
+        # Assign switch
+        deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
+        roleCall = roleCall and main.ONOScli1.deviceRole(
+            deviceId,
+            ONOS4Ip )
+        # Check assignment
+        if ONOS4Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+            roleCheck = roleCheck and main.TRUE
+        else:
+            roleCheck = roleCheck and main.FALSE
+
+        for i in range( 8, 18 ):
+            dpid = '3' + str( i ).zfill( 3 )
+            deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ONOS5Ip )
+            # Check assignment
+            if ONOS5Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+        deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
+        roleCall = roleCall and main.ONOScli1.deviceRole(
+            deviceId,
+            ONOS6Ip )
+        # Check assignment
+        if ONOS6Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+            roleCheck = roleCheck and main.TRUE
+        else:
+            roleCheck = roleCheck and main.FALSE
+
+        for i in range( 18, 28 ):
+            dpid = '6' + str( i ).zfill( 3 )
+            deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ONOS7Ip )
+            # Check assignment
+            if ONOS7Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=roleCall,
+            onpass="Re-assigned switch mastership to designated controller",
+            onfail="Something wrong with deviceRole calls" )
+
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=roleCheck,
+            onpass="Switches were successfully reassigned to designated " +
+                   "controller",
+            onfail="Switches were not successfully reassigned" )
+        mastershipCheck = mastershipCheck and roleCall and roleCheck
+        utilities.assert_equals( expect=main.TRUE, actual=mastershipCheck,
+                                 onpass="Switch mastership correctly assigned",
+                                 onfail="Error in (re)assigning switch" +
+                                 " mastership" )
+
+    def CASE3( self, main ):
+        """
+        Assign intents
+        """
+        import time
+        import json
+        main.log.report( "Adding host intents" )
+        main.case( "Adding host Intents" )
+
+        main.step( "Discovering  Hosts( Via pingall for now )" )
+        # FIXME: Once we have a host discovery mechanism, use that instead
+
+        # install onos-app-fwd
+        main.log.info( "Install reactive forwarding app" )
+        main.ONOScli1.featureInstall( "onos-app-fwd" )
+        main.ONOScli2.featureInstall( "onos-app-fwd" )
+        main.ONOScli3.featureInstall( "onos-app-fwd" )
+        main.ONOScli4.featureInstall( "onos-app-fwd" )
+        main.ONOScli5.featureInstall( "onos-app-fwd" )
+        main.ONOScli6.featureInstall( "onos-app-fwd" )
+        main.ONOScli7.featureInstall( "onos-app-fwd" )
+
+        # REACTIVE FWD test
+        pingResult = main.FALSE
+        time1 = time.time()
+        pingResult = main.Mininet1.pingall()
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=pingResult,
+            onpass="Reactive Pingall test passed",
+            onfail="Reactive Pingall failed, one or more ping pairs failed" )
+        time2 = time.time()
+        main.log.info( "Time for pingall: %2f seconds" % ( time2 - time1 ) )
+
+        # uninstall onos-app-fwd
+        main.log.info( "Uninstall reactive forwarding app" )
+        main.ONOScli1.featureUninstall( "onos-app-fwd" )
+        main.ONOScli2.featureUninstall( "onos-app-fwd" )
+        main.ONOScli3.featureUninstall( "onos-app-fwd" )
+        main.ONOScli4.featureUninstall( "onos-app-fwd" )
+        main.ONOScli5.featureUninstall( "onos-app-fwd" )
+        main.ONOScli6.featureUninstall( "onos-app-fwd" )
+        main.ONOScli7.featureUninstall( "onos-app-fwd" )
+        # timeout for fwd flows
+        time.sleep( 10 )
+
+        main.step( "Add host intents" )
+        # TODO:  move the host numbers to params
+        #        Maybe look at all the paths we ping?
+        intentAddResult = True
+        for i in range( 8, 18 ):
+            main.log.info( "Adding host intent between h" + str( i ) +
+                           " and h" + str( i + 10 ) )
+            host1 = "00:00:00:00:00:" + \
+                str( hex( i )[ 2: ] ).zfill( 2 ).upper()
+            host2 = "00:00:00:00:00:" + \
+                str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
+            # NOTE: getHost can return None
+            host1Dict = main.ONOScli1.getHost( host1 )
+            host2Dict = main.ONOScli1.getHost( host2 )
+            host1Id = None
+            host2Id = None
+            if host1Dict and host2Dict:
+                host1Id = host1Dict.get( 'id', None )
+                host2Id = host2Dict.get( 'id', None )
+            if host1Id and host2Id:
+                # distribute the intents across ONOS nodes
+                nodeNum = ( i % 7 ) + 1
+                node = getattr( main, ( 'ONOScli' + str( nodeNum ) ) )
+                tmpResult = node.addHostIntent(
+                    host1Id,
+                    host2Id )
+            else:
+                main.log.error( "Error, getHost() failed" )
+                main.log.warn( json.dumps( json.loads( main.ONOScli1.hosts() ),
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+                tmpResult = main.FALSE
+            intentAddResult = bool( pingResult and intentAddResult
+                                     and tmpResult )
+            # FIXME Check that intents were added?
+            # TODO Use the new return from add host command and look at each
+            #      intent individually
+            #
+            #
+            #
+            #
+            #
+            #
+        # End of for loop to add intents
+        # Print the intent states
+        intents = main.ONOScli1.intents( )
+        intentStates = []
+        for intent in json.loads( intents ):  # Iter through intents of a node
+            intentStates.append( intent.get( 'state', None ) )
+        out = [ (i, intentStates.count( i ) ) for i in set( intentStates ) ]
+        main.log.info( dict( out ) )
+
+        utilities.assert_equals(
+            expect=True,
+            actual=intentAddResult,
+            onpass="Pushed host intents to ONOS",
+            onfail="Error in pushing host intents to ONOS" )
+        # TODO Check if intents all exist in datastore
+
+    def CASE4( self, main ):
+        """
+        Ping across added host intents
+        """
+        import json
+        description = " Ping across added host intents"
+        main.log.report( description )
+        main.case( description )
+        PingResult = main.TRUE
+        for i in range( 8, 18 ):
+            ping = main.Mininet1.pingHost(
+                src="h" + str( i ), target="h" + str( i + 10 ) )
+            PingResult = PingResult and ping
+            if ping == main.FALSE:
+                main.log.warn( "Ping failed between h" + str( i ) +
+                               " and h" + str( i + 10 ) )
+            elif ping == main.TRUE:
+                main.log.info( "Ping test passed!" )
+                # Don't set PingResult or you'd override failures
+        if PingResult == main.FALSE:
+            main.log.report(
+                "Intents have not been installed correctly, pings failed." )
+            main.log.warn( "ONOS1 intents: " )
+            main.log.warn( json.dumps( json.loads( main.ONOScli1.intents() ),
+                                       sort_keys=True,
+                                       indent=4,
+                                       separators=( ',', ': ' ) ) )
+        if PingResult == main.TRUE:
+            main.log.report(
+                "Intents have been installed correctly and verified by pings" )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=PingResult,
+            onpass="Intents have been installed correctly and pings work",
+            onfail="Intents have not been installed correctly, pings failed." )
+
+    def CASE5( self, main ):
+        """
+        Reading state of ONOS
+        """
+        import json
+        # assumes that sts is already in you PYTHONPATH
+        from sts.topology.teston_topology import TestONTopology
+
+        main.log.report( "Setting up and gathering data for current state" )
+        main.case( "Setting up and gathering data for current state" )
+        # The general idea for this test case is to pull the state of
+        # ( intents,flows, topology,... ) from each ONOS node
+        # We can then compare them with eachother and also with past states
+
+        main.step( "Get the Mastership of each switch from each controller" )
+        global mastershipState
+        mastershipState = []
+
+        # Assert that each device has a master
+        ONOS1MasterNotNull = main.ONOScli1.rolesNotNull()
+        ONOS2MasterNotNull = main.ONOScli2.rolesNotNull()
+        ONOS3MasterNotNull = main.ONOScli3.rolesNotNull()
+        ONOS4MasterNotNull = main.ONOScli4.rolesNotNull()
+        ONOS5MasterNotNull = main.ONOScli5.rolesNotNull()
+        ONOS6MasterNotNull = main.ONOScli6.rolesNotNull()
+        ONOS7MasterNotNull = main.ONOScli7.rolesNotNull()
+        rolesNotNull = ONOS1MasterNotNull and ONOS2MasterNotNull and\
+            ONOS3MasterNotNull and ONOS4MasterNotNull and\
+            ONOS5MasterNotNull and ONOS6MasterNotNull and\
+            ONOS7MasterNotNull
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=rolesNotNull,
+            onpass="Each device has a master",
+            onfail="Some devices don't have a master assigned" )
+
+        ONOS1Mastership = main.ONOScli1.roles()
+        ONOS2Mastership = main.ONOScli2.roles()
+        ONOS3Mastership = main.ONOScli3.roles()
+        ONOS4Mastership = main.ONOScli4.roles()
+        ONOS5Mastership = main.ONOScli5.roles()
+        ONOS6Mastership = main.ONOScli6.roles()
+        ONOS7Mastership = main.ONOScli7.roles()
+        if "Error" in ONOS1Mastership or not ONOS1Mastership\
+                or "Error" in ONOS2Mastership or not ONOS2Mastership\
+                or "Error" in ONOS3Mastership or not ONOS3Mastership\
+                or "Error" in ONOS4Mastership or not ONOS4Mastership\
+                or "Error" in ONOS5Mastership or not ONOS5Mastership\
+                or "Error" in ONOS6Mastership or not ONOS6Mastership\
+                or "Error" in ONOS7Mastership or not ONOS7Mastership:
+            main.log.report( "Error in getting ONOS roles" )
+            for i in range( 1, numControllers + 1 ):
+                mastership = eval( "ONOS" + str( i ) + "Mastership" )
+                main.log.warn(
+                    "ONOS" + str( i ) + " mastership response: " +
+                    repr( mastership ) )
+            consistentMastership = main.FALSE
+        elif ONOS1Mastership == ONOS2Mastership\
+                and ONOS1Mastership == ONOS3Mastership\
+                and ONOS1Mastership == ONOS4Mastership\
+                and ONOS1Mastership == ONOS5Mastership\
+                and ONOS1Mastership == ONOS6Mastership\
+                and ONOS1Mastership == ONOS7Mastership:
+            mastershipState = ONOS1Mastership
+            consistentMastership = main.TRUE
+            main.log.report(
+                "Switch roles are consistent across all ONOS nodes" )
+        else:
+            for i in range( 1, numControllers + 1 ):
+                mastership = eval( "ONOS" + str( i ) + "Mastership" )
+                main.log.warn( "ONOS" + str( i ) + " roles: " +
+                               json.dumps( json.loads( mastership ),
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+            consistentMastership = main.FALSE
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=consistentMastership,
+            onpass="Switch roles are consistent across all ONOS nodes",
+            onfail="ONOS nodes have different views of switch roles" )
+
+        main.step( "Get the intents from each controller" )
+        global intentState
+        intentState = []
+        ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
+        ONOS2Intents = main.ONOScli2.intents( jsonFormat=True )
+        ONOS3Intents = main.ONOScli3.intents( jsonFormat=True )
+        ONOS4Intents = main.ONOScli4.intents( jsonFormat=True )
+        ONOS5Intents = main.ONOScli5.intents( jsonFormat=True )
+        ONOS6Intents = main.ONOScli6.intents( jsonFormat=True )
+        ONOS7Intents = main.ONOScli7.intents( jsonFormat=True )
+        intentCheck = main.FALSE
+        if "Error" in ONOS1Intents or not ONOS1Intents\
+                or "Error" in ONOS2Intents or not ONOS2Intents\
+                or "Error" in ONOS3Intents or not ONOS3Intents\
+                or "Error" in ONOS4Intents or not ONOS4Intents\
+                or "Error" in ONOS5Intents or not ONOS5Intents\
+                or "Error" in ONOS6Intents or not ONOS6Intents\
+                or "Error" in ONOS7Intents or not ONOS7Intents:
+            main.log.report( "Error in getting ONOS intents" )
+            for i in range( 1, numControllers + 1 ):
+                intents = eval( "ONOS" + str( i ) + "Intents" )
+                main.log.warn(
+                    "ONOS" + str( i ) + " intents response: " +
+                    repr( intents ) )
+        elif ONOS1Intents == ONOS2Intents\
+                and ONOS1Intents == ONOS3Intents\
+                and ONOS1Intents == ONOS4Intents\
+                and ONOS1Intents == ONOS5Intents\
+                and ONOS1Intents == ONOS6Intents\
+                and ONOS1Intents == ONOS7Intents:
+            intentState = ONOS1Intents
+            intentCheck = main.TRUE
+            main.log.report( "Intents are consistent across all ONOS nodes" )
+        else:
+            for i in range( 1, numControllers + 1 ):
+                intents = eval( "ONOS" + str( i ) + "Intents" )
+                main.log.warn( "ONOS" + str( i ) + " intents: " +
+                               json.dumps( json.loads( intents ),
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=intentCheck,
+            onpass="Intents are consistent across all ONOS nodes",
+            onfail="ONOS nodes have different views of intents" )
+
+        main.step( "Get the flows from each controller" )
+        global flowState
+        flowState = []
+        ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
+        ONOS2Flows = main.ONOScli2.flows( jsonFormat=True )
+        ONOS3Flows = main.ONOScli3.flows( jsonFormat=True )
+        ONOS4Flows = main.ONOScli4.flows( jsonFormat=True )
+        ONOS5Flows = main.ONOScli5.flows( jsonFormat=True )
+        ONOS6Flows = main.ONOScli6.flows( jsonFormat=True )
+        ONOS7Flows = main.ONOScli7.flows( jsonFormat=True )
+        ONOS1FlowsJson = json.loads( ONOS1Flows )
+        ONOS2FlowsJson = json.loads( ONOS2Flows )
+        ONOS3FlowsJson = json.loads( ONOS3Flows )
+        ONOS4FlowsJson = json.loads( ONOS4Flows )
+        ONOS5FlowsJson = json.loads( ONOS5Flows )
+        ONOS6FlowsJson = json.loads( ONOS6Flows )
+        ONOS7FlowsJson = json.loads( ONOS7Flows )
+        flowCheck = main.FALSE
+        if "Error" in ONOS1Flows or not ONOS1Flows\
+                or "Error" in ONOS2Flows or not ONOS2Flows\
+                or "Error" in ONOS3Flows or not ONOS3Flows\
+                or "Error" in ONOS4Flows or not ONOS4Flows\
+                or "Error" in ONOS5Flows or not ONOS5Flows\
+                or "Error" in ONOS6Flows or not ONOS6Flows\
+                or "Error" in ONOS7Flows or not ONOS7Flows:
+            main.log.report( "Error in getting ONOS intents" )
+            for i in range( 1, numControllers + 1 ):
+                flowsIter = eval( "ONOS" + str( i ) + "Flows" )
+                main.log.warn( "ONOS" + str( i ) + " flows repsponse: " +
+                               flowsIter )
+        elif len( ONOS1FlowsJson ) == len( ONOS2FlowsJson )\
+                and len( ONOS1FlowsJson ) == len( ONOS3FlowsJson )\
+                and len( ONOS1FlowsJson ) == len( ONOS4FlowsJson )\
+                and len( ONOS1FlowsJson ) == len( ONOS5FlowsJson )\
+                and len( ONOS1FlowsJson ) == len( ONOS6FlowsJson )\
+                and len( ONOS1FlowsJson ) == len( ONOS7FlowsJson ):
+                # TODO: Do a better check, maybe compare flows on switches?
+            flowState = ONOS1Flows
+            flowCheck = main.TRUE
+            main.log.report( "Flow count is consistent across all ONOS nodes" )
+        else:
+            for i in range( 1, numControllers + 1 ):
+                flowsJson = eval( "ONOS" + str( i ) + "FlowsJson" )
+                main.log.warn( "ONOS" + str( i ) + " flows repsponse: " +
+                               json.dumps( flowsJson,
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=flowCheck,
+            onpass="The flow count is consistent across all ONOS nodes",
+            onfail="ONOS nodes have different flow counts" )
+
+        main.step( "Get the OF Table entries" )
+        global flows
+        flows = []
+        for i in range( 1, 29 ):
+            flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
+
+        # TODO: Compare switch flow tables with ONOS flow tables
+
+        main.step( "Start continuous pings" )
+        for i in range( 1, 11 ):
+            source = main.params[ 'PING' ][ 'source' + str( i ) ]
+            target = main.params[ 'PING' ][ 'target' + str( i ) ]
+            main.Mininet2.pingLong(
+                src=source,
+                target=target,
+                pingTime=500 )
+        main.step( "Create TestONTopology object" )
+        ctrls = []
+        count = 1
+        while True:
+            temp = ()
+            if ( 'ip' + str( count ) ) in main.params[ 'CTRL' ]:
+                temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
+                temp = temp + ( "ONOS" + str( count ), )
+                temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
+                temp = temp + \
+                    ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
+                ctrls.append( temp )
+                count = count + 1
+            else:
+                break
+        MNTopo = TestONTopology(
+            main.Mininet1,
+            ctrls )  # can also add Intent API info for intent operations
+
+        main.step( "Collecting topology information from ONOS" )
+        # TODO Refactor to a loop? We want all similar calls together?
+        #      So get all "devices" as close together as possible
+        devices = []
+        print "ONOS1"
+        devices.append( main.ONOScli1.devices() )
+        print "ONOS2"
+        devices.append( main.ONOScli2.devices() )
+        print "ONOS3"
+        devices.append( main.ONOScli3.devices() )
+        print "ONOS4"
+        devices.append( main.ONOScli4.devices() )
+        print "ONOS5"
+        devices.append( main.ONOScli5.devices() )
+        print "ONOS6"
+        devices.append( main.ONOScli6.devices() )
+        print "ONOS7"
+        devices.append( main.ONOScli7.devices() )
+        hosts = []
+        hosts.append( main.ONOScli1.hosts() )
+        hosts.append( main.ONOScli2.hosts() )
+        hosts.append( main.ONOScli3.hosts() )
+        hosts.append( main.ONOScli4.hosts() )
+        hosts.append( main.ONOScli5.hosts() )
+        hosts.append( main.ONOScli6.hosts() )
+        hosts.append( main.ONOScli7.hosts() )
+        ports = []
+        ports.append( main.ONOScli1.ports() )
+        ports.append( main.ONOScli2.ports() )
+        ports.append( main.ONOScli3.ports() )
+        ports.append( main.ONOScli4.ports() )
+        ports.append( main.ONOScli5.ports() )
+        ports.append( main.ONOScli6.ports() )
+        ports.append( main.ONOScli7.ports() )
+        links = []
+        links.append( main.ONOScli1.links() )
+        links.append( main.ONOScli2.links() )
+        links.append( main.ONOScli3.links() )
+        links.append( main.ONOScli4.links() )
+        links.append( main.ONOScli5.links() )
+        links.append( main.ONOScli6.links() )
+        links.append( main.ONOScli7.links() )
+        clusters = []
+        clusters.append( main.ONOScli1.clusters() )
+        clusters.append( main.ONOScli2.clusters() )
+        clusters.append( main.ONOScli3.clusters() )
+        clusters.append( main.ONOScli4.clusters() )
+        clusters.append( main.ONOScli5.clusters() )
+        clusters.append( main.ONOScli6.clusters() )
+        clusters.append( main.ONOScli7.clusters() )
+        # Compare json objects for hosts and dataplane clusters
+
+        # hosts
+        consistentHostsResult = main.TRUE
+        for controller in range( len( hosts ) ):
+            controllerStr = str( controller + 1 )
+            if "Error" not in hosts[ controller ]:
+                if hosts[ controller ] == hosts[ 0 ]:
+                    continue
+                else:  # hosts not consistent
+                    main.log.report( "hosts from ONOS" +
+                                     controllerStr +
+                                     " is inconsistent with ONOS1" )
+                    main.log.warn( repr( hosts[ controller ] ) )
+                    consistentHostsResult = main.FALSE
+
+            else:
+                main.log.report( "Error in getting ONOS hosts from ONOS" +
+                                 controllerStr )
+                consistentHostsResult = main.FALSE
+                main.log.warn( "ONOS" + controllerStr +
+                               " hosts response: " +
+                               repr( hosts[ controller ] ) )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=consistentHostsResult,
+            onpass="Hosts view is consistent across all ONOS nodes",
+            onfail="ONOS nodes have different views of hosts" )
+
+        # Strongly connected clusters of devices
+        consistentClustersResult = main.TRUE
+        for controller in range( len( clusters ) ):
+            if "Error" not in clusters[ controller ]:
+                if clusters[ controller ] == clusters[ 0 ]:
+                    continue
+                else:  # clusters not consistent
+                    main.log.report( "clusters from ONOS" +
+                                     controllerStr +
+                                     " is inconsistent with ONOS1" )
+                    consistentClustersResult = main.FALSE
+
+            else:
+                main.log.report( "Error in getting dataplane clusters " +
+                                 "from ONOS" + controllerStr )
+                consistentClustersResult = main.FALSE
+                main.log.warn( "ONOS" + controllerStr +
+                               " clusters response: " +
+                               repr( clusters[ controller ] ) )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=consistentClustersResult,
+            onpass="Clusters view is consistent across all ONOS nodes",
+            onfail="ONOS nodes have different views of clusters" )
+        # there should always only be one cluster
+        numClusters = len( json.loads( clusters[ 0 ] ) )
+        utilities.assert_equals(
+            expect=1,
+            actual=numClusters,
+            onpass="ONOS shows 1 SCC",
+            onfail="ONOS shows " +
+            str( numClusters ) +
+            " SCCs" )
+
+        main.step( "Comparing ONOS topology to MN" )
+        devicesResults = main.TRUE
+        portsResults = main.TRUE
+        linksResults = main.TRUE
+        for controller in range( numControllers ):
+            controllerStr = str( controller + 1 )
+            if devices[ controller ] or "Error" not in devices[ controller ]:
+                currentDevicesResult = main.Mininet1.compareSwitches(
+                    MNTopo,
+                    json.loads(
+                        devices[ 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 ports[ controller ] or "Error" not in ports[ controller ]:
+                currentPortsResult = main.Mininet1.comparePorts(
+                    MNTopo,
+                    json.loads(
+                        ports[ controller ] ) )
+            else:
+                currentPortsResult = main.FALSE
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=currentPortsResult,
+                                     onpass="ONOS" + controllerStr +
+                                     " ports view is correct",
+                                     onfail="ONOS" + controllerStr +
+                                     " ports view is incorrect" )
+
+            if links[ controller ] or "Error" not in links[ controller ]:
+                currentLinksResult = main.Mininet1.compareLinks(
+                    MNTopo,
+                    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" )
+
+            devicesResults = devicesResults and currentDevicesResult
+            portsResults = portsResults and currentPortsResult
+            linksResults = linksResults and currentLinksResult
+
+        topoResult = devicesResults and portsResults and linksResults\
+            and consistentHostsResult and consistentClustersResult
+        utilities.assert_equals( expect=main.TRUE, actual=topoResult,
+                                 onpass="Topology Check Test successful",
+                                 onfail="Topology Check Test NOT successful" )
+
+        finalAssert = main.TRUE
+        finalAssert = finalAssert and topoResult and flowCheck \
+            and intentCheck and consistentMastership and rolesNotNull
+        utilities.assert_equals( expect=main.TRUE, actual=finalAssert,
+                                 onpass="State check successful",
+                                 onfail="State check NOT successful" )
+
+    def CASE6( self, main ):
+        """
+        The Failure case. We will create IPTables rules here.
+        """
+        import time
+        main.log.report( "Wait 30 seconds instead of inducing a failure" )
+        time.sleep( 30 )
+
+        # 1 blocks 4,5,6,7, mn
+        # 2 blocks 4,5,6,7, mn
+        # 3 blocks 4,5,6,7, mn
+        # 4 block 1,2,3
+        # 5 blocks 1,2,3
+        # 6 blocks 1,2,3
+        # 7 blocks 1,2,3
+
+        # TODO: use new log command
+        logcmd = "log:log \" About to partition the ONOS nodes\""
+        main.ONOScli1.handle.sendline( logcmd )
+        main.ONOScli1.handle.expect( "onos>" )
+        print main.ONOScli1.handle.before
+        main.ONOScli2.handle.sendline( logcmd )
+        main.ONOScli2.handle.expect( "onos>" )
+        print main.ONOScli2.handle.before
+        main.ONOScli3.handle.sendline( logcmd )
+        main.ONOScli3.handle.expect( "onos>" )
+        print main.ONOScli3.handle.before
+        main.ONOScli4.handle.sendline( logcmd )
+        main.ONOScli4.handle.expect( "onos>" )
+        print main.ONOScli4.handle.before
+        main.ONOScli5.handle.sendline( logcmd )
+        main.ONOScli5.handle.expect( "onos>" )
+        print main.ONOScli5.handle.before
+        main.ONOScli6.handle.sendline( logcmd )
+        main.ONOScli6.handle.expect( "onos>" )
+        print main.ONOScli6.handle.before
+        main.ONOScli7.handle.sendline( logcmd )
+        main.ONOScli7.handle.expect( "onos>" )
+        print main.ONOScli7.handle.before
+
+        nodes = []
+        #create list of ONOS components
+        for controller in range( 1, numControllers + 1 ):
+            # loop through ONOS handlers
+            node = getattr( main, ( 'ONOS' + str( controller ) ) )
+            nodes.append( node )
+        for node in nodes:
+            # if node is in first half (rounded down )
+            # ( 0 through 2 ) < ( 3.5 - 1)
+            if nodes.index( node ) < ( numControllers / 2.0 - 1 ):
+                # blocked nodes are the last half ( rounded up )
+                # // is forced integer division
+                for blockNode in nodes[ (numControllers // 2 + 1) * -1: ]:
+                    # block all traffic between these ONOS nodes
+                    # NOTE: ONOS 1 and 2 don't support state tracking
+                    node.setIpTables( blockNode.ip_address, states=False )
+                    node.setIpTables( blockNode.ip_address,
+                                      direction="OUTPUT" , states=False )
+                # block traffic between smaller subcluster and Mininet
+                # TODO make OF controller port confgigurable
+                # FIXME Remove this once ONOS can deal with the conflicting
+                #       device mastership
+                node.setIpTables( main.Mininet1.ip_address, 6633,
+                                  packet_type="tcp", states=False )
+            else:  # the larger subcluster
+                # blocked nodes are the first half
+                for blockNode in nodes[ :(numControllers // 2 ) ]:
+                    # block all traffic between these ONOS nodes
+                    node.setIpTables( blockNode.ip_address )
+                    node.setIpTables( blockNode.ip_address,
+                                      direction="OUTPUT" )
+        #FIXME update this
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=main.TRUE,
+            onpass="Sleeping 30 seconds",
+            onfail="Something is terribly wrong with my math" )
+        main.ONOScli1.handle.sendline( "devices -j" )
+        main.ONOScli1.handle.expect( ["onos>", "\$"] )
+        print main.ONOScli1.handle.before
+        main.ONOScli2.handle.sendline( "devices -j" )
+        main.ONOScli2.handle.expect( ["onos>", "\$"] )
+        print main.ONOScli2.handle.before
+        main.ONOScli3.handle.sendline( "devices -j" )
+        main.ONOScli3.handle.expect( ["onos>", "\$"] )
+        print main.ONOScli3.handle.before
+        main.ONOScli4.handle.sendline( "devices -j" )
+        main.ONOScli4.handle.expect( ["onos>", "\$"] )
+        print main.ONOScli4.handle.before
+        main.ONOScli5.handle.sendline( "devices -j" )
+        main.ONOScli5.handle.expect( ["onos>", "\$"] )
+        print main.ONOScli5.handle.before
+        main.ONOScli6.handle.sendline( "devices -j" )
+        main.ONOScli6.handle.expect( ["onos>", "\$"] )
+        print main.ONOScli6.handle.before
+        main.ONOScli7.handle.sendline( "devices -j" )
+        main.ONOScli7.handle.expect( ["onos>", "\$"] )
+        print main.ONOScli7.handle.before
+        time.sleep(100000)
+
+
+    def CASE7( self, main ):
+        """
+        Check state after ONOS failure
+        """
+        import json
+        main.case( "Running ONOS Constant State Tests" )
+
+        # Assert that each device has a master
+        ONOS1MasterNotNull = main.ONOScli1.rolesNotNull()
+        ONOS2MasterNotNull = main.ONOScli2.rolesNotNull()
+        ONOS3MasterNotNull = main.ONOScli3.rolesNotNull()
+        ONOS4MasterNotNull = main.ONOScli4.rolesNotNull()
+        ONOS5MasterNotNull = main.ONOScli5.rolesNotNull()
+        ONOS6MasterNotNull = main.ONOScli6.rolesNotNull()
+        ONOS7MasterNotNull = main.ONOScli7.rolesNotNull()
+        rolesNotNull = ONOS1MasterNotNull and ONOS2MasterNotNull and\
+            ONOS3MasterNotNull and ONOS4MasterNotNull and\
+            ONOS5MasterNotNull and ONOS6MasterNotNull and\
+            ONOS7MasterNotNull
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=rolesNotNull,
+            onpass="Each device has a master",
+            onfail="Some devices don't have a master assigned" )
+
+        main.step( "Check if switch roles are consistent across all nodes" )
+        ONOS1Mastership = main.ONOScli1.roles()
+        ONOS2Mastership = main.ONOScli2.roles()
+        ONOS3Mastership = main.ONOScli3.roles()
+        ONOS4Mastership = main.ONOScli4.roles()
+        ONOS5Mastership = main.ONOScli5.roles()
+        ONOS6Mastership = main.ONOScli6.roles()
+        ONOS7Mastership = main.ONOScli7.roles()
+        if "Error" in ONOS1Mastership or not ONOS1Mastership\
+                or "Error" in ONOS2Mastership or not ONOS2Mastership\
+                or "Error" in ONOS3Mastership or not ONOS3Mastership\
+                or "Error" in ONOS4Mastership or not ONOS4Mastership\
+                or "Error" in ONOS5Mastership or not ONOS5Mastership\
+                or "Error" in ONOS6Mastership or not ONOS6Mastership\
+                or "Error" in ONOS7Mastership or not ONOS7Mastership:
+            main.log.error( "Error in getting ONOS mastership" )
+            main.log.warn( "ONOS1 mastership response: " +
+                           repr( ONOS1Mastership ) )
+            main.log.warn( "ONOS2 mastership response: " +
+                           repr( ONOS2Mastership ) )
+            main.log.warn( "ONOS3 mastership response: " +
+                           repr( ONOS3Mastership ) )
+            main.log.warn( "ONOS4 mastership response: " +
+                           repr( ONOS4Mastership ) )
+            main.log.warn( "ONOS5 mastership response: " +
+                           repr( ONOS5Mastership ) )
+            main.log.warn( "ONOS6 mastership response: " +
+                           repr( ONOS6Mastership ) )
+            main.log.warn( "ONOS7 mastership response: " +
+                           repr( ONOS7Mastership ) )
+            consistentMastership = main.FALSE
+        elif ONOS1Mastership == ONOS2Mastership\
+                and ONOS1Mastership == ONOS3Mastership\
+                and ONOS1Mastership == ONOS4Mastership\
+                and ONOS1Mastership == ONOS5Mastership\
+                and ONOS1Mastership == ONOS6Mastership\
+                and ONOS1Mastership == ONOS7Mastership:
+            consistentMastership = main.TRUE
+            main.log.report(
+                "Switch roles are consistent across all ONOS nodes" )
+        else:
+            for i in range( 1, numControllers + 1 ):
+                mastership = eval( "ONOS" + str( i ) + "Mastership" )
+                main.log.warn( "ONOS" + str( i ) + " roles: " +
+                               json.dumps( json.loads( mastership ),
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+            consistentMastership = main.FALSE
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=consistentMastership,
+            onpass="Switch roles are consistent across all ONOS nodes",
+            onfail="ONOS nodes have different views of switch roles" )
+
+        description2 = "Compare switch roles from before failure"
+        main.step( description2 )
+
+        currentJson = json.loads( ONOS1Mastership )
+        oldJson = json.loads( mastershipState )
+        mastershipCheck = main.TRUE
+        for i in range( 1, 29 ):
+            switchDPID = str(
+                main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
+
+            current = [ switch[ 'master' ] for switch in currentJson
+                        if switchDPID in switch[ 'id' ] ]
+            old = [ switch[ 'master' ] for switch in oldJson
+                    if switchDPID in switch[ 'id' ] ]
+            if current == old:
+                mastershipCheck = mastershipCheck and main.TRUE
+            else:
+                main.log.warn( "Mastership of switch %s changed" % switchDPID )
+                mastershipCheck = main.FALSE
+        if mastershipCheck == main.TRUE:
+            main.log.report( "Mastership of Switches was not changed" )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=mastershipCheck,
+            onpass="Mastership of Switches was not changed",
+            onfail="Mastership of some switches changed" )
+        mastershipCheck = mastershipCheck and consistentMastership
+
+        main.step( "Get the intents and compare across all nodes" )
+        ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
+        ONOS2Intents = main.ONOScli2.intents( jsonFormat=True )
+        ONOS3Intents = main.ONOScli3.intents( jsonFormat=True )
+        ONOS4Intents = main.ONOScli4.intents( jsonFormat=True )
+        ONOS5Intents = main.ONOScli5.intents( jsonFormat=True )
+        ONOS6Intents = main.ONOScli6.intents( jsonFormat=True )
+        ONOS7Intents = main.ONOScli7.intents( jsonFormat=True )
+        intentCheck = main.FALSE
+        if "Error" in ONOS1Intents or not ONOS1Intents\
+                or "Error" in ONOS2Intents or not ONOS2Intents\
+                or "Error" in ONOS3Intents or not ONOS3Intents\
+                or "Error" in ONOS4Intents or not ONOS4Intents\
+                or "Error" in ONOS5Intents or not ONOS5Intents\
+                or "Error" in ONOS6Intents or not ONOS6Intents\
+                or "Error" in ONOS7Intents or not ONOS7Intents:
+            main.log.report( "Error in getting ONOS intents" )
+            main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
+            main.log.warn( "ONOS2 intents response: " + repr( ONOS2Intents ) )
+            main.log.warn( "ONOS3 intents response: " + repr( ONOS3Intents ) )
+            main.log.warn( "ONOS4 intents response: " + repr( ONOS4Intents ) )
+            main.log.warn( "ONOS5 intents response: " + repr( ONOS5Intents ) )
+            main.log.warn( "ONOS6 intents response: " + repr( ONOS6Intents ) )
+            main.log.warn( "ONOS7 intents response: " + repr( ONOS7Intents ) )
+        elif ONOS1Intents == ONOS2Intents\
+                and ONOS1Intents == ONOS3Intents\
+                and ONOS1Intents == ONOS4Intents\
+                and ONOS1Intents == ONOS5Intents\
+                and ONOS1Intents == ONOS6Intents\
+                and ONOS1Intents == ONOS7Intents:
+            intentCheck = main.TRUE
+            main.log.report( "Intents are consistent across all ONOS nodes" )
+        else:
+            for i in range( 1, numControllers + 1 ):
+                intents = eval( "ONOS" + str( i ) + "Intents" )
+                main.log.warn( "ONOS" + str( i ) + " intents: " +
+                               json.dumps( json.loads( ONOS1Intents ),
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=intentCheck,
+            onpass="Intents are consistent across all ONOS nodes",
+            onfail="ONOS nodes have different views of intents" )
+        # Print the intent states
+        intents = []
+        intents.append( ONOS1Intents )
+        intents.append( ONOS2Intents )
+        intents.append( ONOS3Intents )
+        intents.append( ONOS4Intents )
+        intents.append( ONOS5Intents )
+        intents.append( ONOS6Intents )
+        intents.append( ONOS7Intents )
+        intentStates = []
+        for node in intents:  # Iter through ONOS nodes
+            nodeStates = []
+            for intent in json.loads( node ):  # Iter through intents of a node
+                nodeStates.append( intent[ 'state' ] )
+            intentStates.append( nodeStates )
+            out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
+            main.log.info( dict( out ) )
+        # NOTE: Hazelcast has no durability, so intents are lost across system
+        # restarts
+        main.step( "Compare current intents with intents before the failure" )
+        # NOTE: this requires case 5 to pass for intentState to be set.
+        #      maybe we should stop the test if that fails?
+        sameIntents = main.TRUE
+        if intentState and intentState == ONOS1Intents:
+            sameIntents = main.TRUE
+            main.log.report( "Intents are consistent with before failure" )
+        # TODO: possibly the states have changed? we may need to figure out
+        # what the aceptable states are
+        else:
+            try:
+                main.log.warn( "ONOS1 intents: " )
+                print json.dumps( json.loads( ONOS1Intents ),
+                                  sort_keys=True, indent=4,
+                                  separators=( ',', ': ' ) )
+            except:
+                pass
+            sameIntents = main.FALSE
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=sameIntents,
+            onpass="Intents are consistent with before failure",
+            onfail="The Intents changed during failure" )
+        intentCheck = intentCheck and sameIntents
+
+        main.step( "Get the OF Table entries and compare to before " +
+                   "component failure" )
+        FlowTables = main.TRUE
+        flows2 = []
+        for i in range( 28 ):
+            main.log.info( "Checking flow table on s" + str( i + 1 ) )
+            tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
+            flows2.append( tmpFlows )
+            tempResult = main.Mininet2.flowComp(
+                flow1=flows[ i ],
+                flow2=tmpFlows )
+            FlowTables = FlowTables and tempResult
+            if FlowTables == main.FALSE:
+                main.log.info( "Differences in flow table for switch: s" +
+                               str( i + 1 ) )
+        if FlowTables == main.TRUE:
+            main.log.report( "No changes were found in the flow tables" )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=FlowTables,
+            onpass="No changes were found in the flow tables",
+            onfail="Changes were found in the flow tables" )
+
+        main.step( "Check the continuous pings to ensure that no packets " +
+                   "were dropped during component failure" )
+        # FIXME: This check is always failing. Investigate cause
+        # NOTE:  this may be something to do with file permsissions
+        #       or slight change in format
+        main.Mininet2.pingKill(
+            main.params[ 'TESTONUSER' ],
+            main.params[ 'TESTONIP' ] )
+        LossInPings = main.FALSE
+        # NOTE: checkForLoss returns main.FALSE with 0% packet loss
+        for i in range( 8, 18 ):
+            main.log.info(
+                "Checking for a loss in pings along flow from s" +
+                str( i ) )
+            LossInPings = main.Mininet2.checkForLoss(
+                "/tmp/ping.h" +
+                str( i ) ) or LossInPings
+        if LossInPings == main.TRUE:
+            main.log.info( "Loss in ping detected" )
+        elif LossInPings == main.ERROR:
+            main.log.info( "There are multiple mininet process running" )
+        elif LossInPings == main.FALSE:
+            main.log.info( "No Loss in the pings" )
+            main.log.report( "No loss of dataplane connectivity" )
+        utilities.assert_equals(
+            expect=main.FALSE,
+            actual=LossInPings,
+            onpass="No Loss of connectivity",
+            onfail="Loss of dataplane connectivity detected" )
+
+        # Test of LeadershipElection
+        # FIXME Update this for network partition case
+        # NOTE: this only works for the sanity test. In case of failures,
+        # leader will likely change
+        leader = ONOS1Ip
+        leaderResult = main.TRUE
+        for controller in range( 1, numControllers + 1 ):
+            # loop through ONOScli handlers
+            node = getattr( main, ( 'ONOScli' + str( controller ) ) )
+            leaderN = node.electionTestLeader()
+            # verify leader is ONOS1
+            if leaderN == leader:
+                # all is well
+                # NOTE: In failure scenario, this could be a new node, maybe
+                # check != ONOS1
+                pass
+            elif leaderN == main.FALSE:
+                # error in  response
+                main.log.report( "Something is wrong with " +
+                                 "electionTestLeader function," +
+                                 " check the error logs" )
+                leaderResult = main.FALSE
+            elif leader != leaderN:
+                leaderResult = main.FALSE
+                main.log.report( "ONOS" + str( controller ) + " sees " +
+                                 str( leaderN ) +
+                                 " as the leader of the election app. " +
+                                 "Leader should be " + str( leader ) )
+        if leaderResult:
+            main.log.report( "Leadership election tests passed( consistent " +
+                             "view of leader across listeners and a new " +
+                             "leader was re-elected if applicable )" )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=leaderResult,
+            onpass="Leadership election passed",
+            onfail="Something went wrong with Leadership election" )
+
+        result = mastershipCheck and intentCheck and FlowTables and\
+            ( not LossInPings ) and rolesNotNull and leaderResult
+        result = int( result )
+        if result == main.TRUE:
+            main.log.report( "Constant State Tests Passed" )
+        utilities.assert_equals( expect=main.TRUE, actual=result,
+                                 onpass="Constant State Tests Passed",
+                                 onfail="Constant state tests failed" )
+
+    def CASE8( self, main ):
+        """
+        Compare topo
+        """
+        import sys
+        # FIXME add this path to params
+        sys.path.append( "/home/admin/sts" )
+        # assumes that sts is already in you PYTHONPATH
+        from sts.topology.teston_topology import TestONTopology
+        import json
+        import time
+
+        description = "Compare ONOS Topology view to Mininet topology"
+        main.case( description )
+        main.log.report( description )
+        main.step( "Create TestONTopology object" )
+        ctrls = []
+        count = 1
+        while True:
+            temp = ()
+            if ( 'ip' + str( count ) ) in main.params[ 'CTRL' ]:
+                temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
+                temp = temp + ( "ONOS" + str( count ), )
+                temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
+                temp = temp + \
+                    ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
+                ctrls.append( temp )
+                count = count + 1
+            else:
+                break
+        MNTopo = TestONTopology(
+            main.Mininet1,
+            ctrls )  # can also add Intent API info for intent operations
+
+        main.step( "Comparing ONOS topology to MN" )
+        devicesResults = main.TRUE
+        portsResults = main.TRUE
+        linksResults = main.TRUE
+        topoResult = main.FALSE
+        elapsed = 0
+        count = 0
+        main.step( "Collecting topology information from ONOS" )
+        startTime = time.time()
+        # Give time for Gossip to work
+        while topoResult == main.FALSE and elapsed < 60:
+            count = count + 1
+            if count > 1:
+                # TODO: Depricate STS usage
+                MNTopo = TestONTopology(
+                    main.Mininet1,
+                    ctrls )
+            cliStart = time.time()
+            devices = []
+            devices.append( main.ONOScli1.devices() )
+            devices.append( main.ONOScli2.devices() )
+            devices.append( main.ONOScli3.devices() )
+            devices.append( main.ONOScli4.devices() )
+            devices.append( main.ONOScli5.devices() )
+            devices.append( main.ONOScli6.devices() )
+            devices.append( main.ONOScli7.devices() )
+            hosts = []
+            hosts.append( json.loads( main.ONOScli1.hosts() ) )
+            hosts.append( json.loads( main.ONOScli2.hosts() ) )
+            hosts.append( json.loads( main.ONOScli3.hosts() ) )
+            hosts.append( json.loads( main.ONOScli4.hosts() ) )
+            hosts.append( json.loads( main.ONOScli5.hosts() ) )
+            hosts.append( json.loads( main.ONOScli6.hosts() ) )
+            hosts.append( json.loads( main.ONOScli7.hosts() ) )
+            for controller in range( 0, len( hosts ) ):
+                controllerStr = str( controller + 1 )
+                for host in hosts[ controller ]:
+                    if host[ 'ips' ] == []:
+                        main.log.error(
+                            "DEBUG:Error with host ips on controller" +
+                            controllerStr + ": " + str( host ) )
+            ports = []
+            ports.append( main.ONOScli1.ports() )
+            ports.append( main.ONOScli2.ports() )
+            ports.append( main.ONOScli3.ports() )
+            ports.append( main.ONOScli4.ports() )
+            ports.append( main.ONOScli5.ports() )
+            ports.append( main.ONOScli6.ports() )
+            ports.append( main.ONOScli7.ports() )
+            links = []
+            links.append( main.ONOScli1.links() )
+            links.append( main.ONOScli2.links() )
+            links.append( main.ONOScli3.links() )
+            links.append( main.ONOScli4.links() )
+            links.append( main.ONOScli5.links() )
+            links.append( main.ONOScli6.links() )
+            links.append( main.ONOScli7.links() )
+            clusters = []
+            clusters.append( main.ONOScli1.clusters() )
+            clusters.append( main.ONOScli2.clusters() )
+            clusters.append( main.ONOScli3.clusters() )
+            clusters.append( main.ONOScli4.clusters() )
+            clusters.append( main.ONOScli5.clusters() )
+            clusters.append( main.ONOScli6.clusters() )
+            clusters.append( main.ONOScli7.clusters() )
+
+            elapsed = time.time() - startTime
+            cliTime = time.time() - cliStart
+            print "CLI time: " + str( cliTime )
+
+            for controller in range( numControllers ):
+                controllerStr = str( controller + 1 )
+                if devices[ controller ] or "Error" not in devices[
+                        controller ]:
+                    currentDevicesResult = main.Mininet1.compareSwitches(
+                        MNTopo,
+                        json.loads(
+                            devices[ 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 ports[ controller ] or "Error" not in ports[ controller ]:
+                    currentPortsResult = main.Mininet1.comparePorts(
+                        MNTopo,
+                        json.loads(
+                            ports[ controller ] ) )
+                else:
+                    currentPortsResult = main.FALSE
+                utilities.assert_equals( expect=main.TRUE,
+                                         actual=currentPortsResult,
+                                         onpass="ONOS" + controllerStr +
+                                         " ports view is correct",
+                                         onfail="ONOS" + controllerStr +
+                                         " ports view is incorrect" )
+
+                if links[ controller ] or "Error" not in links[ controller ]:
+                    currentLinksResult = main.Mininet1.compareLinks(
+                        MNTopo,
+                        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" )
+            devicesResults = devicesResults and currentDevicesResult
+            portsResults = portsResults and currentPortsResult
+            linksResults = linksResults and currentLinksResult
+
+            # Compare json objects for hosts and dataplane clusters
+
+            # hosts
+            consistentHostsResult = main.TRUE
+            for controller in range( len( hosts ) ):
+                controllerStr = str( controller + 1 )
+                if "Error" not in hosts[ controller ]:
+                    if hosts[ controller ] == hosts[ 0 ]:
+                        continue
+                    else:  # hosts not consistent
+                        main.log.report( "hosts from ONOS" + controllerStr +
+                                         " is inconsistent with ONOS1" )
+                        main.log.warn( repr( hosts[ controller ] ) )
+                        consistentHostsResult = main.FALSE
+
+                else:
+                    main.log.report( "Error in getting ONOS hosts from ONOS" +
+                                     controllerStr )
+                    consistentHostsResult = main.FALSE
+                    main.log.warn( "ONOS" + controllerStr +
+                                   " hosts response: " +
+                                   repr( hosts[ controller ] ) )
+            utilities.assert_equals(
+                expect=main.TRUE,
+                actual=consistentHostsResult,
+                onpass="Hosts view is consistent across all ONOS nodes",
+                onfail="ONOS nodes have different views of hosts" )
+
+            # Strongly connected clusters of devices
+            consistentClustersResult = main.TRUE
+            for controller in range( len( clusters ) ):
+                controllerStr = str( controller + 1 )
+                if "Error" not in clusters[ controller ]:
+                    if clusters[ controller ] == clusters[ 0 ]:
+                        continue
+                    else:  # clusters not consistent
+                        main.log.report( "clusters from ONOS" +
+                                         controllerStr +
+                                         " is inconsistent with ONOS1" )
+                        consistentClustersResult = main.FALSE
+
+                else:
+                    main.log.report( "Error in getting dataplane clusters " +
+                                     "from ONOS" + controllerStr )
+                    consistentClustersResult = main.FALSE
+                    main.log.warn( "ONOS" + controllerStr +
+                                   " clusters response: " +
+                                   repr( clusters[ controller ] ) )
+            utilities.assert_equals(
+                expect=main.TRUE,
+                actual=consistentClustersResult,
+                onpass="Clusters view is consistent across all ONOS nodes",
+                onfail="ONOS nodes have different views of clusters" )
+            # there should always only be one cluster
+            numClusters = len( json.loads( clusters[ 0 ] ) )
+            utilities.assert_equals(
+                expect=1,
+                actual=numClusters,
+                onpass="ONOS shows 1 SCC",
+                onfail="ONOS shows " +
+                str( numClusters ) +
+                " SCCs" )
+
+            topoResult = ( devicesResults and portsResults and linksResults
+                           and consistentHostsResult
+                           and consistentClustersResult )
+
+        topoResult = topoResult and int( count <= 2 )
+        note = "note it takes about " + str( int( cliTime ) ) + \
+            " seconds for the test to make all the cli calls to fetch " +\
+            "the topology from each ONOS instance"
+        main.log.info(
+            "Very crass estimate for topology discovery/convergence( " +
+            str( note ) + " ): " + str( elapsed ) + " seconds, " +
+            str( count ) + " tries" )
+        utilities.assert_equals( expect=main.TRUE, actual=topoResult,
+                                 onpass="Topology Check Test successful",
+                                 onfail="Topology Check Test NOT successful" )
+        if topoResult == main.TRUE:
+            main.log.report( "ONOS topology view matches Mininet topology" )
+
+    def CASE9( self, main ):
+        """
+        Link s3-s28 down
+        """
+        import time
+        # NOTE: You should probably run a topology check after this
+
+        linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
+
+        description = "Turn off a link to ensure that Link Discovery " +\
+            "is working properly"
+        main.log.report( description )
+        main.case( description )
+
+        main.step( "Kill Link between s3 and s28" )
+        LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
+        main.log.info(
+            "Waiting " +
+            str( linkSleep ) +
+            " seconds for link down to be discovered" )
+        time.sleep( linkSleep )
+        utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
+                                 onpass="Link down succesful",
+                                 onfail="Failed to bring link down" )
+        # TODO do some sort of check here
+
+    def CASE10( self, main ):
+        """
+        Link s3-s28 up
+        """
+        import time
+        # NOTE: You should probably run a topology check after this
+
+        linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
+
+        description = "Restore a link to ensure that Link Discovery is " + \
+            "working properly"
+        main.log.report( description )
+        main.case( description )
+
+        main.step( "Bring link between s3 and s28 back up" )
+        LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
+        main.log.info(
+            "Waiting " +
+            str( linkSleep ) +
+            " seconds for link up to be discovered" )
+        time.sleep( linkSleep )
+        utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
+                                 onpass="Link up succesful",
+                                 onfail="Failed to bring link up" )
+        # TODO do some sort of check here
+
+    def CASE11( self, main ):
+        """
+        Switch Down
+        """
+        # NOTE: You should probably run a topology check after this
+        import time
+
+        switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
+
+        description = "Killing a switch to ensure it is discovered correctly"
+        main.log.report( description )
+        main.case( description )
+        switch = main.params[ 'kill' ][ 'switch' ]
+        switchDPID = main.params[ 'kill' ][ 'dpid' ]
+
+        # TODO: Make this switch parameterizable
+        main.step( "Kill " + switch )
+        main.log.report( "Deleting " + switch )
+        main.Mininet1.delSwitch( switch )
+        main.log.info( "Waiting " + str( switchSleep ) +
+                       " seconds for switch down to be discovered" )
+        time.sleep( switchSleep )
+        device = main.ONOScli1.getDevice( dpid=switchDPID )
+        # Peek at the deleted switch
+        main.log.warn( str( device ) )
+        result = main.FALSE
+        if device and device[ 'available' ] is False:
+            result = main.TRUE
+        utilities.assert_equals( expect=main.TRUE, actual=result,
+                                 onpass="Kill switch succesful",
+                                 onfail="Failed to kill switch?" )
+
+    def CASE12( self, main ):
+        """
+        Switch Up
+        """
+        # NOTE: You should probably run a topology check after this
+        import time
+
+        switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
+        switch = main.params[ 'kill' ][ 'switch' ]
+        switchDPID = main.params[ 'kill' ][ 'dpid' ]
+        links = main.params[ 'kill' ][ 'links' ].split()
+        description = "Adding a switch to ensure it is discovered correctly"
+        main.log.report( description )
+        main.case( description )
+
+        main.step( "Add back " + switch )
+        main.log.report( "Adding back " + switch )
+        main.Mininet1.addSwitch( switch, dpid=switchDPID )
+        for peer in links:
+            main.Mininet1.addLink( switch, peer )
+        main.Mininet1.assignSwController(
+            sw=switch.split( 's' )[ 1 ],
+            count=numControllers,
+            ip1=ONOS1Ip,
+            port1=ONOS1Port,
+            ip2=ONOS2Ip,
+            port2=ONOS2Port,
+            ip3=ONOS3Ip,
+            port3=ONOS3Port,
+            ip4=ONOS4Ip,
+            port4=ONOS4Port,
+            ip5=ONOS5Ip,
+            port5=ONOS5Port,
+            ip6=ONOS6Ip,
+            port6=ONOS6Port,
+            ip7=ONOS7Ip,
+            port7=ONOS7Port )
+        main.log.info(
+            "Waiting " +
+            str( switchSleep ) +
+            " seconds for switch up to be discovered" )
+        time.sleep( switchSleep )
+        device = main.ONOScli1.getDevice( dpid=switchDPID )
+        # Peek at the deleted switch
+        main.log.warn( str( device ) )
+        result = main.FALSE
+        if device and device[ 'available' ]:
+            result = main.TRUE
+        utilities.assert_equals( expect=main.TRUE, actual=result,
+                                 onpass="add switch succesful",
+                                 onfail="Failed to add switch?" )
+
+    def CASE13( self, main ):
+        """
+        Clean up
+        """
+        import os
+        import time
+        # TODO: make use of this elsewhere
+        ips = []
+        ips.append( ONOS1Ip )
+        ips.append( ONOS2Ip )
+        ips.append( ONOS3Ip )
+        ips.append( ONOS4Ip )
+        ips.append( ONOS5Ip )
+        ips.append( ONOS6Ip )
+        ips.append( ONOS7Ip )
+
+        # printing colors to terminal
+        colors = {}
+        colors[ 'cyan' ] = '\033[96m'
+        colors[ 'purple' ] = '\033[95m'
+        colors[ 'blue' ] = '\033[94m'
+        colors[ 'green' ] = '\033[92m'
+        colors[ 'yellow' ] = '\033[93m'
+        colors[ 'red' ] = '\033[91m'
+        colors[ 'end' ] = '\033[0m'
+        description = "Test Cleanup"
+        main.log.report( description )
+        main.case( description )
+        main.step( "Killing tcpdumps" )
+        main.Mininet2.stopTcpdump()
+
+        main.step( "Checking ONOS Logs for errors" )
+        for i in range( 7 ):
+            print colors[ 'purple' ] + "Checking logs for errors on " + \
+                "ONOS" + str( i + 1 ) + ":" + colors[ 'end' ]
+            print main.ONOSbench.checkLogs( ips[ i ] )
+
+        main.step( "Copying MN pcap and ONOS log files to test station" )
+        testname = main.TEST
+        teststationUser = main.params[ 'TESTONUSER' ]
+        teststationIP = main.params[ 'TESTONIP' ]
+        # NOTE: MN Pcap file is being saved to ~/packet_captures
+        #       scp this file as MN and TestON aren't necessarily the same vm
+        # FIXME: scp
+        # mn files
+        # TODO: Load these from params
+        # NOTE: must end in /
+        logFolder = "/opt/onos/log/"
+        logFiles = [ "karaf.log", "karaf.log.1" ]
+        # NOTE: must end in /
+        dstDir = "~/packet_captures/"
+        for f in logFiles:
+            for i in range( 7 ):
+                main.ONOSbench.handle.sendline( "scp sdn@" + ips[ i ] + ":" +
+                                                logFolder + f + " " +
+                                                teststationUser + "@" +
+                                                teststationIP + ":" +
+                                                dstDir + str( testname ) +
+                                                "-ONOS" + str( i + 1 ) + "-" +
+                                                f )
+        # std*.log's
+        # NOTE: must end in /
+        logFolder = "/opt/onos/var/"
+        logFiles = [ "stderr.log", "stdout.log" ]
+        # NOTE: must end in /
+        dstDir = "~/packet_captures/"
+        for f in logFiles:
+            for i in range( 7 ):
+                main.ONOSbench.handle.sendline( "scp sdn@" + ips[ i ] + ":" +
+                                                logFolder + f + " " +
+                                                teststationUser + "@" +
+                                                teststationIP + ":" +
+                                                dstDir + str( testname ) +
+                                                "-ONOS" + str( i + 1 ) + "-" +
+                                                f )
+        # sleep so scp can finish
+        time.sleep( 10 )
+        main.step( "Packing and rotating pcap archives" )
+        os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
+
+        # TODO: actually check something here
+        utilities.assert_equals( expect=main.TRUE, actual=main.TRUE,
+                                 onpass="Test cleanup successful",
+                                 onfail="Test cleanup NOT successful" )
+
+    def CASE14( self, main ):
+        """
+        start election app on all onos nodes
+        """
+        leaderResult = main.TRUE
+        # install app on onos 1
+        main.log.info( "Install leadership election app" )
+        main.ONOScli1.featureInstall( "onos-app-election" )
+        # wait for election
+        # check for leader
+        leader = main.ONOScli1.electionTestLeader()
+        # verify leader is ONOS1
+        if leader == ONOS1Ip:
+            # all is well
+            pass
+        elif leader is None:
+            # No leader elected
+            main.log.report( "No leader was elected" )
+            leaderResult = main.FALSE
+        elif leader == main.FALSE:
+            # error in  response
+            # TODO: add check for "Command not found:" in the driver, this
+            # means the app isn't loaded
+            main.log.report( "Something is wrong with electionTestLeader" +
+                             " function, check the error logs" )
+            leaderResult = main.FALSE
+        else:
+            # error in  response
+            main.log.report(
+                "Unexpected response from electionTestLeader function:'" +
+                str( leader ) +
+                "'" )
+            leaderResult = main.FALSE
+
+        # install on other nodes and check for leader.
+        # Should be onos1 and each app should show the same leader
+        for controller in range( 2, numControllers + 1 ):
+            # loop through ONOScli handlers
+            node = getattr( main, ( 'ONOScli' + str( controller ) ) )
+            node.featureInstall( "onos-app-election" )
+            leaderN = node.electionTestLeader()
+            # verify leader is ONOS1
+            if leaderN == ONOS1Ip:
+                # all is well
+                pass
+            elif leaderN == main.FALSE:
+                # error in  response
+                # TODO: add check for "Command not found:" in the driver, this
+                # means the app isn't loaded
+                main.log.report( "Something is wrong with " +
+                                 "electionTestLeader function, check the" +
+                                 " error logs" )
+                leaderResult = main.FALSE
+            elif leader != leaderN:
+                leaderResult = main.FALSE
+                main.log.report( "ONOS" + str( controller ) + " sees " +
+                                 str( leaderN ) +
+                                 " as the leader of the election app. Leader" +
+                                 " should be " +
+                                 str( leader ) )
+        if leaderResult:
+            main.log.report( "Leadership election tests passed( consistent " +
+                             "view of leader across listeners and a leader " +
+                             "was elected )" )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=leaderResult,
+            onpass="Leadership election passed",
+            onfail="Something went wrong with Leadership election" )
+
+    def CASE15( self, main ):
+        """
+        Check that Leadership Election is still functional
+        """
+        leaderResult = main.TRUE
+        description = "Check that Leadership Election is still functional"
+        main.log.report( description )
+        main.case( description )
+        main.step( "Find current leader and withdraw" )
+        leader = main.ONOScli1.electionTestLeader()
+        withdrawResult = main.FALSE
+        if leader == ONOS1Ip:
+            oldLeader = getattr( main, "ONOScli1" )
+        elif leader == ONOS2Ip:
+            oldLeader = getattr( main, "ONOScli2" )
+        elif leader == ONOS3Ip:
+            oldLeader = getattr( main, "ONOScli3" )
+        elif leader == ONOS4Ip:
+            oldLeader = getattr( main, "ONOScli4" )
+        elif leader == ONOS5Ip:
+            oldLeader = getattr( main, "ONOScli5" )
+        elif leader == ONOS6Ip:
+            oldLeader = getattr( main, "ONOScli6" )
+        elif leader == ONOS7Ip:
+            oldLeader = getattr( main, "ONOScli7" )
+        elif leader is None or leader == main.FALSE:
+            main.log.report(
+                "Leader for the election app should be an ONOS node," +
+                "instead got '" +
+                str( leader ) +
+                "'" )
+            leaderResult = main.FALSE
+        withdrawResult = oldLeader.electionTestWithdraw()
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=withdrawResult,
+            onpass="App was withdrawn from election",
+            onfail="App was not withdrawn from election" )
+
+        main.step( "Make sure new leader is elected" )
+        leaderList = []
+        for controller in range( 1, numControllers + 1 ):
+            # loop through ONOScli handlers
+            node = getattr( main, ( 'ONOScli' + str( controller ) ) )
+            leaderList.append( node.electionTestLeader() )
+        for leaderN in leaderList:
+            if leaderN == leader:
+                main.log.report(
+                    "ONOS" +
+                    str( controller ) +
+                    " still sees " +
+                    str( leader ) +
+                    " as leader after they withdrew" )
+                leaderResult = main.FALSE
+            elif leaderN == main.FALSE:
+                # error in  response
+                # TODO: add check for "Command not found:" in the driver, this
+                # means the app isn't loaded
+                main.log.report( "Something is wrong with " +
+                                 "electionTestLeader function, " +
+                                 "check the error logs" )
+                leaderResult = main.FALSE
+        consistentLeader = main.FALSE
+        if len( set( leaderList ) ) == 1:
+            main.log.info( "Each Election-app sees '" +
+                           str( leaderList[ 0 ] ) +
+                           "' as the leader" )
+            consistentLeader = main.TRUE
+        else:
+            main.log.report(
+                "Inconsistent responses for leader of Election-app:" )
+            for n in range( len( leaderList ) ):
+                main.log.report( "ONOS" + str( n + 1 ) + " response: " +
+                                 str( leaderList[ n ] ) )
+        if leaderResult:
+            main.log.report( "Leadership election tests passed( consistent " +
+                             "view of leader across listeners and a new " +
+                             "leader was elected when the old leader " +
+                             "resigned )" )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=leaderResult,
+            onpass="Leadership election passed",
+            onfail="Something went wrong with Leadership election" )
+
+        main.step( "Run for election on old leader( just so everyone "
+                   "is in the hat )" )
+        runResult = oldLeader.electionTestRun()
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=runResult,
+            onpass="App re-ran for election",
+            onfail="App failed to run for election" )
+        if consistentLeader == main.TRUE:
+            afterRun = main.ONOScli1.electionTestLeader()
+            # verify leader didn't just change
+            if afterRun == leaderList[ 0 ]:
+                leaderResult = main.TRUE
+            else:
+                leaderResult = main.FALSE
+        # TODO: assert on  run and withdraw results?
+
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=leaderResult,
+            onpass="Leadership election passed",
+            onfail="Something went wrong with Leadership election after " +
+                   "the old leader re-ran for election" )
+    def CASE16( self ):
+        """
+        """
+        main.ONOScli1.handle.sendline( "sudo iptables -F" )
+        main.ONOScli1.handle.expect( "\$" )
+        main.ONOScli2.handle.sendline( "sudo iptables -F" )
+        main.ONOScli2.handle.expect( "\$" )
+        main.ONOScli3.handle.sendline( "sudo iptables -F" )
+        main.ONOScli3.handle.expect( "\$" )
+        main.ONOScli4.handle.sendline( "sudo iptables -F" )
+        main.ONOScli4.handle.expect( "\$" )
+        main.ONOScli5.handle.sendline( "sudo iptables -F" )
+        main.ONOScli5.handle.expect( "\$" )
+        main.ONOScli6.handle.sendline( "sudo iptables -F" )
+        main.ONOScli6.handle.expect( "\$" )
+        main.ONOScli7.handle.sendline( "sudo iptables -F" )
+        main.ONOScli7.handle.expect( "\$" )
+
diff --git a/TestON/tests/HATestNetworkPartition/HATestNetworkPartition.topo b/TestON/tests/HATestNetworkPartition/HATestNetworkPartition.topo
new file mode 100644
index 0000000..7b32cc2
--- /dev/null
+++ b/TestON/tests/HATestNetworkPartition/HATestNetworkPartition.topo
@@ -0,0 +1,170 @@
+<TOPOLOGY>
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>10.128.30.10</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOSbench>
+
+        <ONOScli1>
+            <host>10.128.30.10</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli1>
+
+        <ONOScli2>
+            <host>10.128.30.10</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli2>
+
+        <ONOScli3>
+            <host>10.128.30.10</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli3>
+
+
+        <ONOScli4>
+            <host>10.128.30.10</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli4>
+
+
+        <ONOScli5>
+            <host>10.128.30.10</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli5>
+
+
+        <ONOScli6>
+            <host>10.128.30.10</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli6>
+
+
+        <ONOScli7>
+            <host>10.128.30.10</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>8</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOScli7>
+
+        <ONOS1>
+            <host>10.128.30.11</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>9</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1>
+
+        <ONOS2>
+            <host>10.128.30.12</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>10</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2>
+
+        <ONOS3>
+            <host>10.128.30.13</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>11</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3>
+
+        <ONOS4>
+            <host>10.128.30.14</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>12</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4>
+
+        <ONOS5>
+            <host>10.128.30.15</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>13</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOS5>
+
+        <ONOS6>
+            <host>10.128.30.16</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>14</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6>
+
+        <ONOS7>
+            <host>10.128.30.17</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>15</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS7>
+
+        <Mininet1>
+            <host>10.128.30.9</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>MininetCliDriver</type>
+            <connect_order>16</connect_order>
+            <COMPONENTS>
+                #Specify the Option for mininet
+                <arg1> --custom ~/mininet/custom/topo-HA.py </arg1>
+                <arg2> --topo mytopo </arg2>
+                <arg3> </arg3>
+                <controller> none </controller>
+            </COMPONENTS>
+        </Mininet1>
+
+        <Mininet2>
+            <host>10.128.30.9</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>RemoteMininetDriver</type>
+            <connect_order>17</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </Mininet2>
+
+    </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/IntentsLoad/__init__.py b/TestON/tests/HATestNetworkPartition/__init__.py
similarity index 100%
copy from TestON/tests/IntentsLoad/__init__.py
copy to TestON/tests/HATestNetworkPartition/__init__.py
diff --git a/TestON/tests/HATestSanity/HATestSanity.py b/TestON/tests/HATestSanity/HATestSanity.py
index 590ff56..5b3e125 100644
--- a/TestON/tests/HATestSanity/HATestSanity.py
+++ b/TestON/tests/HATestSanity/HATestSanity.py
@@ -32,20 +32,24 @@
         CASE1 is to compile ONOS and push it to the test machines
 
         Startup sequence:
-        git pull
-        mvn clean install
-        onos-package
         cell <name>
         onos-verify-cell
         NOTE: temporary - onos-remove-raft-logs
+        onos-uninstall
+        start mininet
+        git pull
+        mvn clean install
+        onos-package
         onos-install -f
         onos-wait-for-start
+        start cli sessions
+        start tcpdump
         """
         main.log.report( "ONOS HA Sanity test - initialization" )
         main.case( "Setting up test environment" )
         # TODO: save all the timers and output them for plotting
 
-        # load some vairables from the params file
+        # load some variables from the params file
         PULLCODE = False
         if main.params[ 'Git' ] == 'True':
             PULLCODE = True
@@ -53,38 +57,34 @@
         cellName = main.params[ 'ENV' ][ 'cellName' ]
 
         # set global variables
-        global ONOS1Ip
         global ONOS1Port
-        global ONOS2Ip
         global ONOS2Port
-        global ONOS3Ip
         global ONOS3Port
-        global ONOS4Ip
         global ONOS4Port
-        global ONOS5Ip
         global ONOS5Port
-        global ONOS6Ip
         global ONOS6Port
-        global ONOS7Ip
         global ONOS7Port
         global numControllers
-
-        ONOS1Ip = main.params[ 'CTRL' ][ 'ip1' ]
-        ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
-        ONOS2Ip = main.params[ 'CTRL' ][ 'ip2' ]
-        ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
-        ONOS3Ip = main.params[ 'CTRL' ][ 'ip3' ]
-        ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
-        ONOS4Ip = main.params[ 'CTRL' ][ 'ip4' ]
-        ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
-        ONOS5Ip = main.params[ 'CTRL' ][ 'ip5' ]
-        ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
-        ONOS6Ip = main.params[ 'CTRL' ][ 'ip6' ]
-        ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
-        ONOS7Ip = main.params[ 'CTRL' ][ 'ip7' ]
-        ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
         numControllers = int( main.params[ 'num_controllers' ] )
 
+        # FIXME: just get controller port from params?
+        # TODO: do we really need all these?
+        ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
+        ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
+        ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
+        ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
+        ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
+        ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
+        ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
+
+        global CLIs
+        CLIs = []
+        global nodes
+        nodes = []
+        for i in range( 1, numControllers + 1 ):
+            CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
+            nodes.append( getattr( main, 'ONOS' + str( i ) ) )
+
         main.step( "Applying cell variable to environment" )
         cellResult = main.ONOSbench.setCell( cellName )
         verifyResult = main.ONOSbench.verifyCell()
@@ -92,14 +92,10 @@
         # FIXME:this is short term fix
         main.log.report( "Removing raft logs" )
         main.ONOSbench.onosRemoveRaftLogs()
+
         main.log.report( "Uninstalling ONOS" )
-        main.ONOSbench.onosUninstall( ONOS1Ip )
-        main.ONOSbench.onosUninstall( ONOS2Ip )
-        main.ONOSbench.onosUninstall( ONOS3Ip )
-        main.ONOSbench.onosUninstall( ONOS4Ip )
-        main.ONOSbench.onosUninstall( ONOS5Ip )
-        main.ONOSbench.onosUninstall( ONOS6Ip )
-        main.ONOSbench.onosUninstall( ONOS7Ip )
+        for node in nodes:
+            main.ONOSbench.onosUninstall( node.ip_address )
 
         cleanInstallResult = main.TRUE
         gitPullResult = main.TRUE
@@ -109,10 +105,11 @@
 
         main.step( "Compiling the latest version of ONOS" )
         if PULLCODE:
-            # TODO Configure branch in params
-            main.step( "Git checkout and pull master" )
+            main.step( "Git checkout and pull " + gitBranch )
             main.ONOSbench.gitCheckout( gitBranch )
             gitPullResult = main.ONOSbench.gitPull()
+            if gitPullResult == main.ERROR:
+                main.log.error( "Error pulling git branch" )
 
             main.step( "Using mvn clean & install" )
             cleanInstallResult = main.ONOSbench.cleanInstall()
@@ -125,77 +122,38 @@
         packageResult = main.ONOSbench.onosPackage()
 
         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 )
-        onos4InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                           node=ONOS4Ip )
-        onos5InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                           node=ONOS5Ip )
-        onos6InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                           node=ONOS6Ip )
-        onos7InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                           node=ONOS7Ip )
-        onosInstallResult = onos1InstallResult and onos2InstallResult\
-            and onos3InstallResult and onos4InstallResult\
-            and onos5InstallResult and onos6InstallResult\
-            and onos7InstallResult
+        onosInstallResult = main.TRUE
+        for node in nodes:
+            tmpResult = main.ONOSbench.onosInstall( options="-f",
+                                                    node=node.ip_address )
+            onosInstallResult = onosInstallResult and tmpResult
 
         main.step( "Checking if ONOS is up yet" )
-        # TODO check bundle:list?
         for i in range( 2 ):
-            onos1Isup = main.ONOSbench.isup( ONOS1Ip )
-            if not onos1Isup:
-                main.log.report( "ONOS1 didn't start!" )
-                main.ONOSbench.onosStop( ONOS1Ip )
-                main.ONOSbench.onosStart( ONOS1Ip )
-            onos2Isup = main.ONOSbench.isup( ONOS2Ip )
-            if not onos2Isup:
-                main.log.report( "ONOS2 didn't start!" )
-                main.ONOSbench.onosStop( ONOS2Ip )
-                main.ONOSbench.onosStart( ONOS2Ip )
-            onos3Isup = main.ONOSbench.isup( ONOS3Ip )
-            if not onos3Isup:
-                main.log.report( "ONOS3 didn't start!" )
-                main.ONOSbench.onosStop( ONOS3Ip )
-                main.ONOSbench.onosStart( ONOS3Ip )
-            onos4Isup = main.ONOSbench.isup( ONOS4Ip )
-            if not onos4Isup:
-                main.log.report( "ONOS4 didn't start!" )
-                main.ONOSbench.onosStop( ONOS4Ip )
-                main.ONOSbench.onosStart( ONOS4Ip )
-            onos5Isup = main.ONOSbench.isup( ONOS5Ip )
-            if not onos5Isup:
-                main.log.report( "ONOS5 didn't start!" )
-                main.ONOSbench.onosStop( ONOS5Ip )
-                main.ONOSbench.onosStart( ONOS5Ip )
-            onos6Isup = main.ONOSbench.isup( ONOS6Ip )
-            if not onos6Isup:
-                main.log.report( "ONOS6 didn't start!" )
-                main.ONOSbench.onosStop( ONOS6Ip )
-                main.ONOSbench.onosStart( ONOS6Ip )
-            onos7Isup = main.ONOSbench.isup( ONOS7Ip )
-            if not onos7Isup:
-                main.log.report( "ONOS7 didn't start!" )
-                main.ONOSbench.onosStop( ONOS7Ip )
-                main.ONOSbench.onosStart( ONOS7Ip )
-            onosIsupResult = onos1Isup and onos2Isup and onos3Isup\
-                and onos4Isup and onos5Isup and onos6Isup and onos7Isup
+            onosIsupResult = main.TRUE
+            for node in nodes:
+                started = main.ONOSbench.isup( node.ip_address )
+                if not started:
+                    main.log.report( node.name + " didn't start!" )
+                    main.ONOSbench.onosStop( node.ip_address )
+                    main.ONOSbench.onosStart( node.ip_address )
+                onosIsupResult = onosIsupResult and started
             if onosIsupResult == main.TRUE:
                 break
 
-        cliResult1 = main.ONOScli1.startOnosCli( ONOS1Ip )
-        cliResult2 = main.ONOScli2.startOnosCli( ONOS2Ip )
-        cliResult3 = main.ONOScli3.startOnosCli( ONOS3Ip )
-        cliResult4 = main.ONOScli4.startOnosCli( ONOS4Ip )
-        cliResult5 = main.ONOScli5.startOnosCli( ONOS5Ip )
-        cliResult6 = main.ONOScli6.startOnosCli( ONOS6Ip )
-        cliResult7 = main.ONOScli7.startOnosCli( ONOS7Ip )
-        cliResults = cliResult1 and cliResult2 and cliResult3 and\
-            cliResult4 and cliResult5 and cliResult6 and cliResult7
+        main.log.step( "Starting ONOS CLI sessions" )
+        cliResults = main.TRUE
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].startOnosCli,
+                             name="startOnosCli-" + str( i ),
+                             args=[nodes[i].ip_address] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            cliResults = cliResults and t.result
 
         main.step( "Start Packet Capture MN" )
         main.Mininet2.startTcpdump(
@@ -209,8 +167,8 @@
                         and onosIsupResult and cliResults )
 
         utilities.assert_equals( expect=main.TRUE, actual=case1Result,
-                                onpass="Test startup successful",
-                                onfail="Test startup NOT successful" )
+                                 onpass="Test startup successful",
+                                 onfail="Test startup NOT successful" )
 
         if case1Result == main.FALSE:
             main.cleanup()
@@ -221,40 +179,49 @@
         Assign mastership to controllers
         """
         import re
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
+        assert ONOS1Port, "ONOS1Port not defined"
+        assert ONOS2Port, "ONOS2Port not defined"
+        assert ONOS3Port, "ONOS3Port not defined"
+        assert ONOS4Port, "ONOS4Port not defined"
+        assert ONOS5Port, "ONOS5Port not defined"
+        assert ONOS6Port, "ONOS6Port not defined"
+        assert ONOS7Port, "ONOS7Port not defined"
 
         main.log.report( "Assigning switches to controllers" )
         main.case( "Assigning Controllers" )
         main.step( "Assign switches to controllers" )
 
+        # TODO: rewrite this function to take lists of ips and ports?
+        #       or list of tuples?
         for i in range( 1, 29 ):
             main.Mininet1.assignSwController(
                 sw=str( i ),
                 count=numControllers,
-                ip1=ONOS1Ip, port1=ONOS1Port,
-                ip2=ONOS2Ip, port2=ONOS2Port,
-                ip3=ONOS3Ip, port3=ONOS3Port,
-                ip4=ONOS4Ip, port4=ONOS4Port,
-                ip5=ONOS5Ip, port5=ONOS5Port,
-                ip6=ONOS6Ip, port6=ONOS6Port,
-                ip7=ONOS7Ip, port7=ONOS7Port )
+                ip1=nodes[ 0 ].ip_address, port1=ONOS1Port,
+                ip2=nodes[ 1 ].ip_address, port2=ONOS2Port,
+                ip3=nodes[ 2 ].ip_address, port3=ONOS3Port,
+                ip4=nodes[ 3 ].ip_address, port4=ONOS4Port,
+                ip5=nodes[ 4 ].ip_address, port5=ONOS5Port,
+                ip6=nodes[ 5 ].ip_address, port6=ONOS6Port,
+                ip7=nodes[ 6 ].ip_address, port7=ONOS7Port )
 
         mastershipCheck = main.TRUE
         for i in range( 1, 29 ):
             response = main.Mininet1.getSwController( "s" + str( i ) )
             try:
                 main.log.info( str( response ) )
-            except:
+            except Exception:
                 main.log.info( repr( response ) )
-            if re.search( "tcp:" + ONOS1Ip, response )\
-                    and re.search( "tcp:" + ONOS2Ip, response )\
-                    and re.search( "tcp:" + ONOS3Ip, response )\
-                    and re.search( "tcp:" + ONOS4Ip, response )\
-                    and re.search( "tcp:" + ONOS5Ip, response )\
-                    and re.search( "tcp:" + ONOS6Ip, response )\
-                    and re.search( "tcp:" + ONOS7Ip, response ):
-                mastershipCheck = mastershipCheck and main.TRUE
-            else:
-                mastershipCheck = main.FALSE
+            for node in nodes:
+                if re.search( "tcp:" + node.ip_address, response ):
+                    mastershipCheck = mastershipCheck and main.TRUE
+                else:
+                    mastershipCheck = main.FALSE
         if mastershipCheck == main.TRUE:
             main.log.report( "Switch mastership assigned correctly" )
         utilities.assert_equals(
@@ -262,122 +229,141 @@
             actual=mastershipCheck,
             onpass="Switch mastership assigned correctly",
             onfail="Switches not assigned correctly to controllers" )
-
+        #FIXME: turning off because of ONOS-1286
         # Manually assign mastership to the controller we want
         roleCall = main.TRUE
         roleCheck = main.TRUE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS1Ip )
-        # Check assignment
-        if ONOS1Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS1Ip )
-        # Check assignment
-        if ONOS1Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS2Ip )
-        # Check assignment
-        if ONOS2Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS2Ip )
-        # Check assignment
-        if ONOS2Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS3Ip )
-        # Check assignment
-        if ONOS3Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS3Ip )
-        # Check assignment
-        if ONOS3Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        # Assign switch
-        deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS4Ip )
-        # Check assignment
-        if ONOS4Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        for i in range( 8, 18 ):
-            dpid = '3' + str( i ).zfill( 3 )
-            deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+        try:
+            # Assign switch
+            ip = nodes[ 0 ].ip_address  # ONOS1
+            deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
+            assert deviceId, "No device id for s1 in ONOS"
             roleCall = roleCall and main.ONOScli1.deviceRole(
                 deviceId,
-                ONOS5Ip )
+                ip )
             # Check assignment
-            if ONOS5Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
                 roleCheck = roleCheck and main.TRUE
             else:
                 roleCheck = roleCheck and main.FALSE
 
-        deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
-        roleCall = roleCall and main.ONOScli1.deviceRole(
-            deviceId,
-            ONOS6Ip )
-        # Check assignment
-        if ONOS6Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-            roleCheck = roleCheck and main.TRUE
-        else:
-            roleCheck = roleCheck and main.FALSE
-
-        for i in range( 18, 28 ):
-            dpid = '6' + str( i ).zfill( 3 )
-            deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
+            assert deviceId, "No device id for s28 in ONOS"
             roleCall = roleCall and main.ONOScli1.deviceRole(
                 deviceId,
-                ONOS7Ip )
+                ip )
             # Check assignment
-            if ONOS7Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
                 roleCheck = roleCheck and main.TRUE
             else:
                 roleCheck = roleCheck and main.FALSE
 
+            ip = nodes[ 1 ].ip_address  # ONOS2
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
+            assert deviceId, "No device id for s2 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
+            assert deviceId, "No device id for s3 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            ip = nodes[ 2 ].ip_address  # ONOS3
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
+            assert deviceId, "No device id for s5 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
+            assert deviceId, "No device id for s6 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            ip = nodes[ 3 ].ip_address  # ONOS4
+            # Assign switch
+            deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
+            assert deviceId, "No device id for s4 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            ip = nodes[ 4 ].ip_address  # ONOS5
+            for i in range( 8, 18 ):
+                dpid = '3' + str( i ).zfill( 3 )
+                deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                assert deviceId, "No device id for s%i in ONOS" % i
+                roleCall = roleCall and main.ONOScli1.deviceRole(
+                    deviceId,
+                    ip )
+                # Check assignment
+                if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                    roleCheck = roleCheck and main.TRUE
+                else:
+                    roleCheck = roleCheck and main.FALSE
+
+            ip = nodes[ 5 ].ip_address  # ONOS6
+            deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
+            assert deviceId, "No device id for s7 in ONOS"
+            roleCall = roleCall and main.ONOScli1.deviceRole(
+                deviceId,
+                ip )
+            # Check assignment
+            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+
+            ip = nodes[ 6 ].ip_address  # ONOS7
+            for i in range( 18, 28 ):
+                dpid = '6' + str( i ).zfill( 3 )
+                deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                assert deviceId, "No device id for s%i in ONOS" % i
+                roleCall = roleCall and main.ONOScli1.deviceRole(
+                    deviceId,
+                    ip )
+                # Check assignment
+                if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                    roleCheck = roleCheck and main.TRUE
+                else:
+                    roleCheck = roleCheck and main.FALSE
+        except ( AttributeError, AssertionError ):
+            main.log.exception( "Something is wrong with ONOS device view" )
+            main.log.info( main.ONOScli1.devices() )
         utilities.assert_equals(
             expect=main.TRUE,
             actual=roleCall,
@@ -401,6 +387,12 @@
         Assign intents
         """
         import time
+        import json
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         main.log.report( "Adding host intents" )
         main.case( "Adding host Intents" )
 
@@ -409,41 +401,55 @@
 
         # install onos-app-fwd
         main.log.info( "Install reactive forwarding app" )
-        main.ONOScli1.featureInstall( "onos-app-fwd" )
-        main.ONOScli2.featureInstall( "onos-app-fwd" )
-        main.ONOScli3.featureInstall( "onos-app-fwd" )
-        main.ONOScli4.featureInstall( "onos-app-fwd" )
-        main.ONOScli5.featureInstall( "onos-app-fwd" )
-        main.ONOScli6.featureInstall( "onos-app-fwd" )
-        main.ONOScli7.featureInstall( "onos-app-fwd" )
+        appResults = main.TRUE
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].featureInstall,
+                             name="featureInstall-" + str( i ),
+                             args=["onos-app-fwd"] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            appResults = appResults and t.result
 
         # REACTIVE FWD test
         pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall()
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=pingResult,
-            onpass="Reactive Pingall test passed",
-            onfail="Reactive Pingall failed, one or more ping pairs failed" )
-        time2 = time.time()
-        main.log.info( "Time for pingall: %2f seconds" % ( time2 - time1 ) )
+        for i in range(2):  # Retry if pingall fails first time
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall()
+            utilities.assert_equals(
+                expect=main.TRUE,
+                actual=pingResult,
+                onpass="Reactive Pingall test passed",
+                onfail="Reactive Pingall failed, one or more ping pairs failed" )
+            time2 = time.time()
+            main.log.info( "Time for pingall: %2f seconds" % ( time2 - time1 ) )
 
         # uninstall onos-app-fwd
         main.log.info( "Uninstall reactive forwarding app" )
-        main.ONOScli1.featureUninstall( "onos-app-fwd" )
-        main.ONOScli2.featureUninstall( "onos-app-fwd" )
-        main.ONOScli3.featureUninstall( "onos-app-fwd" )
-        main.ONOScli4.featureUninstall( "onos-app-fwd" )
-        main.ONOScli5.featureUninstall( "onos-app-fwd" )
-        main.ONOScli6.featureUninstall( "onos-app-fwd" )
-        main.ONOScli7.featureUninstall( "onos-app-fwd" )
-        # timeout for fwd flows
-        time.sleep( 10 )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].featureUninstall,
+                             name="featureUninstall-" + str( i ),
+                             args=["onos-app-fwd"] )
+            threads.append( t )
+            t.start()
 
-        main.step( "Add  host intents" )
+        for t in threads:
+            t.join()
+            appResults = appResults and t.result
+
+        # timeout for fwd flows
+        time.sleep( 11 )
+
+        main.step( "Add host intents" )
+        intentIds = []
         # TODO:  move the host numbers to params
+        #        Maybe look at all the paths we ping?
         intentAddResult = True
+        hostResult = main.TRUE
         for i in range( 8, 18 ):
             main.log.info( "Adding host intent between h" + str( i ) +
                            " and h" + str( i + 10 ) )
@@ -460,46 +466,262 @@
                 host1Id = host1Dict.get( 'id', None )
                 host2Id = host2Dict.get( 'id', None )
             if host1Id and host2Id:
-                # TODO: distribute the intents across onos nodes
-                tmpResult = main.ONOScli1.addHostIntent(
-                    host1Id,
-                    host2Id )
+                nodeNum = ( i % 7 )
+                tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
+                if tmpId:
+                    main.log.info( "Added intent with id: " + tmpId )
+                    intentIds.append( tmpId )
+                else:
+                    main.log.error( "addHostIntent returned: " +
+                                     repr( tmpId ) )
             else:
-                main.log.error( "Error, getHost() failed" )
-                main.log.warn( json.dumps( json.loads( main.ONOScli1.hosts() ),
+                main.log.error( "Error, getHost() failed for h" + str( i ) +
+                                " and/or h" + str( i + 10 ) )
+                hosts = CLIs[ 0 ].hosts()
+                main.log.warn( "Hosts output: " )
+                try:
+                    main.log.warn( json.dumps( json.loads( hosts ),
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                except ( ValueError, TypeError ):
+                    main.log.warn( repr( hosts ) )
+                hostResult = main.FALSE
+        # FIXME: DEBUG
+        intentStart = time.time()
+        onosIds = main.ONOScli1.getAllIntentsId()
+        main.log.info( "Submitted intents: " + str( intentIds ) )
+        main.log.info( "Intents in ONOS: " + str( onosIds ) )
+        for intent in intentIds:
+            if intent in onosIds:
+                pass  # intent submitted is in onos
+            else:
+                intentAddResult = False
+        # FIXME: DEBUG
+        if intentAddResult:
+            intentStop = time.time()
+        else:
+            intentStop = None
+        # Print the intent states
+        intents = main.ONOScli1.intents()
+        intentStates = []
+        installedCheck = True
+        main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
+        count = 0
+        try:
+            for intent in json.loads( intents ):
+                state = intent.get( 'state', None )
+                if "INSTALLED" not in state:
+                    installedCheck = False
+                intentId = intent.get( 'id', None )
+                intentStates.append( ( intentId, state ) )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing intents" )
+        # add submitted intents not in the store
+        tmplist = [ i for i, s in intentStates ]
+        missingIntents = False
+        for i in intentIds:
+            if i not in tmplist:
+                intentStates.append( ( i, " - " ) )
+                missingIntents = True
+        intentStates.sort()
+        for i, s in intentStates:
+            count += 1
+            main.log.info( "%-6s%-15s%-15s" %
+                           ( str( count ), str( i ), str( s ) ) )
+        leaders = main.ONOScli1.leaders()
+        try:
+            if leaders:
+                parsedLeaders = json.loads( leaders )
+                main.log.warn( json.dumps( parsedLeaders,
                                            sort_keys=True,
                                            indent=4,
                                            separators=( ',', ': ' ) ) )
-                tmpResult = main.FALSE
-            intentAddResult = bool( pingResult and intentAddResult
-                                     and tmpResult )
-            # TODO Check that intents were added?
-        # Print the intent states
-        intents = main.ONOScli1.intents( )
-        intentStates = []
-        for intent in json.loads( intents ):  # Iter through intents of a node
-            intentStates.append( intent.get( 'state', None ) )
-        out = [ (i, intentStates.count( i ) ) for i in set( intentStates ) ]
-        main.log.info( dict( out ) )
+                # check for all intent partitions
+                # check for election
+                topics = []
+                for i in range( 14 ):
+                    topics.append( "intent-partition-" + str( i ) )
+                # FIXME: this should only be after we start the app
+                # FIXME: move this to the election test sections
+                topics.append( "org.onosproject.election" )
+                main.log.debug( topics )
+                ONOStopics = [ j['topic'] for j in parsedLeaders ]
+                for topic in topics:
+                    if topic not in ONOStopics:
+                        main.log.error( "Error: " + topic +
+                                        " not in leaders" )
+            else:
+                main.log.error( "leaders() returned None" )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing leaders" )
+            main.log.error( repr( leaders ) )
+        partitions = main.ONOScli1.partitions()
+        try:
+            if partitions :
+                parsedPartitions = json.loads( partitions )
+                main.log.warn( json.dumps( parsedPartitions,
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+                # TODO check for a leader in all paritions
+                # TODO check for consistency among nodes
+            else:
+                main.log.error( "partitions() returned None" )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing partitions" )
+            main.log.error( repr( partitions ) )
+        pendingMap = main.ONOScli1.pendingMap()
+        try:
+            if pendingMap :
+                parsedPending = json.loads( pendingMap )
+                main.log.warn( json.dumps( parsedPending,
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+                # TODO check something here?
+            else:
+                main.log.error( "pendingMap() returned None" )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing pending map" )
+            main.log.error( repr( pendingMap ) )
 
+        intentAddResult = bool( pingResult and hostResult and intentAddResult
+                                and not missingIntents and installedCheck )
         utilities.assert_equals(
             expect=True,
             actual=intentAddResult,
             onpass="Pushed host intents to ONOS",
             onfail="Error in pushing host intents to ONOS" )
-        # TODO Check if intents all exist in datastore
+        for i in range(100):
+            onosIds = main.ONOScli1.getAllIntentsId()
+            main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
+            main.log.info( "Intents in ONOS: " + str( sorted( onosIds ) ) )
+            if sorted(onosIds) == sorted(intentIds):
+                break
+            else:
+                time.sleep(1)
+        # FIXME: DEBUG
+        if not intentStop:
+            intentStop = time.time()
+        gossipTime = intentStop - intentStart
+        main.log.info( "It took about " + str( gossipTime ) +
+                        " seconds for all intents to appear on ONOS1" )
+        # FIXME: make this time configurable/calculate based off of # of nodes
+        #        and gossip rounds
+        utilities.assert_greater_equals(
+                expect=30, actual=gossipTime,
+                onpass="ECM anti-entropy for intents worked within " +
+                       "expected time",
+                onfail="Intent ECM anti-entropy took too long" )
+
+        if not intentAddResult or "key" in pendingMap:
+            import time
+            installedCheck = True
+            main.log.info( "Sleeping 60 seconds to see if intents are found" )
+            time.sleep( 60 )
+            onosIds = main.ONOScli1.getAllIntentsId()
+            main.log.info( "Submitted intents: " + str( intentIds ) )
+            main.log.info( "Intents in ONOS: " + str( onosIds ) )
+            # Print the intent states
+            intents = main.ONOScli1.intents()
+            intentStates = []
+            main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
+            count = 0
+            try:
+                for intent in json.loads( intents ):
+                    # Iter through intents of a node
+                    state = intent.get( 'state', None )
+                    if "INSTALLED" not in state:
+                        installedCheck = False
+                    intentId = intent.get( 'id', None )
+                    intentStates.append( ( intentId, state ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing intents" )
+            # add submitted intents not in the store
+            tmplist = [ i for i, s in intentStates ]
+            for i in intentIds:
+                if i not in tmplist:
+                    intentStates.append( ( i, " - " ) )
+            intentStates.sort()
+            for i, s in intentStates:
+                count += 1
+                main.log.info( "%-6s%-15s%-15s" %
+                               ( str( count ), str( i ), str( s ) ) )
+            leaders = main.ONOScli1.leaders()
+            try:
+                if leaders:
+                    parsedLeaders = json.loads( leaders )
+                    main.log.warn( json.dumps( parsedLeaders,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # check for all intent partitions
+                    # check for election
+                    topics = []
+                    for i in range( 14 ):
+                        topics.append( "intent-partition-" + str( i ) )
+                    # FIXME: this should only be after we start the app
+                    topics.append( "org.onosproject.election" )
+                    main.log.debug( topics )
+                    ONOStopics = [ j['topic'] for j in parsedLeaders ]
+                    for topic in topics:
+                        if topic not in ONOStopics:
+                            main.log.error( "Error: " + topic +
+                                            " not in leaders" )
+                else:
+                    main.log.error( "leaders() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing leaders" )
+                main.log.error( repr( leaders ) )
+            partitions = main.ONOScli1.partitions()
+            try:
+                if partitions :
+                    parsedPartitions = json.loads( partitions )
+                    main.log.warn( json.dumps( parsedPartitions,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check for a leader in all paritions
+                    # TODO check for consistency among nodes
+                else:
+                    main.log.error( "partitions() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing partitions" )
+                main.log.error( repr( partitions ) )
+            pendingMap = main.ONOScli1.pendingMap()
+            try:
+                if pendingMap :
+                    parsedPending = json.loads( pendingMap )
+                    main.log.warn( json.dumps( parsedPending,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check something here?
+                else:
+                    main.log.error( "pendingMap() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing pending map" )
+                main.log.error( repr( pendingMap ) )
 
     def CASE4( self, main ):
         """
         Ping across added host intents
         """
+        import json
+        import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         description = " Ping across added host intents"
         main.log.report( description )
         main.case( description )
         PingResult = main.TRUE
         for i in range( 8, 18 ):
-            ping = main.Mininet1.pingHost(
-                src="h" + str( i ), target="h" + str( i + 10 ) )
+            ping = main.Mininet1.pingHost( src="h" + str( i ),
+                                           target="h" + str( i + 10 ) )
             PingResult = PingResult and ping
             if ping == main.FALSE:
                 main.log.warn( "Ping failed between h" + str( i ) +
@@ -510,12 +732,16 @@
         if PingResult == main.FALSE:
             main.log.report(
                 "Intents have not been installed correctly, pings failed." )
-            #TODO: pretty print
-            main.log.warn( "ONSO1 intents: " )
-            main.log.warn( json.dumps( json.loads( main.ONOScli1.intents() ),
-                                       sort_keys=True,
-                                       indent=4,
-                                       separators=( ',', ': ' ) ) )
+            # TODO: pretty print
+            main.log.warn( "ONOS1 intents: " )
+            try:
+                tmpIntents = main.ONOScli1.intents()
+                main.log.warn( json.dumps( json.loads( tmpIntents ),
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+            except ( ValueError, TypeError ):
+                main.log.warn( repr( tmpIntents ) )
         if PingResult == main.TRUE:
             main.log.report(
                 "Intents have been installed correctly and verified by pings" )
@@ -525,11 +751,175 @@
             onpass="Intents have been installed correctly and pings work",
             onfail="Intents have not been installed correctly, pings failed." )
 
+        installedCheck = True
+        if PingResult is not main.TRUE:
+            # Print the intent states
+            intents = main.ONOScli1.intents()
+            intentStates = []
+            main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
+            count = 0
+            # Iter through intents of a node
+            try:
+                for intent in json.loads( intents ):
+                    state = intent.get( 'state', None )
+                    if "INSTALLED" not in state:
+                        installedCheck = False
+                    intentId = intent.get( 'id', None )
+                    intentStates.append( ( intentId, state ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing intents." )
+            intentStates.sort()
+            for i, s in intentStates:
+                count += 1
+                main.log.info( "%-6s%-15s%-15s" %
+                               ( str( count ), str( i ), str( s ) ) )
+            leaders = main.ONOScli1.leaders()
+            try:
+                if leaders:
+                    parsedLeaders = json.loads( leaders )
+                    main.log.warn( json.dumps( parsedLeaders,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # check for all intent partitions
+                    # check for election
+                    topics = []
+                    for i in range( 14 ):
+                        topics.append( "intent-partition-" + str( i ) )
+                    # FIXME: this should only be after we start the app
+                    topics.append( "org.onosproject.election" )
+                    main.log.debug( topics )
+                    ONOStopics = [ j['topic'] for j in parsedLeaders ]
+                    for topic in topics:
+                        if topic not in ONOStopics:
+                            main.log.error( "Error: " + topic +
+                                            " not in leaders" )
+                else:
+                    main.log.error( "leaders() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing leaders" )
+                main.log.error( repr( leaders ) )
+            partitions = main.ONOScli1.partitions()
+            try:
+                if partitions :
+                    parsedPartitions = json.loads( partitions )
+                    main.log.warn( json.dumps( parsedPartitions,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check for a leader in all paritions
+                    # TODO check for consistency among nodes
+                else:
+                    main.log.error( "partitions() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing partitions" )
+                main.log.error( repr( partitions ) )
+            pendingMap = main.ONOScli1.pendingMap()
+            try:
+                if pendingMap :
+                    parsedPending = json.loads( pendingMap )
+                    main.log.warn( json.dumps( parsedPending,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check something here?
+                else:
+                    main.log.error( "pendingMap() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing pending map" )
+                main.log.error( repr( pendingMap ) )
+
+        if not installedCheck:
+            main.log.info( "Waiting 60 seconds to see if the state of " +
+                           "intents change" )
+            time.sleep( 60 )
+            # Print the intent states
+            intents = main.ONOScli1.intents()
+            intentStates = []
+            main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
+            count = 0
+            # Iter through intents of a node
+            try:
+                for intent in json.loads( intents ):
+                    state = intent.get( 'state', None )
+                    if "INSTALLED" not in state:
+                        installedCheck = False
+                    intentId = intent.get( 'id', None )
+                    intentStates.append( ( intentId, state ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing intents." )
+            intentStates.sort()
+            for i, s in intentStates:
+                count += 1
+                main.log.info( "%-6s%-15s%-15s" %
+                               ( str( count ), str( i ), str( s ) ) )
+            leaders = main.ONOScli1.leaders()
+            try:
+                if leaders:
+                    parsedLeaders = json.loads( leaders )
+                    main.log.warn( json.dumps( parsedLeaders,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # check for all intent partitions
+                    # check for election
+                    topics = []
+                    for i in range( 14 ):
+                        topics.append( "intent-partition-" + str( i ) )
+                    # FIXME: this should only be after we start the app
+                    topics.append( "org.onosproject.election" )
+                    main.log.debug( topics )
+                    ONOStopics = [ j['topic'] for j in parsedLeaders ]
+                    for topic in topics:
+                        if topic not in ONOStopics:
+                            main.log.error( "Error: " + topic +
+                                            " not in leaders" )
+                else:
+                    main.log.error( "leaders() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing leaders" )
+                main.log.error( repr( leaders ) )
+            partitions = main.ONOScli1.partitions()
+            try:
+                if partitions :
+                    parsedPartitions = json.loads( partitions )
+                    main.log.warn( json.dumps( parsedPartitions,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check for a leader in all paritions
+                    # TODO check for consistency among nodes
+                else:
+                    main.log.error( "partitions() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing partitions" )
+                main.log.error( repr( partitions ) )
+            pendingMap = main.ONOScli1.pendingMap()
+            try:
+                if pendingMap :
+                    parsedPending = json.loads( pendingMap )
+                    main.log.warn( json.dumps( parsedPending,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check something here?
+                else:
+                    main.log.error( "pendingMap() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing pending map" )
+                main.log.error( repr( pendingMap ) )
+
     def CASE5( self, main ):
         """
         Reading state of ONOS
         """
         import json
+        import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         # assumes that sts is already in you PYTHONPATH
         from sts.topology.teston_topology import TestONTopology
 
@@ -537,330 +927,240 @@
         main.case( "Setting up and gathering data for current state" )
         # The general idea for this test case is to pull the state of
         # ( intents,flows, topology,... ) from each ONOS node
-        # We can then compare them with eachother and also with past states
+        # We can then compare them with each other and also with past states
 
-        main.step( "Get the Mastership of each switch from each controller" )
+        main.step( "Check that each switch has a master" )
         global mastershipState
-        mastershipState = []
+        mastershipState = '[]'
 
         # Assert that each device has a master
-        ONOS1MasterNotNull = main.ONOScli1.rolesNotNull()
-        ONOS2MasterNotNull = main.ONOScli2.rolesNotNull()
-        ONOS3MasterNotNull = main.ONOScli3.rolesNotNull()
-        ONOS4MasterNotNull = main.ONOScli4.rolesNotNull()
-        ONOS5MasterNotNull = main.ONOScli5.rolesNotNull()
-        ONOS6MasterNotNull = main.ONOScli6.rolesNotNull()
-        ONOS7MasterNotNull = main.ONOScli7.rolesNotNull()
-        rolesNotNull = ONOS1MasterNotNull and ONOS2MasterNotNull and\
-            ONOS3MasterNotNull and ONOS4MasterNotNull and\
-            ONOS5MasterNotNull and ONOS6MasterNotNull and\
-            ONOS7MasterNotNull
+        rolesNotNull = main.TRUE
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].rolesNotNull,
+                             name="rolesNotNull-" + str( i ),
+                             args=[] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            rolesNotNull = rolesNotNull and t.result
         utilities.assert_equals(
             expect=main.TRUE,
             actual=rolesNotNull,
             onpass="Each device has a master",
             onfail="Some devices don't have a master assigned" )
 
-        ONOS1Mastership = main.ONOScli1.roles()
-        ONOS2Mastership = main.ONOScli2.roles()
-        ONOS3Mastership = main.ONOScli3.roles()
-        ONOS4Mastership = main.ONOScli4.roles()
-        ONOS5Mastership = main.ONOScli5.roles()
-        ONOS6Mastership = main.ONOScli6.roles()
-        ONOS7Mastership = main.ONOScli7.roles()
-        if "Error" in ONOS1Mastership or not ONOS1Mastership\
-                or "Error" in ONOS2Mastership or not ONOS2Mastership\
-                or "Error" in ONOS3Mastership or not ONOS3Mastership\
-                or "Error" in ONOS4Mastership or not ONOS4Mastership\
-                or "Error" in ONOS5Mastership or not ONOS5Mastership\
-                or "Error" in ONOS6Mastership or not ONOS6Mastership\
-                or "Error" in ONOS7Mastership or not ONOS7Mastership:
-            main.log.report( "Error in getting ONOS roles" )
-            main.log.warn(
-                "ONOS1 mastership response: " +
-                repr( ONOS1Mastership ) )
-            main.log.warn(
-                "ONOS2 mastership response: " +
-                repr( ONOS2Mastership ) )
-            main.log.warn(
-                "ONOS3 mastership response: " +
-                repr( ONOS3Mastership ) )
-            main.log.warn(
-                "ONOS4 mastership response: " +
-                repr( ONOS4Mastership ) )
-            main.log.warn(
-                "ONOS5 mastership response: " +
-                repr( ONOS5Mastership ) )
-            main.log.warn(
-                "ONOS6 mastership response: " +
-                repr( ONOS6Mastership ) )
-            main.log.warn(
-                "ONOS7 mastership response: " +
-                repr( ONOS7Mastership ) )
-            consistentMastership = main.FALSE
-        elif ONOS1Mastership == ONOS2Mastership\
-                and ONOS1Mastership == ONOS3Mastership\
-                and ONOS1Mastership == ONOS4Mastership\
-                and ONOS1Mastership == ONOS5Mastership\
-                and ONOS1Mastership == ONOS6Mastership\
-                and ONOS1Mastership == ONOS7Mastership:
-            mastershipState = ONOS1Mastership
-            consistentMastership = main.TRUE
+        main.step( "Get the Mastership of each switch from each controller" )
+        ONOSMastership = []
+        mastershipCheck = main.FALSE
+        consistentMastership = True
+        rolesResults = True
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].roles,
+                             name="roles-" + str( i ),
+                             args=[] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            ONOSMastership.append( t.result )
+
+        for i in range( numControllers ):
+            if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
+                main.log.report( "Error in getting ONOS" + str( i + 1 ) +
+                                 " roles" )
+                main.log.warn(
+                    "ONOS" + str( i + 1 ) + " mastership response: " +
+                    repr( ONOSMastership[i] ) )
+                rolesResults = False
+        utilities.assert_equals(
+            expect=True,
+            actual=rolesResults,
+            onpass="No error in reading roles output",
+            onfail="Error in reading roles from ONOS" )
+
+        main.step( "Check for consistency in roles from each controller" )
+        if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
             main.log.report(
                 "Switch roles are consistent across all ONOS nodes" )
         else:
-            main.log.warn(
-                "ONOS1 roles: ",
-                json.dumps(
-                    json.loads( ONOS1Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS2 roles: ",
-                json.dumps(
-                    json.loads( ONOS2Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS3 roles: ",
-                json.dumps(
-                    json.loads( ONOS3Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS4 roles: ",
-                json.dumps(
-                    json.loads( ONOS4Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS5 roles: ",
-                json.dumps(
-                    json.loads( ONOS5Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS6 roles: ",
-                json.dumps(
-                    json.loads( ONOS6Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS7 roles: ",
-                json.dumps(
-                    json.loads( ONOS7Mastership ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            consistentMastership = main.FALSE
+            consistentMastership = False
         utilities.assert_equals(
-            expect=main.TRUE,
+            expect=True,
             actual=consistentMastership,
             onpass="Switch roles are consistent across all ONOS nodes",
             onfail="ONOS nodes have different views of switch roles" )
 
+        if rolesResults and not consistentMastership:
+            for i in range( numControllers ):
+                try:
+                    main.log.warn(
+                        "ONOS" + str( i + 1 ) + " roles: ",
+                        json.dumps(
+                            json.loads( ONOSMastership[ i ] ),
+                            sort_keys=True,
+                            indent=4,
+                            separators=( ',', ': ' ) ) )
+                except ( ValueError, TypeError ):
+                    main.log.warn( repr( ONOSMastership[ i ] ) )
+        elif rolesResults and consistentMastership:
+            mastershipCheck = main.TRUE
+            mastershipState = ONOSMastership[ 0 ]
+
         main.step( "Get the intents from each controller" )
         global intentState
         intentState = []
-        ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
-        ONOS2Intents = main.ONOScli2.intents( jsonFormat=True )
-        ONOS3Intents = main.ONOScli3.intents( jsonFormat=True )
-        ONOS4Intents = main.ONOScli4.intents( jsonFormat=True )
-        ONOS5Intents = main.ONOScli5.intents( jsonFormat=True )
-        ONOS6Intents = main.ONOScli6.intents( jsonFormat=True )
-        ONOS7Intents = main.ONOScli7.intents( jsonFormat=True )
+        ONOSIntents = []
         intentCheck = main.FALSE
-        if "Error" in ONOS1Intents or not ONOS1Intents\
-                or "Error" in ONOS2Intents or not ONOS2Intents\
-                or "Error" in ONOS3Intents or not ONOS3Intents\
-                or "Error" in ONOS4Intents or not ONOS4Intents\
-                or "Error" in ONOS5Intents or not ONOS5Intents\
-                or "Error" in ONOS6Intents or not ONOS6Intents\
-                or "Error" in ONOS7Intents or not ONOS7Intents:
-            main.log.report( "Error in getting ONOS intents" )
-            main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
-            main.log.warn( "ONOS2 intents response: " + repr( ONOS2Intents ) )
-            main.log.warn( "ONOS3 intents response: " + repr( ONOS3Intents ) )
-            main.log.warn( "ONOS4 intents response: " + repr( ONOS4Intents ) )
-            main.log.warn( "ONOS5 intents response: " + repr( ONOS5Intents ) )
-            main.log.warn( "ONOS6 intents response: " + repr( ONOS6Intents ) )
-            main.log.warn( "ONOS7 intents response: " + repr( ONOS7Intents ) )
-        elif ONOS1Intents == ONOS2Intents\
-                and ONOS1Intents == ONOS3Intents\
-                and ONOS1Intents == ONOS4Intents\
-                and ONOS1Intents == ONOS5Intents\
-                and ONOS1Intents == ONOS6Intents\
-                and ONOS1Intents == ONOS7Intents:
-            intentState = ONOS1Intents
-            intentCheck = main.TRUE
-            main.log.report( "Intents are consistent across all ONOS nodes" )
-        else:
-            main.log.warn(
-                "ONOS1 intents: ",
-                json.dumps(
-                    json.loads( ONOS1Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS2 intents: ",
-                json.dumps(
-                    json.loads( ONOS2Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS3 intents: ",
-                json.dumps(
-                    json.loads( ONOS3Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS4 intents: ",
-                json.dumps(
-                    json.loads( ONOS4Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS5 intents: ",
-                json.dumps(
-                    json.loads( ONOS5Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS6 intents: ",
-                json.dumps(
-                    json.loads( ONOS6Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
-            main.log.warn(
-                "ONOS7 intents: ",
-                json.dumps(
-                    json.loads( ONOS7Intents ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=(
-                        ',',
-                        ': ' ) ) )
+        consistentIntents = True
+        intentsResults = True
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].intents,
+                             name="intents-" + str( i ),
+                             args=[],
+                             kwargs={ 'jsonFormat': True } )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            ONOSIntents.append( t.result )
+
+        for i in range( numControllers ):
+            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
+                main.log.report( "Error in getting ONOS" + str( i + 1 ) +
+                                 " intents" )
+                main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
+                               repr( ONOSIntents[ i ] ) )
+                intentsResults = False
         utilities.assert_equals(
-            expect=main.TRUE,
-            actual=intentCheck,
+            expect=True,
+            actual=intentsResults,
+            onpass="No error in reading intents output",
+            onfail="Error in reading intents from ONOS" )
+
+        main.step( "Check for consistency in Intents from each controller" )
+        if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
+            main.log.report( "Intents are consistent across all ONOS " +
+                             "nodes" )
+        else:
+            consistentIntents = False
+            main.log.report( "Intents not consistent" )
+        utilities.assert_equals(
+            expect=True,
+            actual=consistentIntents,
             onpass="Intents are consistent across all ONOS nodes",
             onfail="ONOS nodes have different views of intents" )
 
+        if intentsResults and not consistentIntents:
+            n = len(ONOSIntents)
+            main.log.warn( "ONOS" + str( n ) + " intents: " )
+            main.log.warn( json.dumps( json.loads( ONOSIntents[ -1 ] ),
+                                       sort_keys=True,
+                                       indent=4,
+                                       separators=( ',', ': ' ) ) )
+            for i in range( numControllers ):
+                if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
+                    main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
+                    main.log.warn( json.dumps( json.loads( ONOSIntents[i] ),
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                else:
+                    main.log.warn( nodes[ i ].name + " intents match ONOS" +
+                                   str( n ) + " intents" )
+        elif intentsResults and consistentIntents:
+            intentCheck = main.TRUE
+            intentState = ONOSIntents[ 0 ]
+
         main.step( "Get the flows from each controller" )
         global flowState
         flowState = []
-        ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
-        ONOS2Flows = main.ONOScli2.flows( jsonFormat=True )
-        ONOS3Flows = main.ONOScli3.flows( jsonFormat=True )
-        ONOS4Flows = main.ONOScli4.flows( jsonFormat=True )
-        ONOS5Flows = main.ONOScli5.flows( jsonFormat=True )
-        ONOS6Flows = main.ONOScli6.flows( jsonFormat=True )
-        ONOS7Flows = main.ONOScli7.flows( jsonFormat=True )
-        ONOS1FlowsJson = json.loads( ONOS1Flows )
-        ONOS2FlowsJson = json.loads( ONOS2Flows )
-        ONOS3FlowsJson = json.loads( ONOS3Flows )
-        ONOS4FlowsJson = json.loads( ONOS4Flows )
-        ONOS5FlowsJson = json.loads( ONOS5Flows )
-        ONOS6FlowsJson = json.loads( ONOS6Flows )
-        ONOS7FlowsJson = json.loads( ONOS7Flows )
+        ONOSFlows = []
+        ONOSFlowsJson = []
         flowCheck = main.FALSE
-        if "Error" in ONOS1Flows or not ONOS1Flows\
-                or "Error" in ONOS2Flows or not ONOS2Flows\
-                or "Error" in ONOS3Flows or not ONOS3Flows\
-                or "Error" in ONOS4Flows or not ONOS4Flows\
-                or "Error" in ONOS5Flows or not ONOS5Flows\
-                or "Error" in ONOS6Flows or not ONOS6Flows\
-                or "Error" in ONOS7Flows or not ONOS7Flows:
-            main.log.report( "Error in getting ONOS intents" )
-            main.log.warn( "ONOS1 flows repsponse: " + ONOS1Flows )
-            main.log.warn( "ONOS2 flows repsponse: " + ONOS2Flows )
-            main.log.warn( "ONOS3 flows repsponse: " + ONOS3Flows )
-            main.log.warn( "ONOS4 flows repsponse: " + ONOS4Flows )
-            main.log.warn( "ONOS5 flows repsponse: " + ONOS5Flows )
-            main.log.warn( "ONOS6 flows repsponse: " + ONOS6Flows )
-            main.log.warn( "ONOS7 flows repsponse: " + ONOS7Flows )
-        elif len( ONOS1FlowsJson ) == len( ONOS2FlowsJson )\
-                and len( ONOS1FlowsJson ) == len( ONOS3FlowsJson )\
-                and len( ONOS1FlowsJson ) == len( ONOS4FlowsJson )\
-                and len( ONOS1FlowsJson ) == len( ONOS5FlowsJson )\
-                and len( ONOS1FlowsJson ) == len( ONOS6FlowsJson )\
-                and len( ONOS1FlowsJson ) == len( ONOS7FlowsJson ):
-                # TODO: Do a better check, maybe compare flows on switches?
-            flowState = ONOS1Flows
-            flowCheck = main.TRUE
+        consistentFlows = True
+        flowsResults = True
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].flows,
+                             name="flows-" + str( i ),
+                             args=[],
+                             kwargs={ 'jsonFormat': True } )
+            threads.append( t )
+            t.start()
+
+        # FIXME: why am I sleeping here?
+        time.sleep(30)
+        for t in threads:
+            t.join()
+            result = t.result
+            ONOSFlows.append( result )
+
+        for i in range( numControllers ):
+            num = str( i + 1 )
+            if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
+                main.log.report( "Error in getting ONOS" + num + " flows" )
+                main.log.warn( "ONOS" + num + " flows response: " +
+                               repr( ONOSFlows[ i ] ) )
+                flowsResults = False
+                ONOSFlowsJson.append( None )
+            else:
+                try:
+                    ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
+                except ( ValueError, TypeError ):
+                    # FIXME: change this to log.error?
+                    main.log.exception( "Error in parsing ONOS" + num +
+                                        " response as json." )
+                    main.log.error( repr( ONOSFlows[ i ] ) )
+                    ONOSFlowsJson.append( None )
+                    flowsResults = False
+        utilities.assert_equals(
+            expect=True,
+            actual=flowsResults,
+            onpass="No error in reading flows output",
+            onfail="Error in reading flows from ONOS" )
+
+        main.step( "Check for consistency in Flows from each controller" )
+        tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
+        if all( tmp ):
             main.log.report( "Flow count is consistent across all ONOS nodes" )
         else:
-            main.log.warn( "ONOS1 flows: " +
-                           json.dumps( ONOS1FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS2 flows: " +
-                           json.dumps( ONOS2FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS3 flows: " +
-                           json.dumps( ONOS3FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS4 flows: " +
-                           json.dumps( ONOS4FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS5 flows: " +
-                           json.dumps( ONOS5FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS6 flows: " +
-                           json.dumps( ONOS6FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS7 flows: " +
-                           json.dumps( ONOS7FlowsJson, sort_keys=True,
-                                       indent=4, separators=( ',', ': ' ) ) )
+            consistentFlows = False
         utilities.assert_equals(
-            expect=main.TRUE,
-            actual=flowCheck,
+            expect=True,
+            actual=consistentFlows,
             onpass="The flow count is consistent across all ONOS nodes",
             onfail="ONOS nodes have different flow counts" )
 
+        if flowsResults and not consistentFlows:
+            for i in range( numControllers ):
+                try:
+                    main.log.warn(
+                        "ONOS" + str( i + 1 ) + " flows: " +
+                        json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
+                                    indent=4, separators=( ',', ': ' ) ) )
+                except ( ValueError, TypeError ):
+                    main.log.warn(
+                        "ONOS" + str( i + 1 ) + " flows: " +
+                        repr( ONOSFlows[ i ] ) )
+        elif flowsResults and consistentFlows:
+            flowCheck = main.TRUE
+            flowState = ONOSFlows[ 0 ]
+
         main.step( "Get the OF Table entries" )
         global flows
         flows = []
         for i in range( 1, 29 ):
             flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
-
+        if flowCheck == main.FALSE:
+            for table in flows:
+                main.log.warn( table )
         # TODO: Compare switch flow tables with ONOS flow tables
 
         main.step( "Start continuous pings" )
@@ -907,64 +1207,80 @@
 
         main.step( "Create TestONTopology object" )
         ctrls = []
-        count = 1
-        while True:
-            temp = ()
-            if ( 'ip' + str( count ) ) in main.params[ 'CTRL' ]:
-                temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
-                temp = temp + ( "ONOS" + str( count ), )
-                temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
-                temp = temp + \
-                    ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
-                ctrls.append( temp )
-                count = count + 1
-            else:
-                break
-        MNTopo = TestONTopology(
-            main.Mininet1,
-            ctrls )  # can also add Intent API info for intent operations
+        for node in nodes:
+            temp = ( node, node.name, node.ip_address, 6633 )
+            ctrls.append( temp )
+        MNTopo = TestONTopology( main.Mininet1, ctrls )
 
         main.step( "Collecting topology information from ONOS" )
         devices = []
-        devices.append( main.ONOScli1.devices() )
-        devices.append( main.ONOScli2.devices() )
-        devices.append( main.ONOScli3.devices() )
-        devices.append( main.ONOScli4.devices() )
-        devices.append( main.ONOScli5.devices() )
-        devices.append( main.ONOScli6.devices() )
-        devices.append( main.ONOScli7.devices() )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].devices,
+                             name="devices-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            devices.append( t.result )
         hosts = []
-        hosts.append( main.ONOScli1.hosts() )
-        hosts.append( main.ONOScli2.hosts() )
-        hosts.append( main.ONOScli3.hosts() )
-        hosts.append( main.ONOScli4.hosts() )
-        hosts.append( main.ONOScli5.hosts() )
-        hosts.append( main.ONOScli6.hosts() )
-        hosts.append( main.ONOScli7.hosts() )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].hosts,
+                             name="hosts-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            try:
+                hosts.append( json.loads( t.result ) )
+            except ( ValueError, TypeError ):
+                # FIXME: better handling of this, print which node
+                #        Maybe use thread name?
+                main.log.exception( "Error parsing json output of hosts" )
+                # FIXME: should this be an empty json object instead?
+                hosts.append( None )
+
         ports = []
-        ports.append( main.ONOScli1.ports() )
-        ports.append( main.ONOScli2.ports() )
-        ports.append( main.ONOScli3.ports() )
-        ports.append( main.ONOScli4.ports() )
-        ports.append( main.ONOScli5.ports() )
-        ports.append( main.ONOScli6.ports() )
-        ports.append( main.ONOScli7.ports() )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].ports,
+                             name="ports-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            ports.append( t.result )
         links = []
-        links.append( main.ONOScli1.links() )
-        links.append( main.ONOScli2.links() )
-        links.append( main.ONOScli3.links() )
-        links.append( main.ONOScli4.links() )
-        links.append( main.ONOScli5.links() )
-        links.append( main.ONOScli6.links() )
-        links.append( main.ONOScli7.links() )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].links,
+                             name="links-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            links.append( t.result )
         clusters = []
-        clusters.append( main.ONOScli1.clusters() )
-        clusters.append( main.ONOScli2.clusters() )
-        clusters.append( main.ONOScli3.clusters() )
-        clusters.append( main.ONOScli4.clusters() )
-        clusters.append( main.ONOScli5.clusters() )
-        clusters.append( main.ONOScli6.clusters() )
-        clusters.append( main.ONOScli7.clusters() )
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].clusters,
+                             name="clusters-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            clusters.append( t.result )
         # Compare json objects for hosts and dataplane clusters
 
         # hosts
@@ -994,15 +1310,29 @@
             onpass="Hosts view is consistent across all ONOS nodes",
             onfail="ONOS nodes have different views of hosts" )
 
+        ipResult = main.TRUE
+        for controller in range( 0, len( hosts ) ):
+            controllerStr = str( controller + 1 )
+            for host in hosts[ controller ]:
+                if not host.get( 'ips', [ ] ):
+                    main.log.error( "DEBUG:Error with host ips on controller" +
+                                    controllerStr + ": " + str( host ) )
+                    ipResult = main.FALSE
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=ipResult,
+            onpass="The ips of the hosts aren't empty",
+            onfail="The ip of at least one host is missing" )
+
         # Strongly connected clusters of devices
         consistentClustersResult = main.TRUE
         for controller in range( len( clusters ) ):
+            controllerStr = str( controller + 1 )
             if "Error" not in clusters[ controller ]:
                 if clusters[ controller ] == clusters[ 0 ]:
                     continue
                 else:  # clusters not consistent
-                    main.log.report( "clusters from ONOS" +
-                                     controllerStr +
+                    main.log.report( "clusters from ONOS" + controllerStr +
                                      " is inconsistent with ONOS1" )
                     consistentClustersResult = main.FALSE
 
@@ -1019,14 +1349,19 @@
             onpass="Clusters view is consistent across all ONOS nodes",
             onfail="ONOS nodes have different views of clusters" )
         # there should always only be one cluster
-        numClusters = len( json.loads( clusters[ 0 ] ) )
+        try:
+            numClusters = len( json.loads( clusters[ 0 ] ) )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing clusters[0]: " +
+                                repr( clusters[ 0 ] ) )
+        clusterResults = main.FALSE
+        if numClusters == 1:
+            clusterResults = main.TRUE
         utilities.assert_equals(
             expect=1,
             actual=numClusters,
             onpass="ONOS shows 1 SCC",
-            onfail="ONOS shows " +
-            str( numClusters ) +
-            " SCCs" )
+            onfail="ONOS shows " + str( numClusters ) + " SCCs" )
 
         main.step( "Comparing ONOS topology to MN" )
         devicesResults = main.TRUE
@@ -1037,67 +1372,71 @@
             if devices[ controller ] or "Error" not in devices[ controller ]:
                 currentDevicesResult = main.Mininet1.compareSwitches(
                     MNTopo,
-                    json.loads(
-                        devices[ controller ] ) )
+                    json.loads( devices[ 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" )
+                                     actual=currentDevicesResult,
+                                     onpass="ONOS" + controllerStr +
+                                     " Switches view is correct",
+                                     onfail="ONOS" + controllerStr +
+                                     " Switches view is incorrect" )
 
             if ports[ controller ] or "Error" not in ports[ controller ]:
                 currentPortsResult = main.Mininet1.comparePorts(
                     MNTopo,
-                    json.loads(
-                        ports[ controller ] ) )
+                    json.loads( ports[ controller ] ) )
             else:
                 currentPortsResult = main.FALSE
             utilities.assert_equals( expect=main.TRUE,
-                                    actual=currentPortsResult,
-                                    onpass="ONOS" + controllerStr +
-                                    " ports view is correct",
-                                    onfail="ONOS" + controllerStr +
-                                    " ports view is incorrect" )
+                                     actual=currentPortsResult,
+                                     onpass="ONOS" + controllerStr +
+                                     " ports view is correct",
+                                     onfail="ONOS" + controllerStr +
+                                     " ports view is incorrect" )
 
             if links[ controller ] or "Error" not in links[ controller ]:
                 currentLinksResult = main.Mininet1.compareLinks(
                     MNTopo,
-                    json.loads(
-                        links[ controller ] ) )
+                    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" )
+                                     actual=currentLinksResult,
+                                     onpass="ONOS" + controllerStr +
+                                     " links view is correct",
+                                     onfail="ONOS" + controllerStr +
+                                     " links view is incorrect" )
 
             devicesResults = devicesResults and currentDevicesResult
             portsResults = portsResults and currentPortsResult
             linksResults = linksResults and currentLinksResult
 
-        topoResult = devicesResults and portsResults and linksResults\
-            and consistentHostsResult and consistentClustersResult
+        topoResult = ( devicesResults and portsResults and linksResults
+                       and consistentHostsResult and consistentClustersResult
+                       and clusterResults and ipResult )
         utilities.assert_equals( expect=main.TRUE, actual=topoResult,
-                                onpass="Topology Check Test successful",
-                                onfail="Topology Check Test NOT successful" )
+                                 onpass="Topology Check Test successful",
+                                 onfail="Topology Check Test NOT successful" )
 
         finalAssert = main.TRUE
-        finalAssert = finalAssert and topoResult and flowCheck \
-            and intentCheck and consistentMastership and rolesNotNull
+        finalAssert = ( finalAssert and topoResult and flowCheck
+                        and intentCheck and consistentMastership
+                        and rolesNotNull )
         utilities.assert_equals( expect=main.TRUE, actual=finalAssert,
-                                onpass="State check successful",
-                                onfail="State check NOT successful" )
+                                 onpass="State check successful",
+                                 onfail="State check NOT successful" )
 
     def CASE6( self, main ):
         """
         The Failure case. Since this is the Sanity test, we do nothing.
         """
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         main.log.report( "Wait 60 seconds instead of inducing a failure" )
         time.sleep( 60 )
         utilities.assert_equals(
@@ -1111,107 +1450,103 @@
         Check state after ONOS failure
         """
         import json
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         main.case( "Running ONOS Constant State Tests" )
 
+        main.step( "Check that each switch has a master" )
         # Assert that each device has a master
-        ONOS1MasterNotNull = main.ONOScli1.rolesNotNull()
-        ONOS2MasterNotNull = main.ONOScli2.rolesNotNull()
-        ONOS3MasterNotNull = main.ONOScli3.rolesNotNull()
-        ONOS4MasterNotNull = main.ONOScli4.rolesNotNull()
-        ONOS5MasterNotNull = main.ONOScli5.rolesNotNull()
-        ONOS6MasterNotNull = main.ONOScli6.rolesNotNull()
-        ONOS7MasterNotNull = main.ONOScli7.rolesNotNull()
-        rolesNotNull = ONOS1MasterNotNull and ONOS2MasterNotNull and\
-            ONOS3MasterNotNull and ONOS4MasterNotNull and\
-            ONOS5MasterNotNull and ONOS6MasterNotNull and\
-            ONOS7MasterNotNull
+        rolesNotNull = main.TRUE
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].rolesNotNull,
+                             name="rolesNotNull-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            rolesNotNull = rolesNotNull and t.result
         utilities.assert_equals(
             expect=main.TRUE,
             actual=rolesNotNull,
             onpass="Each device has a master",
             onfail="Some devices don't have a master assigned" )
 
-        main.step( "Check if switch roles are consistent across all nodes" )
-        ONOS1Mastership = main.ONOScli1.roles()
-        ONOS2Mastership = main.ONOScli2.roles()
-        ONOS3Mastership = main.ONOScli3.roles()
-        ONOS4Mastership = main.ONOScli4.roles()
-        ONOS5Mastership = main.ONOScli5.roles()
-        ONOS6Mastership = main.ONOScli6.roles()
-        ONOS7Mastership = main.ONOScli7.roles()
-        if "Error" in ONOS1Mastership or not ONOS1Mastership\
-                or "Error" in ONOS2Mastership or not ONOS2Mastership\
-                or "Error" in ONOS3Mastership or not ONOS3Mastership\
-                or "Error" in ONOS4Mastership or not ONOS4Mastership\
-                or "Error" in ONOS5Mastership or not ONOS5Mastership\
-                or "Error" in ONOS6Mastership or not ONOS6Mastership\
-                or "Error" in ONOS7Mastership or not ONOS7Mastership:
-            main.log.error( "Error in getting ONOS mastership" )
-            main.log.warn( "ONOS1 mastership response: " +
-                           repr( ONOS1Mastership ) )
-            main.log.warn( "ONOS2 mastership response: " +
-                           repr( ONOS2Mastership ) )
-            main.log.warn( "ONOS3 mastership response: " +
-                           repr( ONOS3Mastership ) )
-            main.log.warn( "ONOS4 mastership response: " +
-                           repr( ONOS4Mastership ) )
-            main.log.warn( "ONOS5 mastership response: " +
-                           repr( ONOS5Mastership ) )
-            main.log.warn( "ONOS6 mastership response: " +
-                           repr( ONOS6Mastership ) )
-            main.log.warn( "ONOS7 mastership response: " +
-                           repr( ONOS7Mastership ) )
-            consistentMastership = main.FALSE
-        elif ONOS1Mastership == ONOS2Mastership\
-                and ONOS1Mastership == ONOS3Mastership\
-                and ONOS1Mastership == ONOS4Mastership\
-                and ONOS1Mastership == ONOS5Mastership\
-                and ONOS1Mastership == ONOS6Mastership\
-                and ONOS1Mastership == ONOS7Mastership:
-            consistentMastership = main.TRUE
+        ONOSMastership = []
+        mastershipCheck = main.FALSE
+        consistentMastership = True
+        rolesResults = True
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].roles,
+                             name="roles-" + str( i ),
+                             args=[] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            ONOSMastership.append( t.result )
+
+        for i in range( numControllers ):
+            if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
+                main.log.report( "Error in getting ONOS" + str( i + 1 ) +
+                                 " roles" )
+                main.log.warn(
+                    "ONOS" + str( i + 1 ) + " mastership response: " +
+                    repr( ONOSMastership[i] ) )
+                rolesResults = False
+        utilities.assert_equals(
+            expect=True,
+            actual=rolesResults,
+            onpass="No error in reading roles output",
+            onfail="Error in reading roles from ONOS" )
+
+        main.step( "Check for consistency in roles from each controller" )
+        if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
             main.log.report(
                 "Switch roles are consistent across all ONOS nodes" )
         else:
-            main.log.warn( "ONOS1 roles: ", json.dumps(
-                json.loads( ONOS1Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS2 roles: ", json.dumps(
-                json.loads( ONOS2Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS3 roles: ", json.dumps(
-                json.loads( ONOS3Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS4 roles: ", json.dumps(
-                json.loads( ONOS4Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS5 roles: ", json.dumps(
-                json.loads( ONOS5Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS6 roles: ", json.dumps(
-                json.loads( ONOS6Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            main.log.warn( "ONOS7 roles: ", json.dumps(
-                json.loads( ONOS7Mastership ), sort_keys=True, indent=4,
-                separators=( ',', ': ' ) ) )
-            consistentMastership = main.FALSE
+            consistentMastership = False
         utilities.assert_equals(
-            expect=main.TRUE,
+            expect=True,
             actual=consistentMastership,
             onpass="Switch roles are consistent across all ONOS nodes",
             onfail="ONOS nodes have different views of switch roles" )
 
+        if rolesResults and not consistentMastership:
+            for i in range( numControllers ):
+                main.log.warn(
+                    "ONOS" + str( i + 1 ) + " roles: ",
+                    json.dumps(
+                        json.loads( ONOSMastership[ i ] ),
+                        sort_keys=True,
+                        indent=4,
+                        separators=( ',', ': ' ) ) )
+        elif rolesResults and not consistentMastership:
+            mastershipCheck = main.TRUE
+
         description2 = "Compare switch roles from before failure"
         main.step( description2 )
-
-        currentJson = json.loads( ONOS1Mastership )
-        oldJson = json.loads( mastershipState )
+        try:
+            currentJson = json.loads( ONOSMastership[0] )
+            oldJson = json.loads( mastershipState )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Something is wrong with parsing " +
+                                "ONOSMastership[0] or mastershipState" )
+            main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
+            main.log.error( "mastershipState" + repr( mastershipState ) )
+            main.cleanup()
+            main.exit()
         mastershipCheck = main.TRUE
         for i in range( 1, 29 ):
             switchDPID = str(
-                main.Mininet1.getSwitchDPID(
-                    switch="s" +
-                    str( i ) ) )
-
+                main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
             current = [ switch[ 'master' ] for switch in currentJson
                         if switchDPID in switch[ 'id' ] ]
             old = [ switch[ 'master' ] for switch in oldJson
@@ -1231,102 +1566,92 @@
         mastershipCheck = mastershipCheck and consistentMastership
 
         main.step( "Get the intents and compare across all nodes" )
-        ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
-        ONOS2Intents = main.ONOScli2.intents( jsonFormat=True )
-        ONOS3Intents = main.ONOScli3.intents( jsonFormat=True )
-        ONOS4Intents = main.ONOScli4.intents( jsonFormat=True )
-        ONOS5Intents = main.ONOScli5.intents( jsonFormat=True )
-        ONOS6Intents = main.ONOScli6.intents( jsonFormat=True )
-        ONOS7Intents = main.ONOScli7.intents( jsonFormat=True )
+        ONOSIntents = []
         intentCheck = main.FALSE
-        if "Error" in ONOS1Intents or not ONOS1Intents\
-                or "Error" in ONOS2Intents or not ONOS2Intents\
-                or "Error" in ONOS3Intents or not ONOS3Intents\
-                or "Error" in ONOS4Intents or not ONOS4Intents\
-                or "Error" in ONOS5Intents or not ONOS5Intents\
-                or "Error" in ONOS6Intents or not ONOS6Intents\
-                or "Error" in ONOS7Intents or not ONOS7Intents:
-            main.log.report( "Error in getting ONOS intents" )
-            main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
-            main.log.warn( "ONOS2 intents response: " + repr( ONOS2Intents ) )
-            main.log.warn( "ONOS3 intents response: " + repr( ONOS3Intents ) )
-            main.log.warn( "ONOS4 intents response: " + repr( ONOS4Intents ) )
-            main.log.warn( "ONOS5 intents response: " + repr( ONOS5Intents ) )
-            main.log.warn( "ONOS6 intents response: " + repr( ONOS6Intents ) )
-            main.log.warn( "ONOS7 intents response: " + repr( ONOS7Intents ) )
-        elif ONOS1Intents == ONOS2Intents\
-                and ONOS1Intents == ONOS3Intents\
-                and ONOS1Intents == ONOS4Intents\
-                and ONOS1Intents == ONOS5Intents\
-                and ONOS1Intents == ONOS6Intents\
-                and ONOS1Intents == ONOS7Intents:
-            intentCheck = main.TRUE
-            main.log.report( "Intents are consistent across all ONOS nodes" )
-        else:
-            main.log.warn( "ONOS1 intents: " )
-            print json.dumps( json.loads( ONOS1Intents ), sort_keys=True,
-                              indent=4, separators=( ',', ': ' ) )
-            main.log.warn( "ONOS2 intents: " )
-            print json.dumps( json.loads( ONOS2Intents ), sort_keys=True,
-                              indent=4, separators=( ',', ': ' ) )
-            main.log.warn( "ONOS3 intents: " )
-            print json.dumps( json.loads( ONOS3Intents ), sort_keys=True,
-                              indent=4, separators=( ',', ': ' ) )
-            main.log.warn( "ONOS4 intents: " )
-            print json.dumps( json.loads( ONOS4Intents ), sort_keys=True,
-                              indent=4, separators=( ',', ': ' ) )
-            main.log.warn( "ONOS5 intents: " )
-            print json.dumps( json.loads( ONOS5Intents ), sort_keys=True,
-                              indent=4, separators=( ',', ': ' ) )
-            main.log.warn( "ONOS6 intents: " )
-            print json.dumps( json.loads( ONOS6Intents ), sort_keys=True,
-                              indent=4, separators=( ',', ': ' ) )
-            main.log.warn( "ONOS7 intents: " )
-            print json.dumps( json.loads( ONOS7Intents ), sort_keys=True,
-                              indent=4, separators=( ',', ': ' ) )
+        consistentIntents = True
+        intentsResults = True
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].intents,
+                             name="intents-" + str( i ),
+                             args=[],
+                             kwargs={ 'jsonFormat': True } )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            ONOSIntents.append( t.result )
+
+        for i in range( numControllers ):
+            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
+                main.log.report( "Error in getting ONOS" + str( i + 1 ) +
+                                 " intents" )
+                main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
+                               repr( ONOSIntents[ i ] ) )
+                intentsResults = False
         utilities.assert_equals(
-            expect=main.TRUE,
-            actual=intentCheck,
+            expect=True,
+            actual=intentsResults,
+            onpass="No error in reading intents output",
+            onfail="Error in reading intents from ONOS" )
+
+        main.step( "Check for consistency in Intents from each controller" )
+        if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
+            main.log.report( "Intents are consistent across all ONOS " +
+                             "nodes" )
+        else:
+            consistentIntents = False
+        utilities.assert_equals(
+            expect=True,
+            actual=consistentIntents,
             onpass="Intents are consistent across all ONOS nodes",
             onfail="ONOS nodes have different views of intents" )
-        # Print the intent states
-        intents = []
-        intents.append( ONOS1Intents )
-        intents.append( ONOS2Intents )
-        intents.append( ONOS3Intents )
-        intents.append( ONOS4Intents )
-        intents.append( ONOS5Intents )
-        intents.append( ONOS6Intents )
-        intents.append( ONOS7Intents )
         intentStates = []
-        for node in intents:  # Iter through ONOS nodes
+        for node in ONOSIntents:  # Iter through ONOS nodes
             nodeStates = []
-            for intent in json.loads( node ):  # Iter through intents of a node
-                nodeStates.append( intent[ 'state' ] )
+            # Iter through intents of a node
+            try:
+                for intent in json.loads( node ):
+                    nodeStates.append( intent[ 'state' ] )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error in parsing intents" )
+                main.log.error( repr( node ) )
             intentStates.append( nodeStates )
             out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
             main.log.info( dict( out ) )
 
+        if intentsResults and not consistentIntents:
+            for i in range( numControllers ):
+                main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
+                main.log.warn( json.dumps(
+                    json.loads( ONOSIntents[ i ] ),
+                    sort_keys=True,
+                    indent=4,
+                    separators=( ',', ': ' ) ) )
+        elif intentsResults and consistentIntents:
+            intentCheck = main.TRUE
 
-        # NOTE: Hazelcast has no durability, so intents are lost across system
-        # restarts
+        # NOTE: Store has no durability, so intents are lost across system
+        #       restarts
         main.step( "Compare current intents with intents before the failure" )
         # NOTE: this requires case 5 to pass for intentState to be set.
         #      maybe we should stop the test if that fails?
         sameIntents = main.TRUE
-        if intentState and intentState == ONOS1Intents:
+        if intentState and intentState == ONOSIntents[ 0 ]:
             sameIntents = main.TRUE
             main.log.report( "Intents are consistent with before failure" )
         # TODO: possibly the states have changed? we may need to figure out
-        # what the aceptable states are
+        #       what the acceptable states are
         else:
             try:
-                main.log.warn( "ONOS1 intents: " )
-                print json.dumps( json.loads( ONOS1Intents ),
-                                  sort_keys=True, indent=4,
-                                  separators=( ',', ': ' ) )
-            except:
-                pass
+                main.log.warn( "ONOS intents: " )
+                main.log.warn( json.dumps( json.loads( ONOSIntents[ 0 ] ),
+                                           sort_keys=True, indent=4,
+                                           separators=( ',', ': ' ) ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Exception printing intents" )
+                main.log.warn( repr( ONOSIntents[0] ) )
             sameIntents = main.FALSE
         utilities.assert_equals(
             expect=main.TRUE,
@@ -1360,12 +1685,8 @@
 
         main.step( "Check the continuous pings to ensure that no packets " +
                    "were dropped during component failure" )
-        # FIXME: This check is always failing. Investigate cause
-        # NOTE:  this may be something to do with file permsissions
-        #       or slight change in format
-        main.Mininet2.pingKill(
-            main.params[ 'TESTONUSER' ],
-            main.params[ 'TESTONIP' ] )
+        main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
+                                main.params[ 'TESTONIP' ] )
         LossInPings = main.FALSE
         # NOTE: checkForLoss returns main.FALSE with 0% packet loss
         for i in range( 8, 18 ):
@@ -1390,13 +1711,11 @@
 
         # Test of LeadershipElection
         # NOTE: this only works for the sanity test. In case of failures,
-        # leader will likely change
-        leader = ONOS1Ip
+        #       leader will likely change
+        leader = nodes[ 0 ].ip_address
         leaderResult = main.TRUE
-        for controller in range( 1, numControllers + 1 ):
-            # loop through ONOScli handlers
-            node = getattr( main, ( 'ONOScli' + str( controller ) ) )
-            leaderN = node.electionTestLeader()
+        for cli in CLIs:
+            leaderN = cli.electionTestLeader()
             # verify leader is ONOS1
             if leaderN == leader:
                 # all is well
@@ -1404,15 +1723,14 @@
                 # check != ONOS1
                 pass
             elif leaderN == main.FALSE:
-                # error in  response
+                # error in response
                 main.log.report( "Something is wrong with " +
-                                 "electionTestLeader function," +
-                                 " check the error logs" )
+                                 "electionTestLeader function, check the" +
+                                 " error logs" )
                 leaderResult = main.FALSE
             elif leader != leaderN:
                 leaderResult = main.FALSE
-                main.log.report( "ONOS" + str( controller ) + " sees " +
-                                 str( leaderN ) +
+                main.log.report( cli.name + " sees " + str( leaderN ) +
                                  " as the leader of the election app. " +
                                  "Leader should be " + str( leader ) )
         if leaderResult:
@@ -1425,14 +1743,14 @@
             onpass="Leadership election passed",
             onfail="Something went wrong with Leadership election" )
 
-        result = mastershipCheck and intentCheck and FlowTables and\
-            ( not LossInPings ) and rolesNotNull and leaderResult
+        result = ( mastershipCheck and intentCheck and FlowTables and
+                   ( not LossInPings ) and rolesNotNull and leaderResult )
         result = int( result )
         if result == main.TRUE:
             main.log.report( "Constant State Tests Passed" )
         utilities.assert_equals( expect=main.TRUE, actual=result,
-                                onpass="Constant State Tests Passed",
-                                onfail="Constant state tests failed" )
+                                 onpass="Constant State Tests Passed",
+                                 onfail="Constant state tests failed" )
 
     def CASE8( self, main ):
         """
@@ -1445,33 +1763,27 @@
         from sts.topology.teston_topology import TestONTopology
         import json
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
 
         description = "Compare ONOS Topology view to Mininet topology"
         main.case( description )
         main.log.report( description )
         main.step( "Create TestONTopology object" )
         ctrls = []
-        count = 1
-        while True:
-            temp = ()
-            if ( 'ip' + str( count ) ) in main.params[ 'CTRL' ]:
-                temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
-                temp = temp + ( "ONOS" + str( count ), )
-                temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
-                temp = temp + \
-                    ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
-                ctrls.append( temp )
-                count = count + 1
-            else:
-                break
-        MNTopo = TestONTopology(
-            main.Mininet1,
-            ctrls )  # can also add Intent API info for intent operations
+        for node in nodes:
+            temp = ( node, node.name, node.ip_address, 6633 )
+            ctrls.append( temp )
+        MNTopo = TestONTopology( main.Mininet1, ctrls )
 
         main.step( "Comparing ONOS topology to MN" )
         devicesResults = main.TRUE
         portsResults = main.TRUE
         linksResults = main.TRUE
+        hostsResults = main.TRUE
         topoResult = main.FALSE
         elapsed = 0
         count = 0
@@ -1479,60 +1791,84 @@
         startTime = time.time()
         # Give time for Gossip to work
         while topoResult == main.FALSE and elapsed < 60:
-            count = count + 1
+            count += 1
             if count > 1:
-                # TODO: Depricate STS usage
-                MNTopo = TestONTopology(
-                    main.Mininet1,
-                    ctrls )
+                # TODO: Deprecate STS usage
+                MNTopo = TestONTopology( main.Mininet1, ctrls )
             cliStart = time.time()
             devices = []
-            devices.append( main.ONOScli1.devices() )
-            devices.append( main.ONOScli2.devices() )
-            devices.append( main.ONOScli3.devices() )
-            devices.append( main.ONOScli4.devices() )
-            devices.append( main.ONOScli5.devices() )
-            devices.append( main.ONOScli6.devices() )
-            devices.append( main.ONOScli7.devices() )
+            threads = []
+            for i in range( numControllers ):
+                t = main.Thread( target=CLIs[i].devices,
+                                 name="devices-" + str( i ),
+                                 args=[ ] )
+                threads.append( t )
+                t.start()
+
+            for t in threads:
+                t.join()
+                devices.append( t.result )
             hosts = []
-            hosts.append( json.loads( main.ONOScli1.hosts() ) )
-            hosts.append( json.loads( main.ONOScli2.hosts() ) )
-            hosts.append( json.loads( main.ONOScli3.hosts() ) )
-            hosts.append( json.loads( main.ONOScli4.hosts() ) )
-            hosts.append( json.loads( main.ONOScli5.hosts() ) )
-            hosts.append( json.loads( main.ONOScli6.hosts() ) )
-            hosts.append( json.loads( main.ONOScli7.hosts() ) )
+            ipResult = main.TRUE
+            threads = []
+            for i in range( numControllers ):
+                t = main.Thread( target=CLIs[i].hosts,
+                                 name="hosts-" + str( i ),
+                                 args=[ ] )
+                threads.append( t )
+                t.start()
+
+            for t in threads:
+                t.join()
+                try:
+                    hosts.append( json.loads( t.result ) )
+                except ( ValueError, TypeError ):
+                    main.log.exception( "Error parsing hosts results" )
+                    main.log.error( repr( t.result ) )
             for controller in range( 0, len( hosts ) ):
                 controllerStr = str( controller + 1 )
                 for host in hosts[ controller ]:
-                    if host[ 'ips' ] == []:
+                    if host is None or host.get( 'ips', [] ) == []:
                         main.log.error(
                             "DEBUG:Error with host ips on controller" +
                             controllerStr + ": " + str( host ) )
+                        ipResult = main.FALSE
             ports = []
-            ports.append( main.ONOScli1.ports() )
-            ports.append( main.ONOScli2.ports() )
-            ports.append( main.ONOScli3.ports() )
-            ports.append( main.ONOScli4.ports() )
-            ports.append( main.ONOScli5.ports() )
-            ports.append( main.ONOScli6.ports() )
-            ports.append( main.ONOScli7.ports() )
+            threads = []
+            for i in range( numControllers ):
+                t = main.Thread( target=CLIs[i].ports,
+                                 name="ports-" + str( i ),
+                                 args=[ ] )
+                threads.append( t )
+                t.start()
+
+            for t in threads:
+                t.join()
+                ports.append( t.result )
             links = []
-            links.append( main.ONOScli1.links() )
-            links.append( main.ONOScli2.links() )
-            links.append( main.ONOScli3.links() )
-            links.append( main.ONOScli4.links() )
-            links.append( main.ONOScli5.links() )
-            links.append( main.ONOScli6.links() )
-            links.append( main.ONOScli7.links() )
+            threads = []
+            for i in range( numControllers ):
+                t = main.Thread( target=CLIs[i].links,
+                                 name="links-" + str( i ),
+                                 args=[ ] )
+                threads.append( t )
+                t.start()
+
+            for t in threads:
+                t.join()
+                links.append( t.result )
             clusters = []
-            clusters.append( main.ONOScli1.clusters() )
-            clusters.append( main.ONOScli2.clusters() )
-            clusters.append( main.ONOScli3.clusters() )
-            clusters.append( main.ONOScli4.clusters() )
-            clusters.append( main.ONOScli5.clusters() )
-            clusters.append( main.ONOScli6.clusters() )
-            clusters.append( main.ONOScli7.clusters() )
+            threads = []
+            for i in range( numControllers ):
+                t = main.Thread( target=CLIs[i].clusters,
+                                 name="clusters-" + str( i ),
+                                 args=[ ] )
+                threads.append( t )
+                t.start()
+
+            for t in threads:
+                t.join()
+                clusters.append( t.result )
 
             elapsed = time.time() - startTime
             cliTime = time.time() - cliStart
@@ -1544,47 +1880,58 @@
                         controller ]:
                     currentDevicesResult = main.Mininet1.compareSwitches(
                         MNTopo,
-                        json.loads(
-                            devices[ controller ] ) )
+                        json.loads( devices[ 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" )
+                                         actual=currentDevicesResult,
+                                         onpass="ONOS" + controllerStr +
+                                         " Switches view is correct",
+                                         onfail="ONOS" + controllerStr +
+                                         " Switches view is incorrect" )
 
                 if ports[ controller ] or "Error" not in ports[ controller ]:
                     currentPortsResult = main.Mininet1.comparePorts(
                         MNTopo,
-                        json.loads(
-                            ports[ controller ] ) )
+                        json.loads( ports[ controller ] ) )
                 else:
                     currentPortsResult = main.FALSE
                 utilities.assert_equals( expect=main.TRUE,
-                                        actual=currentPortsResult,
-                                        onpass="ONOS" + controllerStr +
-                                        " ports view is correct",
-                                        onfail="ONOS" + controllerStr +
-                                        " ports view is incorrect" )
+                                         actual=currentPortsResult,
+                                         onpass="ONOS" + controllerStr +
+                                         " ports view is correct",
+                                         onfail="ONOS" + controllerStr +
+                                         " ports view is incorrect" )
 
                 if links[ controller ] or "Error" not in links[ controller ]:
                     currentLinksResult = main.Mininet1.compareLinks(
                         MNTopo,
-                        json.loads(
-                            links[ controller ] ) )
+                        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" )
-            devicesResults = devicesResults and currentDevicesResult
-            portsResults = portsResults and currentPortsResult
-            linksResults = linksResults and currentLinksResult
+                                         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(
+                        MNTopo, 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" )
+
+                devicesResults = devicesResults and currentDevicesResult
+                portsResults = portsResults and currentPortsResult
+                linksResults = linksResults and currentLinksResult
+                hostsResults = hostsResults and currentHostsResult
 
             # Compare json objects for hosts and dataplane clusters
 
@@ -1640,18 +1987,24 @@
                 onpass="Clusters view is consistent across all ONOS nodes",
                 onfail="ONOS nodes have different views of clusters" )
             # there should always only be one cluster
-            numClusters = len( json.loads( clusters[ 0 ] ) )
+            try:
+                numClusters = len( json.loads( clusters[ 0 ] ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing clusters[0]: " +
+                                    repr( clusters[0] ) )
+            clusterResults = main.FALSE
+            if numClusters == 1:
+                clusterResults = main.TRUE
             utilities.assert_equals(
                 expect=1,
                 actual=numClusters,
                 onpass="ONOS shows 1 SCC",
-                onfail="ONOS shows " +
-                str( numClusters ) +
-                " SCCs" )
+                onfail="ONOS shows " + str( numClusters ) + " SCCs" )
 
             topoResult = ( devicesResults and portsResults and linksResults
-                           and consistentHostsResult
-                           and consistentClustersResult )
+                           and hostsResults and consistentHostsResult
+                           and consistentClustersResult and clusterResults
+                           and ipResult )
 
         topoResult = topoResult and int( count <= 2 )
         note = "note it takes about " + str( int( cliTime ) ) + \
@@ -1662,35 +2015,72 @@
             str( note ) + " ): " + str( elapsed ) + " seconds, " +
             str( count ) + " tries" )
         utilities.assert_equals( expect=main.TRUE, actual=topoResult,
-                                onpass="Topology Check Test successful",
-                                onfail="Topology Check Test NOT successful" )
+                                 onpass="Topology Check Test successful",
+                                 onfail="Topology Check Test NOT successful" )
         if topoResult == main.TRUE:
             main.log.report( "ONOS topology view matches Mininet topology" )
 
+        #FIXME: move this to an ONOS state case
+        main.step( "Checking ONOS nodes" )
+        nodesOutput = []
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].nodes,
+                             name="nodes-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            nodesOutput.append( t.result )
+        ips = [ node.ip_address for node in nodes ]
+        for i in nodesOutput:
+            try:
+                current = json.loads( i )
+                for node in current:
+                    if node['ip'] in ips:  # node in nodes() output is in cell
+                        if node['state'] == 'ACTIVE':
+                            pass # as it should be
+                        else:
+                            main.log.error( "Error in ONOS node availability" )
+                            main.log.error(
+                                    json.dumps( current,
+                                                sort_keys=True,
+                                                indent=4,
+                                                separators=( ',', ': ' ) ) )
+                            break
+            except ( ValueError, TypeError ):
+                main.log.error( "Error parsing nodes output" )
+                main.log.warn( repr( i ) )
+
     def CASE9( self, main ):
         """
         Link s3-s28 down
         """
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         # NOTE: You should probably run a topology check after this
 
         linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
 
         description = "Turn off a link to ensure that Link Discovery " +\
-            "is working properly"
+                      "is working properly"
         main.log.report( description )
         main.case( description )
 
         main.step( "Kill Link between s3 and s28" )
         LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
-        main.log.info(
-            "Waiting " +
-            str( linkSleep ) +
-            " seconds for link down to be discovered" )
+        main.log.info( "Waiting " + str( linkSleep ) +
+                       " seconds for link down to be discovered" )
         time.sleep( linkSleep )
         utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
-                                onpass="Link down succesful",
-                                onfail="Failed to bring link down" )
+                                 onpass="Link down successful",
+                                 onfail="Failed to bring link down" )
         # TODO do some sort of check here
 
     def CASE10( self, main ):
@@ -1698,25 +2088,28 @@
         Link s3-s28 up
         """
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
         # NOTE: You should probably run a topology check after this
 
         linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
 
         description = "Restore a link to ensure that Link Discovery is " + \
-            "working properly"
+                      "working properly"
         main.log.report( description )
         main.case( description )
 
         main.step( "Bring link between s3 and s28 back up" )
         LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
-        main.log.info(
-            "Waiting " +
-            str( linkSleep ) +
-            " seconds for link up to be discovered" )
+        main.log.info( "Waiting " + str( linkSleep ) +
+                       " seconds for link up to be discovered" )
         time.sleep( linkSleep )
         utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
-                                onpass="Link up succesful",
-                                onfail="Failed to bring link up" )
+                                 onpass="Link up successful",
+                                 onfail="Failed to bring link up" )
         # TODO do some sort of check here
 
     def CASE11( self, main ):
@@ -1725,6 +2118,11 @@
         """
         # NOTE: You should probably run a topology check after this
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
 
         switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
 
@@ -1748,8 +2146,8 @@
         if device and device[ 'available' ] is False:
             result = main.TRUE
         utilities.assert_equals( expect=main.TRUE, actual=result,
-                                onpass="Kill switch succesful",
-                                onfail="Failed to kill switch?" )
+                                 onpass="Kill switch successful",
+                                 onfail="Failed to kill switch?" )
 
     def CASE12( self, main ):
         """
@@ -1757,6 +2155,18 @@
         """
         # NOTE: You should probably run a topology check after this
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
+        assert ONOS1Port, "ONOS1Port not defined"
+        assert ONOS2Port, "ONOS2Port not defined"
+        assert ONOS3Port, "ONOS3Port not defined"
+        assert ONOS4Port, "ONOS4Port not defined"
+        assert ONOS5Port, "ONOS5Port not defined"
+        assert ONOS6Port, "ONOS6Port not defined"
+        assert ONOS7Port, "ONOS7Port not defined"
 
         switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
         switch = main.params[ 'kill' ][ 'switch' ]
@@ -1769,30 +2179,26 @@
         main.step( "Add back " + switch )
         main.log.report( "Adding back " + switch )
         main.Mininet1.addSwitch( switch, dpid=switchDPID )
-        # TODO: New dpid or same? Ask Thomas?
         for peer in links:
             main.Mininet1.addLink( switch, peer )
-        main.Mininet1.assignSwController(
-            sw=switch.split( 's' )[ 1 ],
-            count=numControllers,
-            ip1=ONOS1Ip,
-            port1=ONOS1Port,
-            ip2=ONOS2Ip,
-            port2=ONOS2Port,
-            ip3=ONOS3Ip,
-            port3=ONOS3Port,
-            ip4=ONOS4Ip,
-            port4=ONOS4Port,
-            ip5=ONOS5Ip,
-            port5=ONOS5Port,
-            ip6=ONOS6Ip,
-            port6=ONOS6Port,
-            ip7=ONOS7Ip,
-            port7=ONOS7Port )
-        main.log.info(
-            "Waiting " +
-            str( switchSleep ) +
-            " seconds for switch up to be discovered" )
+        main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
+                                          count=numControllers,
+                                          ip1=nodes[ 0 ].ip_address,
+                                          port1=ONOS1Port,
+                                          ip2=nodes[ 1 ].ip_address,
+                                          port2=ONOS2Port,
+                                          ip3=nodes[ 2 ].ip_address,
+                                          port3=ONOS3Port,
+                                          ip4=nodes[ 3 ].ip_address,
+                                          port4=ONOS4Port,
+                                          ip5=nodes[ 4 ].ip_address,
+                                          port5=ONOS5Port,
+                                          ip6=nodes[ 5 ].ip_address,
+                                          port6=ONOS6Port,
+                                          ip7=nodes[ 6 ].ip_address,
+                                          port7=ONOS7Port )
+        main.log.info( "Waiting " + str( switchSleep ) +
+                       " seconds for switch up to be discovered" )
         time.sleep( switchSleep )
         device = main.ONOScli1.getDevice( dpid=switchDPID )
         # Peek at the deleted switch
@@ -1801,8 +2207,8 @@
         if device and device[ 'available' ]:
             result = main.TRUE
         utilities.assert_equals( expect=main.TRUE, actual=result,
-                                onpass="add switch succesful",
-                                onfail="Failed to add switch?" )
+                                 onpass="add switch successful",
+                                 onfail="Failed to add switch?" )
 
     def CASE13( self, main ):
         """
@@ -1810,37 +2216,22 @@
         """
         import os
         import time
-        # TODO: make use of this elsewhere
-        ips = []
-        ips.append( ONOS1Ip )
-        ips.append( ONOS2Ip )
-        ips.append( ONOS3Ip )
-        ips.append( ONOS4Ip )
-        ips.append( ONOS5Ip )
-        ips.append( ONOS6Ip )
-        ips.append( ONOS7Ip )
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
 
         # printing colors to terminal
-        colors = {}
-        colors[ 'cyan' ] = '\033[96m'
-        colors[ 'purple' ] = '\033[95m'
-        colors[ 'blue' ] = '\033[94m'
-        colors[ 'green' ] = '\033[92m'
-        colors[ 'yellow' ] = '\033[93m'
-        colors[ 'red' ] = '\033[91m'
-        colors[ 'end' ] = '\033[0m'
+        colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
+                   'blue': '\033[94m', 'green': '\033[92m',
+                   'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
         description = "Test Cleanup"
         main.log.report( description )
         main.case( description )
         main.step( "Killing tcpdumps" )
         main.Mininet2.stopTcpdump()
 
-        main.step( "Checking ONOS Logs for errors" )
-        for i in range( 7 ):
-            print colors[ 'purple' ] + "Checking logs for errors on " + \
-                "ONOS" + str( i + 1 ) + ":" + colors[ 'end' ]
-            print main.ONOSbench.checkLogs( ips[ i ] )
-
         main.step( "Copying MN pcap and ONOS log files to test station" )
         testname = main.TEST
         teststationUser = main.params[ 'TESTONUSER' ]
@@ -1856,14 +2247,15 @@
         # NOTE: must end in /
         dstDir = "~/packet_captures/"
         for f in logFiles:
-            for i in range( 7 ):
-                main.ONOSbench.handle.sendline( "scp sdn@" + ips[ i ] + ":" +
-                                                logFolder + f + " " +
+            for node in nodes:
+                main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
+                                                ":" + logFolder + f + " " +
                                                 teststationUser + "@" +
                                                 teststationIP + ":" +
                                                 dstDir + str( testname ) +
-                                                "-ONOS" + str( i + 1 ) + "-" +
-                                                f )
+                                                "-" + node.name + "-" + f )
+                main.ONOSbench.handle.expect( "\$" )
+
         # std*.log's
         # NOTE: must end in /
         logFolder = "/opt/onos/var/"
@@ -1871,44 +2263,61 @@
         # NOTE: must end in /
         dstDir = "~/packet_captures/"
         for f in logFiles:
-            for i in range( 7 ):
-                main.ONOSbench.handle.sendline( "scp sdn@" + ips[ i ] + ":" +
-                                                logFolder + f + " " +
+            for node in nodes:
+                main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
+                                                ":" + logFolder + f + " " +
                                                 teststationUser + "@" +
                                                 teststationIP + ":" +
                                                 dstDir + str( testname ) +
-                                                "-ONOS" + str( i + 1 ) + "-" +
-                                                f )
+                                                "-" + node.name + "-" + f )
+                main.ONOSbench.handle.expect( "\$" )
         # sleep so scp can finish
         time.sleep( 10 )
+
+        main.step( "Stopping Mininet" )
+        main.Mininet1.stopNet()
+
+        main.step( "Checking ONOS Logs for errors" )
+        for node in nodes:
+            print colors[ 'purple' ] + "Checking logs for errors on " + \
+                node.name + ":" + colors[ 'end' ]
+            print main.ONOSbench.checkLogs( node.ip_address )
+
         main.step( "Packing and rotating pcap archives" )
         os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
 
         # TODO: actually check something here
         utilities.assert_equals( expect=main.TRUE, actual=main.TRUE,
-                                onpass="Test cleanup successful",
-                                onfail="Test cleanup NOT successful" )
+                                 onpass="Test cleanup successful",
+                                 onfail="Test cleanup NOT successful" )
 
     def CASE14( self, main ):
         """
         start election app on all onos nodes
         """
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
+
         leaderResult = main.TRUE
         # install app on onos 1
         main.log.info( "Install leadership election app" )
         main.ONOScli1.featureInstall( "onos-app-election" )
+        leader = nodes[0].ip_address
         # wait for election
         # check for leader
-        leader = main.ONOScli1.electionTestLeader()
+        leader1 = main.ONOScli1.electionTestLeader()
         # verify leader is ONOS1
-        if leader == ONOS1Ip:
+        if leader1 == leader:
             # all is well
             pass
-        elif leader is None:
+        elif leader1 is None:
             # No leader elected
             main.log.report( "No leader was elected" )
             leaderResult = main.FALSE
-        elif leader == main.FALSE:
+        elif leader1 == main.FALSE:
             # error in  response
             # TODO: add check for "Command not found:" in the driver, this
             # means the app isn't loaded
@@ -1919,19 +2328,16 @@
             # error in  response
             main.log.report(
                 "Unexpected response from electionTestLeader function:'" +
-                str( leader ) +
-                "'" )
+                str( leader1 ) + "'" )
             leaderResult = main.FALSE
 
         # install on other nodes and check for leader.
-        # Should be onos1 and each app should show the same leader
-        for controller in range( 2, numControllers + 1 ):
-            # loop through ONOScli handlers
-            node = getattr( main, ( 'ONOScli' + str( controller ) ) )
-            node.featureInstall( "onos-app-election" )
-            leaderN = node.electionTestLeader()
+        # Leader should be ONOS1 and each app should show the same leader
+        for cli in CLIs[ 1: ]:
+            cli.featureInstall( "onos-app-election" )
+            leaderN = cli.electionTestLeader()
             # verify leader is ONOS1
-            if leaderN == ONOS1Ip:
+            if leaderN == leader:
                 # all is well
                 pass
             elif leaderN == main.FALSE:
@@ -1944,8 +2350,7 @@
                 leaderResult = main.FALSE
             elif leader != leaderN:
                 leaderResult = main.FALSE
-                main.log.report( "ONOS" + str( controller ) + " sees " +
-                                 str( leaderN ) +
+                main.log.report( cli.name + " sees " + str( leaderN ) +
                                  " as the leader of the election app. Leader" +
                                  " should be " +
                                  str( leader ) )
@@ -1963,6 +2368,12 @@
         """
         Check that Leadership Election is still functional
         """
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert CLIs, "CLIs not defined"
+        assert nodes, "nodes not defined"
+
         leaderResult = main.TRUE
         description = "Check that Leadership Election is still functional"
         main.log.report( description )
@@ -1971,28 +2382,20 @@
         leader = main.ONOScli1.electionTestLeader()
         # TODO: do some sanity checking on leader before using it
         withdrawResult = main.FALSE
-        if leader == ONOS1Ip:
-            oldLeader = getattr( main, "ONOScli1" )
-        elif leader == ONOS2Ip:
-            oldLeader = getattr( main, "ONOScli2" )
-        elif leader == ONOS3Ip:
-            oldLeader = getattr( main, "ONOScli3" )
-        elif leader == ONOS4Ip:
-            oldLeader = getattr( main, "ONOScli4" )
-        elif leader == ONOS5Ip:
-            oldLeader = getattr( main, "ONOScli5" )
-        elif leader == ONOS6Ip:
-            oldLeader = getattr( main, "ONOScli6" )
-        elif leader == ONOS7Ip:
-            oldLeader = getattr( main, "ONOScli7" )
-        elif leader is None or leader == main.FALSE:
+        if leader is None or leader == main.FALSE:
             main.log.report(
                 "Leader for the election app should be an ONOS node," +
-                "instead got '" +
-                str( leader ) +
-                "'" )
+                "instead got '" + str( leader ) + "'" )
             leaderResult = main.FALSE
-        withdrawResult = oldLeader.electionTestWithdraw()
+            oldLeader = None
+        for i in range( len( CLIs ) ):
+            if leader == nodes[ i ].ip_address:
+                oldLeader = CLIs[ i ]
+                break
+        else:
+            main.log.error( "Leader election, could not find current leader" )
+        if oldLeader:
+            withdrawResult = oldLeader.electionTestWithdraw()
         utilities.assert_equals(
             expect=main.TRUE,
             actual=withdrawResult,
@@ -2001,23 +2404,17 @@
 
         main.step( "Make sure new leader is elected" )
         leaderList = []
-        for controller in range( 1, numControllers + 1 ):
-            # loop through ONOScli handlers
-            node = getattr( main, ( 'ONOScli' + str( controller ) ) )
-            leaderList.append( node.electionTestLeader() )
-        for leaderN in leaderList:
+        for cli in CLIs:
+            leaderN = cli.electionTestLeader()
+            leaderList.append( leaderN )
             if leaderN == leader:
-                main.log.report(
-                    "ONOS" +
-                    str( controller ) +
-                    " still sees " +
-                    str( leader ) +
-                    " as leader after they withdrew" )
+                main.log.report(  cli.name + " still sees " + str( leader ) +
+                                  " as leader after they withdrew" )
                 leaderResult = main.FALSE
             elif leaderN == main.FALSE:
                 # error in  response
                 # TODO: add check for "Command not found:" in the driver, this
-                # means the app isn't loaded
+                #       means the app isn't loaded
                 main.log.report( "Something is wrong with " +
                                  "electionTestLeader function, " +
                                  "check the error logs" )
@@ -2034,6 +2431,7 @@
             for n in range( len( leaderList ) ):
                 main.log.report( "ONOS" + str( n + 1 ) + " response: " +
                                  str( leaderList[ n ] ) )
+        leaderResult = leaderResult and consistentLeader
         if leaderResult:
             main.log.report( "Leadership election tests passed( consistent " +
                              "view of leader across listeners and a new " +
@@ -2045,9 +2443,12 @@
             onpass="Leadership election passed",
             onfail="Something went wrong with Leadership election" )
 
-        main.step(
-            "Run for election on old leader( just so everyone is in the hat )" )
-        runResult = oldLeader.electionTestRun()
+        main.step( "Run for election on old leader( just so everyone " +
+                   "is in the hat )" )
+        if oldLeader:
+            runResult = oldLeader.electionTestRun()
+        else:
+            runResult = main.FALSE
         utilities.assert_equals(
             expect=main.TRUE,
             actual=runResult,
diff --git a/TestON/tests/HATestSanity/HATestSanity.topo b/TestON/tests/HATestSanity/HATestSanity.topo
index 9305025..0855d4e 100644
--- a/TestON/tests/HATestSanity/HATestSanity.topo
+++ b/TestON/tests/HATestSanity/HATestSanity.topo
@@ -7,7 +7,8 @@
             <password>onos_test</password>
             <type>OnosDriver</type>
             <connect_order>1</connect_order>
-            <COMPONENTS> </COMPONENTS>
+            <COMPONENTS>
+            </COMPONENTS>
         </ONOSbench>
 
         <ONOScli1>
diff --git a/TestON/tests/HATestSingleInstanceRestart/HATestSingleInstanceRestart.params b/TestON/tests/HATestSingleInstanceRestart/HATestSingleInstanceRestart.params
index 80de267..d3eb8dd 100644
--- a/TestON/tests/HATestSingleInstanceRestart/HATestSingleInstanceRestart.params
+++ b/TestON/tests/HATestSingleInstanceRestart/HATestSingleInstanceRestart.params
@@ -1,4 +1,21 @@
 <PARAMS>
+    #CASE1: Compile ONOS and push it to the test machines
+    #CASE2: Assign mastership to controllers
+    #CASE3: Assign intents
+    #CASE4: Ping across added host intents
+    #CASE5: Reading state of ONOS
+    #CASE6: The Failure case. Since this is the Sanity test, we do nothing.
+    #CASE7: Check state after control plane failure
+    #CASE8: Compare topo
+    #CASE9: Link s3-s28 down
+    #CASE10: Link s3-s28 up
+    #CASE11: Switch down
+    #CASE12: Switch up
+    #CASE13: Clean up
+    #CASE14: start election app on all onos nodes
+    #CASE15: Check that Leadership Election is still functional
+    #1,2,8,3,4,5,14,[6],8,3,7,4,15,9,8,4,10,8,4,11,8,4,12,8,4,13
+    #extra hosts test 1,2,8,11,8,12,8
     <testcases>1,2,8,3,4,5,14,[6],8,3,7,4,15,9,8,4,10,8,4,11,8,4,12,8,4,13</testcases>
     <ENV>
         <cellName>HA</cellName>
diff --git a/TestON/tests/HATestSingleInstanceRestart/HATestSingleInstanceRestart.py b/TestON/tests/HATestSingleInstanceRestart/HATestSingleInstanceRestart.py
index 44ce741..d6e3daf 100644
--- a/TestON/tests/HATestSingleInstanceRestart/HATestSingleInstanceRestart.py
+++ b/TestON/tests/HATestSingleInstanceRestart/HATestSingleInstanceRestart.py
@@ -31,21 +31,25 @@
         CASE1 is to compile ONOS and push it to the test machines
 
         Startup sequence:
-        git pull
-        mvn clean install
-        onos-package
         cell <name>
         onos-verify-cell
         NOTE: temporary - onos-remove-raft-logs
+        onos-uninstall
+        start mininet
+        git pull
+        mvn clean install
+        onos-package
         onos-install -f
         onos-wait-for-start
+        start cli sessions
+        start tcpdump
         """
         main.log.report( "ONOS Single node cluster restart " +
                          "HA test - initialization" )
         main.case( "Setting up test environment" )
         # TODO: save all the timers and output them for plotting
 
-        # load some vairables from the params file
+        # load some variables from the params file
         PULLCODE = False
         if main.params[ 'Git' ] == 'True':
             PULLCODE = True
@@ -68,6 +72,7 @@
         global ONOS7Ip
         global ONOS7Port
         global numControllers
+        numControllers = int( main.params[ 'num_controllers' ] )
 
         ONOS1Ip = main.params[ 'CTRL' ][ 'ip1' ]
         ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
@@ -83,7 +88,6 @@
         ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
         ONOS7Ip = main.params[ 'CTRL' ][ 'ip7' ]
         ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
-        numControllers = int( main.params[ 'num_controllers' ] )
 
         main.step( "Applying cell variable to environment" )
         cellResult = main.ONOSbench.setCell( cellName )
@@ -109,8 +113,7 @@
 
         main.step( "Compiling the latest version of ONOS" )
         if PULLCODE:
-            # TODO Configure branch in params
-            main.step( "Git checkout and pull master" )
+            main.step( "Git checkout and pull " + gitBranch )
             main.ONOSbench.gitCheckout( gitBranch )
             gitPullResult = main.ONOSbench.gitPull()
 
@@ -131,7 +134,6 @@
                                                            node=ONOS1Ip )
 
         main.step( "Checking if ONOS is up yet" )
-        # TODO check bundle:list?
         for i in range( 2 ):
             onos1Isup = main.ONOSbench.isup( ONOS1Ip )
             if onos1Isup:
@@ -153,8 +155,8 @@
                         and onos1Isup and cliResult )
 
         utilities.assert_equals( expect=main.TRUE, actual=case1Result,
-                                onpass="Test startup successful",
-                                onfail="Test startup NOT successful" )
+                                 onpass="Test startup successful",
+                                 onfail="Test startup NOT successful" )
 
         if case1Result == main.FALSE:
             main.cleanup()
@@ -165,6 +167,16 @@
         Assign mastership to controllers
         """
         import re
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert ONOS1Port, "ONOS1Port not defined"
+        assert ONOS2Port, "ONOS2Port not defined"
+        assert ONOS3Port, "ONOS3Port not defined"
+        assert ONOS4Port, "ONOS4Port not defined"
+        assert ONOS5Port, "ONOS5Port not defined"
+        assert ONOS6Port, "ONOS6Port not defined"
+        assert ONOS7Port, "ONOS7Port not defined"
 
         main.log.report( "Assigning switches to controllers" )
         main.case( "Assigning Controllers" )
@@ -180,7 +192,7 @@
             response = main.Mininet1.getSwController( "s" + str( i ) )
             try:
                 main.log.info( str( response ) )
-            except:
+            except Exception:
                 main.log.info( repr( response ) )
             if re.search( "tcp:" + ONOS1Ip, response ):
                 mastershipCheck = mastershipCheck and main.TRUE
@@ -198,9 +210,13 @@
         """
         Assign intents
         """
+        import time
+        import json
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
         # FIXME: we must reinstall intents until we have a persistant
         # datastore!
-        import time
         main.log.report( "Adding host intents" )
         main.case( "Adding host Intents" )
 
@@ -213,15 +229,16 @@
 
         # REACTIVE FWD test
         pingResult = main.FALSE
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall()
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=pingResult,
-            onpass="Reactive Pingall test passed",
-            onfail="Reactive Pingall failed, one or more ping pairs failed" )
-        time2 = time.time()
-        main.log.info( "Time for pingall: %2f seconds" % ( time2 - time1 ) )
+        for i in range(2):  # Retry if pingall fails first time
+            time1 = time.time()
+            pingResult = main.Mininet1.pingall()
+            utilities.assert_equals(
+                expect=main.TRUE,
+                actual=pingResult,
+                onpass="Reactive Pingall test passed",
+                onfail="Reactive Pingall failed, one or more ping pairs failed" )
+            time2 = time.time()
+            main.log.info( "Time for pingall: %2f seconds" % ( time2 - time1 ) )
 
         # uninstall onos-app-fwd
         main.log.info( "Uninstall reactive forwarding app" )
@@ -230,8 +247,11 @@
         time.sleep( 10 )
 
         main.step( "Add  host intents" )
+        intentIds = []
         # TODO:  move the host numbers to params
+        #        Maybe look at all the paths we ping?
         intentAddResult = True
+        hostResult = main.TRUE
         for i in range( 8, 18 ):
             main.log.info( "Adding host intent between h" + str( i ) +
                            " and h" + str( i + 10 ) )
@@ -248,45 +268,224 @@
                 host1Id = host1Dict.get( 'id', None )
                 host2Id = host2Dict.get( 'id', None )
             if host1Id and host2Id:
-                tmpResult = main.ONOScli1.addHostIntent(
+                tmpId = main.ONOScli1.addHostIntent(
                     host1Id,
                     host2Id )
+                if tmpId:
+                    main.log.info( "Added intent with id: " + tmpId )
+                    intentIds.append( tmpId )
+                else:
+                    main.log.error( "addHostIntent reutrned None" )
             else:
                 main.log.error( "Error, getHost() failed" )
                 main.log.warn( json.dumps( json.loads( main.ONOScli1.hosts() ),
                                            sort_keys=True,
                                            indent=4,
                                            separators=( ',', ': ' ) ) )
-                tmpResult = main.FALSE
-            intentAddResult = bool( pingResult and intentAddResult
-                                     and tmpResult )
-            # TODO Check that intents were added?
+                hostResult = main.FALSE
+        onosIds = main.ONOScli1.getAllIntentsId()
+        main.log.info( "Submitted intents: " + str( intentIds ) )
+        main.log.info( "Intents in ONOS: " + str( onosIds ) )
+        for intent in intentIds:
+            if intent in onosIds:
+                pass  # intent submitted is still in onos
+            else:
+                intentAddResult = False
         # Print the intent states
-        intents = main.ONOScli1.intents( )
+        intents = main.ONOScli1.intents()
         intentStates = []
-        for intent in json.loads( intents ):  # Iter through intents of a node
-            intentStates.append( intent.get( 'state', None ) )
-        out = [ (i, intentStates.count( i ) ) for i in set( intentStates ) ]
-        main.log.info( dict( out ) )
+        installedCheck = True 
+        main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
+        count = 0
+        try:
+            for intent in json.loads( intents ):
+                state = intent.get( 'state', None )
+                if "INSTALLED" not in state:
+                    installedCheck = False
+                intentId = intent.get( 'id', None )
+                intentStates.append( ( intentId, state ) )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing intents" )
+        # add submitted intents not in the store
+        tmplist = [ i for i, s in intentStates ]
+        missingIntents = False
+        for i in intentIds:
+            if i not in tmplist:
+                intentStates.append( ( i, " - " ) )
+                missingIntents = True
+        intentStates.sort()
+        for i, s in intentStates:
+            count += 1
+            main.log.info( "%-6s%-15s%-15s" %
+                           ( str( count ), str( i ), str( s ) ) )
+        leaders = main.ONOScli1.leaders()
+        try:
+            if leaders:
+                parsedLeaders = json.loads( leaders )
+                main.log.warn( json.dumps( parsedLeaders,
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+                # check for all intent partitions
+                # check for election
+                topics = []
+                for i in range( 14 ):
+                    topics.append( "intent-partition-" + str( i ) )
+                # FIXME: this should only be after we start the app
+                topics.append( "org.onosproject.election" )
+                main.log.debug( topics )
+                ONOStopics = [ j['topic'] for j in parsedLeaders ]
+                for topic in topics:
+                    if topic not in ONOStopics:
+                        main.log.error( "Error: " + topic +
+                                        " not in leaders" )
+            else:
+                main.log.error( "leaders() returned None" )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing leaders" )
+            main.log.error( repr( leaders ) )
+        partitions = main.ONOScli1.partitions()
+        try:
+            if partitions :
+                parsedPartitions = json.loads( partitions )
+                main.log.warn( json.dumps( parsedPartitions,
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+                # TODO check for a leader in all paritions
+                # TODO check for consistency among nodes
+            else:
+                main.log.error( "partitions() returned None" )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing partitions" )
+            main.log.error( repr( partitions ) )
+        pendingMap = main.ONOScli1.pendingMap()
+        try:
+            if pendingMap :
+                parsedPending = json.loads( pendingMap )
+                main.log.warn( json.dumps( parsedPending,
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+                # TODO check something here?
+            else:
+                main.log.error( "pendingMap() returned None" )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing pending map" )
+            main.log.error( repr( pendingMap ) )
 
+        intentAddResult = bool( pingResult and hostResult and intentAddResult
+                                and not missingIntents and installedCheck )
         utilities.assert_equals(
             expect=True,
             actual=intentAddResult,
             onpass="Pushed host intents to ONOS",
             onfail="Error in pushing host intents to ONOS" )
-        # TODO Check if intents all exist in datastore
+
+        if not intentAddResult or "key" in pendingMap:
+            import time
+            installedCheck = True
+            main.log.info( "Sleeping 60 seconds to see if intents are found" )
+            time.sleep( 60 )
+            onosIds = main.ONOScli1.getAllIntentsId()
+            main.log.info( "Submitted intents: " + str( intentIds ) )
+            main.log.info( "Intents in ONOS: " + str( onosIds ) )
+            # Print the intent states
+            intents = main.ONOScli1.intents()
+            intentStates = []
+            main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
+            count = 0
+            try:
+                for intent in json.loads( intents ):
+                    # Iter through intents of a node
+                    state = intent.get( 'state', None )
+                    if "INSTALLED" not in state:
+                        installedCheck = False
+                    intentId = intent.get( 'id', None )
+                    intentStates.append( ( intentId, state ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing intents" )
+            # add submitted intents not in the store
+            tmplist = [ i for i, s in intentStates ]
+            for i in intentIds:
+                if i not in tmplist:
+                    intentStates.append( ( i, " - " ) )
+            intentStates.sort()
+            for i, s in intentStates:
+                count += 1
+                main.log.info( "%-6s%-15s%-15s" %
+                               ( str( count ), str( i ), str( s ) ) )
+            leaders = main.ONOScli1.leaders()
+            try:
+                if leaders:
+                    parsedLeaders = json.loads( leaders )
+                    main.log.warn( json.dumps( parsedLeaders,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # check for all intent partitions
+                    # check for election
+                    topics = []
+                    for i in range( 14 ):
+                        topics.append( "intent-partition-" + str( i ) )
+                    # FIXME: this should only be after we start the app
+                    topics.append( "org.onosproject.election" )
+                    main.log.debug( topics )
+                    ONOStopics = [ j['topic'] for j in parsedLeaders ]
+                    for topic in topics:
+                        if topic not in ONOStopics:
+                            main.log.error( "Error: " + topic +
+                                            " not in leaders" )
+                else:
+                    main.log.error( "leaders() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing leaders" )
+                main.log.error( repr( leaders ) )
+            partitions = main.ONOScli1.partitions()
+            try:
+                if partitions :
+                    parsedPartitions = json.loads( partitions )
+                    main.log.warn( json.dumps( parsedPartitions,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check for a leader in all paritions
+                    # TODO check for consistency among nodes
+                else:
+                    main.log.error( "partitions() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing partitions" )
+                main.log.error( repr( partitions ) )
+            pendingMap = main.ONOScli1.pendingMap()
+            try:
+                if pendingMap :
+                    parsedPending = json.loads( pendingMap )
+                    main.log.warn( json.dumps( parsedPending,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check something here?
+                else:
+                    main.log.error( "pendingMap() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing pending map" )
+                main.log.error( repr( pendingMap ) )
 
     def CASE4( self, main ):
         """
         Ping across added host intents
         """
+        import json
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
         description = " Ping across added host intents"
         main.log.report( description )
         main.case( description )
         PingResult = main.TRUE
         for i in range( 8, 18 ):
-            ping = main.Mininet1.pingHost(
-                src="h" + str( i ), target="h" + str( i + 10 ) )
+            ping = main.Mininet1.pingHost( src="h" + str( i ),
+                                           target="h" + str( i + 10 ) )
             PingResult = PingResult and ping
             if ping == main.FALSE:
                 main.log.warn( "Ping failed between h" + str( i ) +
@@ -297,12 +496,16 @@
         if PingResult == main.FALSE:
             main.log.report(
                 "Intents have not been installed correctly, pings failed." )
-            #TODO: pretty print
-            main.log.warn( "ONSO1 intents: " )
-            main.log.warn( json.dumps( json.loads( main.ONOScli1.intents() ),
-                                       sort_keys=True,
-                                       indent=4,
-                                       separators=( ',', ': ' ) ) )
+            # TODO: pretty print
+            main.log.warn( "ONOS1 intents: " )
+            try:
+                tmpIntents = main.ONOScli1.intents()
+                main.log.warn( json.dumps( json.loads( tmpIntents ),
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+            except ( ValueError, TypeError ):
+                main.log.warn( repr( tmpIntents ) )
         if PingResult == main.TRUE:
             main.log.report(
                 "Intents have been installed correctly and verified by pings" )
@@ -312,11 +515,173 @@
             onpass="Intents have been installed correctly and pings work",
             onfail="Intents have not been installed correctly, pings failed." )
 
+        installedCheck = True
+        if PingResult is not main.TRUE:
+            # Print the intent states
+            intents = main.ONOScli1.intents()
+            intentStates = []
+            main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
+            count = 0
+            # Iter through intents of a node
+            try:
+                for intent in json.loads( intents ):
+                    state = intent.get( 'state', None )
+                    if "INSTALLED" not in state:
+                        installedCheck = False
+                    intentId = intent.get( 'id', None )
+                    intentStates.append( ( intentId, state ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing intents." )
+            intentStates.sort()
+            for i, s in intentStates:
+                count += 1
+                main.log.info( "%-6s%-15s%-15s" %
+                               ( str( count ), str( i ), str( s ) ) )
+            leaders = main.ONOScli1.leaders()
+            try:
+                if leaders:
+                    parsedLeaders = json.loads( leaders )
+                    main.log.warn( json.dumps( parsedLeaders,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # check for all intent partitions
+                    # check for election
+                    topics = []
+                    for i in range( 14 ):
+                        topics.append( "intent-partition-" + str( i ) )
+                    # FIXME: this should only be after we start the app
+                    topics.append( "org.onosproject.election" )
+                    main.log.debug( topics )
+                    ONOStopics = [ j['topic'] for j in parsedLeaders ]
+                    for topic in topics:
+                        if topic not in ONOStopics:
+                            main.log.error( "Error: " + topic +
+                                            " not in leaders" )
+                else:
+                    main.log.error( "leaders() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing leaders" )
+                main.log.error( repr( leaders ) )
+            partitions = main.ONOScli1.partitions()
+            try:
+                if partitions :
+                    parsedPartitions = json.loads( partitions )
+                    main.log.warn( json.dumps( parsedPartitions,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check for a leader in all paritions
+                    # TODO check for consistency among nodes
+                else:
+                    main.log.error( "partitions() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing partitions" )
+                main.log.error( repr( partitions ) )
+            pendingMap = main.ONOScli1.pendingMap()
+            try:
+                if pendingMap :
+                    parsedPending = json.loads( pendingMap )
+                    main.log.warn( json.dumps( parsedPending,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check something here?
+                else:
+                    main.log.error( "pendingMap() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing pending map" )
+                main.log.error( repr( pendingMap ) )
+
+        if not installedCheck:
+            main.log.info( "Waiting 60 seconds to see if the state of " +
+                           "intents change" )
+            time.sleep( 60 )
+            # Print the intent states
+            intents = main.ONOScli1.intents()
+            intentStates = []
+            main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
+            count = 0
+            # Iter through intents of a node
+            try:
+                for intent in json.loads( intents ):
+                    state = intent.get( 'state', None )
+                    if "INSTALLED" not in state:
+                        installedCheck = False
+                    intentId = intent.get( 'id', None )
+                    intentStates.append( ( intentId, state ) )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing intents." )
+            intentStates.sort()
+            for i, s in intentStates:
+                count += 1
+                main.log.info( "%-6s%-15s%-15s" %
+                               ( str( count ), str( i ), str( s ) ) )
+            leaders = main.ONOScli1.leaders()
+            try:
+                if leaders:
+                    parsedLeaders = json.loads( leaders )
+                    main.log.warn( json.dumps( parsedLeaders,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # check for all intent partitions
+                    # check for election
+                    topics = []
+                    for i in range( 14 ):
+                        topics.append( "intent-partition-" + str( i ) )
+                    # FIXME: this should only be after we start the app
+                    topics.append( "org.onosproject.election" )
+                    main.log.debug( topics )
+                    ONOStopics = [ j['topic'] for j in parsedLeaders ]
+                    for topic in topics:
+                        if topic not in ONOStopics:
+                            main.log.error( "Error: " + topic +
+                                            " not in leaders" )
+                else:
+                    main.log.error( "leaders() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing leaders" )
+                main.log.error( repr( leaders ) )
+            partitions = main.ONOScli1.partitions()
+            try:
+                if partitions :
+                    parsedPartitions = json.loads( partitions )
+                    main.log.warn( json.dumps( parsedPartitions,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check for a leader in all paritions
+                    # TODO check for consistency among nodes
+                else:
+                    main.log.error( "partitions() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing partitions" )
+                main.log.error( repr( partitions ) )
+            pendingMap = main.ONOScli1.pendingMap()
+            try:
+                if pendingMap :
+                    parsedPending = json.loads( pendingMap )
+                    main.log.warn( json.dumps( parsedPending,
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                    # TODO check something here?
+                else:
+                    main.log.error( "pendingMap() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing pending map" )
+                main.log.error( repr( pendingMap ) )
+
     def CASE5( self, main ):
         """
         Reading state of ONOS
         """
         import json
+        import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
         # assumes that sts is already in you PYTHONPATH
         from sts.topology.teston_topology import TestONTopology
 
@@ -324,7 +689,7 @@
         main.case( "Setting up and gathering data for current state" )
         # The general idea for this test case is to pull the state of
         # ( intents,flows, topology,... ) from each ONOS node
-        # We can then compare them with eachother and also with past states
+        # We can then compare them with each other and also with past states
 
         main.step( "Get the Mastership of each switch from each controller" )
         global mastershipState
@@ -364,10 +729,10 @@
         main.step( "Get the flows from each controller" )
         global flowState
         flowState = []
-        ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
         flowCheck = main.FALSE
+        ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
         if "Error" in ONOS1Flows or not ONOS1Flows:
-            main.log.report( "Error in getting ONOS intents" )
+            main.log.report( "Error in getting ONOS flows" )
             main.log.warn( "ONOS1 flows repsponse: " + ONOS1Flows )
         else:
             # TODO: Do a better check, maybe compare flows on switches?
@@ -379,7 +744,9 @@
         flows = []
         for i in range( 1, 29 ):
             flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
-
+        if flowCheck == main.FALSE:
+            for table in flows:
+                main.log.warn( table )
         # TODO: Compare switch flow tables with ONOS flow tables
 
         main.step( "Create TestONTopology object" )
@@ -399,84 +766,119 @@
         main.step( "Collecting topology information from ONOS" )
         devices = []
         devices.append( main.ONOScli1.devices() )
-        """
         hosts = []
-        hosts.append( main.ONOScli1.hosts() )
-        """
+        hosts.append( json.loads( main.ONOScli1.hosts() ) )
         ports = []
         ports.append( main.ONOScli1.ports() )
         links = []
         links.append( main.ONOScli1.links() )
+        clusters = []
+        clusters.append( main.ONOScli1.clusters() )
+        ipResult = main.TRUE
+        for controller in range( 0, len( hosts ) ):
+            controllerStr = str( controller + 1 )
+            for host in hosts[ controller ]:
+                if host is None or host.get( 'ips', [] ) == []:
+                    main.log.error(
+                        "DEBUG:Error with host ips on controller" +
+                        controllerStr + ": " + str( host ) )
+                    ipResult = main.FALSE
+
+        # there should always only be one cluster
+        numClusters = len( json.loads( clusters[ 0 ] ) )
+        clusterResults = main.FALSE
+        if numClusters == 1:
+            clusterResults = main.TRUE
+        utilities.assert_equals(
+            expect=1,
+            actual=numClusters,
+            onpass="ONOS shows 1 SCC",
+            onfail="ONOS shows " + str( numClusters ) + " SCCs" )
 
         main.step( "Comparing ONOS topology to MN" )
         devicesResults = main.TRUE
         portsResults = main.TRUE
         linksResults = main.TRUE
+        hostsResults = main.TRUE
         for controller in range( numControllers ):
             controllerStr = str( controller + 1 )
             if devices[ controller ] or "Error" not in devices[ controller ]:
                 currentDevicesResult = main.Mininet1.compareSwitches(
                     MNTopo,
-                    json.loads(
-                        devices[ controller ] ) )
+                    json.loads( devices[ 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" )
+                                     actual=currentDevicesResult,
+                                     onpass="ONOS" + controllerStr +
+                                     " Switches view is correct",
+                                     onfail="ONOS" + controllerStr +
+                                     " Switches view is incorrect" )
 
             if ports[ controller ] or "Error" not in ports[ controller ]:
                 currentPortsResult = main.Mininet1.comparePorts(
                     MNTopo,
-                    json.loads(
-                        ports[ controller ] ) )
+                    json.loads( ports[ controller ] ) )
             else:
                 currentPortsResult = main.FALSE
             utilities.assert_equals( expect=main.TRUE,
-                                    actual=currentPortsResult,
-                                    onpass="ONOS" + controllerStr +
-                                    " ports view is correct",
-                                    onfail="ONOS" + controllerStr +
-                                    " ports view is incorrect" )
+                                     actual=currentPortsResult,
+                                     onpass="ONOS" + controllerStr +
+                                     " ports view is correct",
+                                     onfail="ONOS" + controllerStr +
+                                     " ports view is incorrect" )
 
             if links[ controller ] or "Error" not in links[ controller ]:
                 currentLinksResult = main.Mininet1.compareLinks(
                     MNTopo,
-                    json.loads(
-                        links[ controller ] ) )
+                    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" )
+                                     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(
+                    MNTopo, 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" )
 
             devicesResults = devicesResults and currentDevicesResult
             portsResults = portsResults and currentPortsResult
             linksResults = linksResults and currentLinksResult
+            hostsResults = hostsResults and currentHostsResult
 
-        topoResult = devicesResults and portsResults and linksResults
+        topoResult = devicesResults and portsResults and linksResults\
+                     and clusterResults and ipResult and hostsResults
         utilities.assert_equals( expect=main.TRUE, actual=topoResult,
-                                onpass="Topology Check Test successful",
-                                onfail="Topology Check Test NOT successful" )
+                                 onpass="Topology Check Test successful",
+                                 onfail="Topology Check Test NOT successful" )
 
         finalAssert = main.TRUE
         finalAssert = finalAssert and topoResult and flowCheck \
-            and intentCheck and consistentMastership and rolesNotNull
+                      and intentCheck and consistentMastership and rolesNotNull
         utilities.assert_equals( expect=main.TRUE, actual=finalAssert,
-                                onpass="State check successful",
-                                onfail="State check NOT successful" )
+                                 onpass="State check successful",
+                                 onfail="State check NOT successful" )
 
     def CASE6( self, main ):
         """
         The Failure case.
         """
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
 
         main.log.report( "Restart ONOS node" )
         main.log.case( "Restart ONOS node" )
@@ -497,11 +899,11 @@
 
         caseResults = main.TRUE and onos1Isup and cliResult
         utilities.assert_equals( expect=main.TRUE, actual=caseResults,
-                                onpass="ONOS restart successful",
-                                onfail="ONOS restart NOT successful" )
-        main.log.info(
-            "ESTIMATE: ONOS took %s seconds to restart" %
-            str( elapsed ) )
+                                 onpass="ONOS restart successful",
+                                 onfail="ONOS restart NOT successful" )
+        if elapsed:
+            main.log.info( "ESTIMATE: ONOS took %s seconds to restart" %
+                           str( elapsed ) )
         time.sleep( 5 )
 
     def CASE7( self, main ):
@@ -509,6 +911,9 @@
         Check state after ONOS failure
         """
         import json
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
         main.case( "Running ONOS Constant State Tests" )
 
         # Assert that each device has a master
@@ -524,9 +929,8 @@
         # FIXME: Refactor this whole case for single instance
         if "Error" in ONOS1Mastership or not ONOS1Mastership:
             main.log.report( "Error in getting ONOS mastership" )
-            main.log.warn(
-                "ONOS1 mastership response: " +
-                repr( ONOS1Mastership ) )
+            main.log.warn( "ONOS1 mastership response: " +
+                           repr( ONOS1Mastership ) )
             consistentMastership = main.FALSE
         else:
             consistentMastership = main.TRUE
@@ -546,9 +950,7 @@
         mastershipCheck = main.TRUE
         for i in range( 1, 29 ):
             switchDPID = str(
-                main.Mininet1.getSwitchDPID(
-                    switch="s" +
-                    str( i ) ) )
+                main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
 
             current = [ switch[ 'master' ] for switch in currentJson
                         if switchDPID in switch[ 'id' ] ]
@@ -588,15 +990,15 @@
         intentStates = []
         for node in intents:  # Iter through ONOS nodes
             nodeStates = []
-            for intent in json.loads( node ):  # Iter through intents of a node
+            # Iter through intents of a node
+            for intent in json.loads( node ):
                 nodeStates.append( intent[ 'state' ] )
             intentStates.append( nodeStates )
             out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
             main.log.info( dict( out ) )
 
-
-        # NOTE: Hazelcast has no durability, so intents are lost across system
-        # restarts
+        # NOTE: Store has no durability, so intents are lost across system
+        #       restarts
         """
         main.step( "Compare current intents with intents before the failure" )
         # NOTE: this requires case 5 to pass for intentState to be set.
@@ -613,7 +1015,7 @@
                 print json.dumps( json.loads( ONOS1Intents ),
                                   sort_keys=True, indent=4,
                                   separators=( ',', ': ' ) )
-            except:
+            except Exception:
                 pass
             sameIntents = main.FALSE
         utilities.assert_equals(
@@ -668,10 +1070,10 @@
                 leaderResult = main.FALSE
             elif leader != leaderN:
                 leaderResult = main.FALSE
-                main.log.report( "ONOS" + str( controller ) +
-                                 " sees " + str( leaderN ) +
-                                 " as the leader of the election app." +
-                                 " Leader should be " + str( leader ) )
+                main.log.report( "ONOS" + str( controller ) + " sees " +
+                                 str( leaderN ) +
+                                 " as the leader of the election app. " +
+                                 "Leader should be " + str( leader ) )
         if leaderResult:
             main.log.report( "Leadership election tests passed( consistent " +
                              "view of leader across listeners and a new " +
@@ -688,8 +1090,8 @@
         if result == main.TRUE:
             main.log.report( "Constant State Tests Passed" )
         utilities.assert_equals( expect=main.TRUE, actual=result,
-                                onpass="Constant State Tests Passed",
-                                onfail="Constant state tests failed" )
+                                 onpass="Constant State Tests Passed",
+                                 onfail="Constant state tests failed" )
 
     def CASE8( self, main ):
         """
@@ -702,6 +1104,9 @@
         from sts.topology.teston_topology import TestONTopology
         import json
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
 
         description = "Compare ONOS Topology view to Mininet topology"
         main.case( description )
@@ -724,28 +1129,39 @@
         devicesResults = main.TRUE
         portsResults = main.TRUE
         linksResults = main.TRUE
+        hostsResults = main.TRUE
         topoResult = main.FALSE
         elapsed = 0
         count = 0
         main.step( "Collecting topology information from ONOS" )
         startTime = time.time()
+        # Give time for Gossip to work
         while topoResult == main.FALSE and elapsed < 60:
             count = count + 1
             if count > 1:
-                MNTopo = TestONTopology(
-                    main.Mininet1,
-                    ctrls )
+                # TODO: Depricate STS usage
+                MNTopo = TestONTopology( main.Mininet1, ctrls )
             cliStart = time.time()
             devices = []
             devices.append( main.ONOScli1.devices() )
-            """
             hosts = []
-            hosts.append( main.ONOScli1.hosts() )
-            """
+            hosts.append( json.loads( main.ONOScli1.hosts() ) )
+            ipResult = main.TRUE
+            for controller in range( 0, len( hosts ) ):
+                controllerStr = str( controller + 1 )
+                for host in hosts[ controller ]:
+                    if host is None or host.get( 'ips', [] ) == []:
+                        main.log.error(
+                            "DEBUG:Error with host ips on controller" +
+                            controllerStr + ": " + str( host ) )
+                        ipResult = main.FALSE
             ports = []
             ports.append( main.ONOScli1.ports() )
             links = []
             links.append( main.ONOScli1.links() )
+            clusters = []
+            clusters.append( main.ONOScli1.clusters() )
+
             elapsed = time.time() - startTime
             cliTime = time.time() - cliStart
             print "CLI time: " + str( cliTime )
@@ -756,48 +1172,73 @@
                         controller ]:
                     currentDevicesResult = main.Mininet1.compareSwitches(
                         MNTopo,
-                        json.loads(
-                            devices[ controller ] ) )
+                        json.loads( devices[ 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" )
+                                         actual=currentDevicesResult,
+                                         onpass="ONOS" + controllerStr +
+                                         " Switches view is correct",
+                                         onfail="ONOS" + controllerStr +
+                                         " Switches view is incorrect" )
 
                 if ports[ controller ] or "Error" not in ports[ controller ]:
                     currentPortsResult = main.Mininet1.comparePorts(
                         MNTopo,
-                        json.loads(
-                            ports[ controller ] ) )
+                        json.loads( ports[ controller ] ) )
                 else:
                     currentPortsResult = main.FALSE
                 utilities.assert_equals( expect=main.TRUE,
-                                        actual=currentPortsResult,
-                                        onpass="ONOS" + controllerStr +
-                                        " ports view is correct",
-                                        onfail="ONOS" + controllerStr +
-                                        " ports view is incorrect" )
+                                         actual=currentPortsResult,
+                                         onpass="ONOS" + controllerStr +
+                                         " ports view is correct",
+                                         onfail="ONOS" + controllerStr +
+                                         " ports view is incorrect" )
 
                 if links[ controller ] or "Error" not in links[ controller ]:
                     currentLinksResult = main.Mininet1.compareLinks(
                         MNTopo,
-                        json.loads(
-                            links[ controller ] ) )
+                        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" )
-            devicesResults = devicesResults and currentDevicesResult
-            portsResults = portsResults and currentPortsResult
-            linksResults = linksResults and currentLinksResult
-            topoResult = devicesResults and portsResults and linksResults
+                                         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(
+                        MNTopo, 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" )
+
+                devicesResults = devicesResults and currentDevicesResult
+                portsResults = portsResults and currentPortsResult
+                linksResults = linksResults and currentLinksResult
+                hostsResults = hostsResults and currentHostsResult
+
+                # "consistent" results don't make sense for single instance
+            # there should always only be one cluster
+            numClusters = len( json.loads( clusters[ 0 ] ) )
+            clusterResults = main.FALSE
+            if numClusters == 1:
+                clusterResults = main.TRUE
+            utilities.assert_equals(
+                expect=1,
+                actual=numClusters,
+                onpass="ONOS shows 1 SCC",
+                onfail="ONOS shows " + str( numClusters ) + " SCCs" )
+
+            topoResult = ( devicesResults and portsResults and linksResults
+                           and hostsResults and ipResult and clusterResults )
 
         topoResult = topoResult and int( count <= 2 )
         note = "note it takes about " + str( int( cliTime ) ) + \
@@ -807,11 +1248,9 @@
             "Very crass estimate for topology discovery/convergence( " +
             str( note ) + " ): " + str( elapsed ) + " seconds, " +
             str( count ) + " tries" )
-        if elapsed > 60:
-            main.log.report( "Giving up on topology convergence" )
         utilities.assert_equals( expect=main.TRUE, actual=topoResult,
-                                onpass="Topology Check Test successful",
-                                onfail="Topology Check Test NOT successful" )
+                                 onpass="Topology Check Test successful",
+                                 onfail="Topology Check Test NOT successful" )
         if topoResult == main.TRUE:
             main.log.report( "ONOS topology view matches Mininet topology" )
 
@@ -820,25 +1259,26 @@
         Link s3-s28 down
         """
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
         # NOTE: You should probably run a topology check after this
 
         linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
 
         description = "Turn off a link to ensure that Link Discovery " +\
-            "is working properly"
+                      "is working properly"
         main.log.report( description )
         main.case( description )
 
         main.step( "Kill Link between s3 and s28" )
         LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
-        main.log.info(
-            "Waiting " +
-            str( linkSleep ) +
-            " seconds for link down to be discovered" )
+        main.log.info( "Waiting " + str( linkSleep ) +
+                       " seconds for link down to be discovered" )
         time.sleep( linkSleep )
         utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
-                                onpass="Link down succesful",
-                                onfail="Failed to bring link down" )
+                                 onpass="Link down succesful",
+                                 onfail="Failed to bring link down" )
         # TODO do some sort of check here
 
     def CASE10( self, main ):
@@ -846,25 +1286,26 @@
         Link s3-s28 up
         """
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
         # NOTE: You should probably run a topology check after this
 
         linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
 
         description = "Restore a link to ensure that Link Discovery is " + \
-            "working properly"
+                      "working properly"
         main.log.report( description )
         main.case( description )
 
         main.step( "Bring link between s3 and s28 back up" )
         LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
-        main.log.info(
-            "Waiting " +
-            str( linkSleep ) +
-            " seconds for link up to be discovered" )
+        main.log.info( "Waiting " + str( linkSleep ) +
+                       " seconds for link up to be discovered" )
         time.sleep( linkSleep )
         utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
-                                onpass="Link up succesful",
-                                onfail="Failed to bring link up" )
+                                 onpass="Link up succesful",
+                                 onfail="Failed to bring link up" )
         # TODO do some sort of check here
 
     def CASE11( self, main ):
@@ -873,6 +1314,9 @@
         """
         # NOTE: You should probably run a topology check after this
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
 
         switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
 
@@ -896,8 +1340,8 @@
         if device and device[ 'available' ] is False:
             result = main.TRUE
         utilities.assert_equals( expect=main.TRUE, actual=result,
-                                onpass="Kill switch succesful",
-                                onfail="Failed to kill switch?" )
+                                 onpass="Kill switch succesful",
+                                 onfail="Failed to kill switch?" )
 
     def CASE12( self, main ):
         """
@@ -905,6 +1349,16 @@
         """
         # NOTE: You should probably run a topology check after this
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert ONOS1Port, "ONOS1Port not defined"
+        assert ONOS2Port, "ONOS2Port not defined"
+        assert ONOS3Port, "ONOS3Port not defined"
+        assert ONOS4Port, "ONOS4Port not defined"
+        assert ONOS5Port, "ONOS5Port not defined"
+        assert ONOS6Port, "ONOS6Port not defined"
+        assert ONOS7Port, "ONOS7Port not defined"
 
         switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
         switch = main.params[ 'kill' ][ 'switch' ]
@@ -921,11 +1375,10 @@
         for peer in links:
             main.Mininet1.addLink( switch, peer )
         main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
-                                           ip1=ONOS1Ip, port1=ONOS1Port )
-        main.log.info(
-            "Waiting " +
-            str( switchSleep ) +
-            " seconds for switch up to be discovered" )
+                                          ip1=ONOS1Ip,
+                                          port1=ONOS1Port )
+        main.log.info( "Waiting " + str( switchSleep ) +
+                       " seconds for switch up to be discovered" )
         time.sleep( switchSleep )
         device = main.ONOScli1.getDevice( dpid=switchDPID )
         # Peek at the deleted switch
@@ -934,8 +1387,8 @@
         if device and device[ 'available' ]:
             result = main.TRUE
         utilities.assert_equals( expect=main.TRUE, actual=result,
-                                onpass="add switch succesful",
-                                onfail="Failed to add switch?" )
+                                 onpass="add switch succesful",
+                                 onfail="Failed to add switch?" )
 
     def CASE13( self, main ):
         """
@@ -943,6 +1396,9 @@
         """
         import os
         import time
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
         # printing colors to terminal
         colors = {}
         colors[ 'cyan' ] = '\033[96m'
@@ -962,6 +1418,7 @@
         print colors[ 'purple' ] + "Checking logs for errors on ONOS1:" + \
             colors[ 'end' ]
         print main.ONOSbench.checkLogs( ONOS1Ip )
+
         main.step( "Copying MN pcap and ONOS log files to test station" )
         testname = main.TEST
         teststationUser = main.params[ 'TESTONUSER' ]
@@ -983,7 +1440,6 @@
                                             teststationIP + ":" + dstDir +
                                             str( testname ) + "-ONOS1-" + f )
             main.ONOSbench.handle.expect( "\$" )
-            print main.ONOSbench.handle.before
 
         # std*.log's
         # NOTE: must end in /
@@ -997,20 +1453,25 @@
                                             teststationUser + "@" +
                                             teststationIP + ":" + dstDir +
                                             str( testname ) + "-ONOS1-" + f )
+            main.ONOSbench.handle.expect( "\$" )
         # sleep so scp can finish
         time.sleep( 10 )
+        main.Mininet1.stopNet()
         main.step( "Packing and rotating pcap archives" )
         os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
 
         # TODO: actually check something here
         utilities.assert_equals( expect=main.TRUE, actual=main.TRUE,
-                                onpass="Test cleanup successful",
-                                onfail="Test cleanup NOT successful" )
+                                 onpass="Test cleanup successful",
+                                 onfail="Test cleanup NOT successful" )
 
     def CASE14( self, main ):
         """
         start election app on all onos nodes
         """
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
         leaderResult = main.TRUE
         # install app on onos 1
         main.log.info( "Install leadership election app" )
@@ -1081,6 +1542,9 @@
         """
         Check that Leadership Election is still functional
         """
+        assert numControllers, "numControllers not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
         leaderResult = main.TRUE
         description = "Check that Leadership Election is still functional"
         main.log.report( description )
@@ -1094,11 +1558,13 @@
         elif leader is None or leader == main.FALSE:
             main.log.report(
                 "Leader for the election app should be an ONOS node," +
-                "instead got '" +
-                str( leader ) +
-                "'" )
+                "instead got '" + str( leader ) + "'" )
             leaderResult = main.FALSE
-        withdrawResult = oldLeader.electionTestWithdraw()
+            oldLeader = None
+        else:
+            main.log.error( "Leader election --- why am I HERE?!?")
+        if oldLeader:
+            withdrawResult = oldLeader.electionTestWithdraw()
         utilities.assert_equals(
             expect=main.TRUE,
             actual=withdrawResult,
@@ -1131,9 +1597,12 @@
             onpass="Leadership election passed",
             onfail="Something went wrong with Leadership election" )
 
-        main.step(
-            "Run for election on old leader( just so everyone is in the hat )" )
-        runResult = oldLeader.electionTestRun()
+        main.step( "Run for election on old leader( just so everyone " +
+                   "is in the hat )" )
+        if oldLeader:
+            runResult = oldLeader.electionTestRun()
+        else:
+            runResult = main.FALSE
         utilities.assert_equals(
             expect=main.TRUE,
             actual=runResult,
diff --git a/TestON/tests/IntentEventTP/IntentEventTP.params b/TestON/tests/IntentEventTP/IntentEventTP.params
new file mode 100644
index 0000000..d5dd65c
--- /dev/null
+++ b/TestON/tests/IntentEventTP/IntentEventTP.params
@@ -0,0 +1,66 @@
+<PARAMS>
+
+    <testcases>1,3,2,3,2,3,2,3</testcases>
+    
+    <debugMode></debugMode>  #nothing means false 
+
+    <ENV>
+    <cellName>intentTP</cellName>
+    <cellFeatures>"webconsole,onos-core,onos-api,onos-cli,onos-null,onos-gui,onos-rest,onos-app-metrics,onos-app-metrics-intent,onos-app-metrics-topology"</cellFeatures>
+    </ENV>
+
+    <SCALE>2</SCALE>
+    <availableNodes>7</availableNodes>
+
+    <GIT>
+        <autopull>off</autopull>
+        <checkout>master</checkout>
+    </GIT>
+
+    <CTRL> 
+        <USER>admin</USER>
+
+        <ip1>10.128.5.51</ip1>
+        <port1>6633</port1>
+
+        <ip2>10.128.5.52</ip2>
+        <port2>6633</port2>
+
+        <ip3>10.128.5.53</ip3>
+        <port3>6633</port3>
+
+        <ip4>10.128.5.54</ip4>
+        <port4>6633</port4>
+
+        <ip5>10.128.5.65</ip5>
+        <port5>6633</port5>
+
+        <ip6>10.128.5.66</ip6>
+        <port6>6633</port6>
+
+         <ip7>10.128.5.67</ip7>
+        <port7>6633</port7> 
+    </CTRL>
+
+    <MN><ip1>10.128.5.55</ip1></MN>
+
+    <BENCH>
+        <user>admin</user>
+        <ip1>10.128.5.55</ip1>
+    </BENCH>
+
+    <TEST> 
+        <loadFrom>1,0,0,0,0,0,0</loadFrom>                                     #generate load on server, 1 = generator on 
+        <numSwitches>35</numSwitches>
+        <skipCleanInstall>yes</skipCleanInstall>
+        <duration>60</duration>
+        <log_interval>5</log_interval>                            
+    </TEST>
+
+    <METRICS>
+        <intents_rate>intents-events-metrics|grep "Intent Installed Events"|cut -d ' ' -f7</intents_rate>
+        <intents_withdrawn>intents-events-metrics|grep "Intent Withdrawn Events"|cut -d ' ' -f7</intents_withdrawn>
+        <intents_failed>intents-events-metrics|grep "Intent Failed Events"|cut -d ' ' -f7</intents_failed>
+    </METRICS>
+
+</PARAMS>
diff --git a/TestON/tests/IntentEventTP/IntentEventTP.py b/TestON/tests/IntentEventTP/IntentEventTP.py
new file mode 100644
index 0000000..b1f0e91
--- /dev/null
+++ b/TestON/tests/IntentEventTP/IntentEventTP.py
@@ -0,0 +1,397 @@
+# ScaleOutTemplate --> IntentEventTP
+#
+# CASE1 starts number of nodes specified in param file
+#
+# cameron@onlab.us
+
+import sys
+import os
+import time
+
+
+class IntentEventTP:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):            #This is the initialization case
+        import os.path                  #this case will clean up all nodes 
+        import time                     #but only node 1 is started in this case
+        
+        global clusterCount             #number of nodes running
+        global ONOSIp                   #list of ONOS IP addresses 
+        clusterCount = 1
+        ONOSIp = [ 0 ]
+
+        #Load values from params file
+        checkoutBranch = main.params[ 'GIT' ][ 'checkout' ]
+        gitPull = main.params[ 'GIT' ][ 'autopull' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        Features= main.params[ 'ENV' ][ 'cellFeatures' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+        maxNodes = int(main.params[ 'availableNodes' ])
+        MNip = main.params[ 'MN' ][ 'ip1' ]
+        skipMvn = main.params[ 'TEST' ][ 'skipCleanInstall' ]
+        numSwitches = main.params[ 'TEST' ][ 'numSwitches' ]
+
+        homeDir = os.path.expanduser('~')
+        
+        main.ONOSbench.handle.sendline("export TERM=vt100")
+        dump = main.ONOSbench.handle.expect(":~")
+
+        #Populate ONOSIp with ips from params 
+        for i in range(1, maxNodes + 1): 
+            ipString = 'ip' + str(i) 
+            ONOSIp.append(main.params[ 'CTRL' ][ ipString ])   
+        
+        #kill off all onos processes
+        main.log.step("Safety check, killing all ONOS processes")
+        main.log.step("before initiating enviornment setup")
+        for node in range(1, maxNodes + 1):
+            main.log.info("killing node " + str(node))
+            main.ONOSbench.onosDie(ONOSIp[node])
+
+        #construct the cell file
+        main.log.info("Creating cell file")
+        exec "a = main.ONOSbench.createCellFile"
+        cellIp = []
+        for node in range (1, clusterCount + 1):
+            cellIp.append(ONOSIp[node])
+        a(BENCHIp,cellName,MNip,str(Features), *cellIp)   
+
+        main.step( "Set Cell" )
+        main.ONOSbench.setCell(cellName)
+
+        #Uninstall everywhere
+        main.log.step( "Cleaning Enviornment..." )
+        for i in range(1, maxNodes + 1):
+            main.log.info(" Uninstalling ONOS " + str(i) )
+            main.ONOSbench.onosUninstall( ONOSIp[i] )
+
+        #git 
+        main.step( "Git checkout and pull " + checkoutBranch )
+        if gitPull == 'on':
+            checkoutResult = main.ONOSbench.gitCheckout( checkoutBranch )
+            pullResult = main.ONOSbench.gitPull()
+        else:
+            checkoutResult = main.TRUE
+            pullResult = main.TRUE
+            main.log.info( "Skipped git checkout and pull" )
+        
+        #mvn clean install, for debugging set param 'skipCleanInstall' to yes to speed up test
+        if skipMvn != "yes":
+            mvnResult = main.ONOSbench.cleanInstall()
+ 
+        #configure null device provider         
+        switchList = [0,int(numSwitches),0,0,0,0,0,0]
+        devicesString  = ""
+        for node in range(1, maxNodes + 1):
+            devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
+            if node < maxNodes:
+                devicesString += (",")
+
+        main.log.info("Configuring device provider: ONOS 1 with " + (numSwitches) + " switches")
+        localPath = "/onos/tools/package/etc/org.onosproject.provider.nil.device.impl.NullDeviceProvider.cfg"
+        filePath = homeDir + localPath
+        main.log.info(filePath)
+
+        configFile = open(filePath, 'w+')
+        configFile.write("devConfigs = " + devicesString + "\n")
+        configFile.write("#numPorts = 8") 
+        configFile.close()
+        main.log.info("DevConfig = " + devicesString) 
+        main.log.info("Device provider file written and closed")
+
+        ## configuring null link provider
+        main.log.info(" Configuring null provider to disable flicker" )
+        homeDir = os.path.expanduser('~')
+        main.log.info(homeDir)
+        localPath = "/onos/tools/package/etc/org.onosproject.provider.nil.link.impl.NullLinkProvider.cfg"
+        filePath = homeDir + localPath
+        main.log.info(filePath)
+
+        neighborsString = ""
+        for node in range(1, maxNodes + 1):
+            neighborsString += ONOSIp[node]
+            if node < maxNodes:
+                neighborsString += ","
+
+        configFile = open(filePath, 'w+')
+        configFile.write("#eventRate =\n")
+        configFile.write("#cfgFile = /tmp/foo.cfg        #If enabled, points to the full path to the topology file.\n")
+        configFile.write("#neighbors = ")
+        configFile.close()
+        main.log.info("Configuration completed")
+        
+        main.log.info("Writing link graph configuration file..." )
+        homeDir = os.path.expanduser('~')
+        localPath = "/onos/tools/package/etc/linkGraph.cfg"
+        filePath = homeDir + localPath
+        linkGraph = open(filePath, 'w+')
+        linkGraph.write("# NullLinkProvider topology description (config file).\n")
+        linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
+        linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
+
+        myPort = 6
+        for node in range(1, clusterCount+1):
+            linkGraph.write("graph " + ONOSIp[node] + " {\n")
+            for switch in range (0, switchList[node]-1):
+                line = ""
+                line = ("\t" + str(switch) + ":" + str(myPort))
+                line += " -- "
+                line += (str(switch+1) + ":" + str(myPort-1) + "\n")
+                linkGraph.write(line) 
+            linkGraph.write("}")
+        linkGraph.close()        
+
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.onosPackage()  
+
+        main.step( "Installing ONOS package" )
+        install1Result = main.ONOSbench.onosInstall( node=ONOSIp[1] )
+
+        main.step( "verify cells" )
+        verifyCellResult = main.ONOSbench.verifyCell()
+
+        main.step( "Checking if ONOS is up yet" )
+        for i in range( 2 ):
+            isup = main.ONOSbench.isup( ONOSIp[1] )
+            if isup:
+                break
+        if not isup:
+            main.log.report( "ONOS1 didn't start!" )
+
+        lastOutput = "--" 
+        origin = time.time()
+        clockStarted = False 
+        while True:
+            main.ONOSbench.handle.sendline("onos $OC1 summary")
+            main.ONOSbench.handle.expect(":~")
+            clusterCheck = ((main.ONOSbench.handle.before).splitlines())[3]
+            print("\nBefore: " + str(clusterCheck))
+            if "SCC(s)=1," in clusterCheck and ("devices=" + str(numSwitches)) in clusterCheck:                  #check for links and devices too 
+                break 
+            if clusterCheck != lastOutput:
+                sameOutput = False 
+            elif clusterCheck == lastOutput:
+                if clockStarted == False: 
+                    start = time.time()
+                    clockStarted = True
+                if time.time() > (start + 30):
+                    main.log.error("TIMEOUT EXCEEDED: Clusters have not converged, continuing anyway...") 
+                    break 
+            lastOutput = clusterCheck
+            time.sleep(5)
+
+
+
+    def CASE2( self, main ):
+        # This case increases the cluster size by whatever scale is
+        # Note: 'scale' is the size of the step
+        # if scaling is not a part of your test, simply run this case
+        # once after CASE1 to set up your enviornment for your desired 
+        # cluster size. If scaling is a part of you test call this case each time 
+        # you want to increase cluster size
+
+        ''                                                         
+        'Increase number of nodes and initiate CLI'
+        ''
+        import time
+        import os.path
+        global clusterCount
+        
+        Features= main.params[ 'ENV' ][ 'cellFeatures' ] 
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        MNip = main.params[ 'MN' ][ 'ip1' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        numSwitches = int(main.params[ 'TEST' ][ 'numSwitches' ])
+        scale = int( main.params[ 'SCALE' ] )
+        maxNodes = int(main.params[ 'availableNodes' ])
+        clusterCount += scale
+        homeDir = os.path.expanduser('~')        
+
+        #kill off all onos processes
+        main.log.step("Safety check, killing all ONOS processes")
+        main.log.step("before initiating enviornment setup")
+        for node in range(1, maxNodes + 1):
+            main.ONOSbench.onosDie(ONOSIp[node]) 
+
+        #Uninstall everywhere
+        main.log.step( "Cleaning Enviornment..." )
+        for i in range(1, maxNodes + 1):
+            main.log.info(" Uninstalling ONOS " + str(i) )
+            main.ONOSbench.onosUninstall( ONOSIp[i] )      
+        
+        #construct the cell file
+        main.log.info("Creating cell file")
+        exec "a = main.ONOSbench.createCellFile"
+        cellIp = []
+        for node in range (1, clusterCount + 1):
+            cellIp.append(ONOSIp[node])
+        a(BENCHIp,cellName,MNip,str(Features), *cellIp)
+
+        main.step( "Set Cell" )
+        main.ONOSbench.setCell(cellName)
+
+        baselineSwitchCount = numSwitches/clusterCount
+        switchList = [0,0,0,0,0,0,0,0]
+        
+        for node in range(1, clusterCount + 1):
+            switchList[node] = baselineSwitchCount  
+            
+        for node in range(1, (numSwitches%clusterCount)+1):
+            switchList[node] += 1
+                      
+        devicesString  = ""
+        for node in range(1, maxNodes + 1):
+            devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
+            if node < maxNodes:
+                devicesString += (",")
+
+        main.log.info("Configuring device provider")
+        localPath = "/onos/tools/package/etc/org.onosproject.provider.nil.device.impl.NullDeviceProvider.cfg"
+        filePath = homeDir + localPath
+        main.log.info(filePath)
+
+        configFile = open(filePath, 'w+')
+        configFile.write("devConfigs = " + devicesString +"\n")
+        configFile.write("# numPorts = 8")
+        configFile.close()
+        main.log.info("DevConfig = " + devicesString)
+        main.log.info("Device provider file written and closed")
+
+        main.log.info("Writing link graph configuration file..." )
+        homeDir = os.path.expanduser('~')
+        localPath = "/onos/tools/package/etc/linkGraph.cfg"
+        filePath = homeDir + localPath
+        linkGraph = open(filePath, 'w+')
+        linkGraph.write("# NullLinkProvider topology description (config file).\n")
+        linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
+        linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
+
+        myPort = 6
+        for node in range(1, clusterCount+1):
+            linkGraph.write("graph " + ONOSIp[node] + " {\n")
+            for switch in range (0, switchList[node]-1):
+                line = ""
+                line = ("\t" + str(switch) + ":" + str(myPort))
+                line += " -- "
+                line += (str(switch+1) + ":" + str(myPort-1) + "\n")
+                linkGraph.write(line)
+            linkGraph.write("}\n")
+        linkGraph.close()
+
+        main.step( "Creating ONOS package, preparing to reinstall" )
+        packageResult = main.ONOSbench.onosPackage()   
+       
+        main.log.report( "Reinstalling on all nodes and increasing cluster size to " + str( clusterCount ) )
+        for node in range(1, clusterCount + 1):
+            main.log.info("Starting ONOS " + str(node) + " at IP: " + ONOSIp[node])    
+            main.ONOSbench.onosInstall( ONOSIp[node])
+    
+            for i in range( 2 ):
+                isup = main.ONOSbench.isup( ONOSIp[node] )
+                if isup:
+                    main.log.info("ONOS " + str(node) + " is up\n")
+                    break
+            if not isup:
+                main.log.report( "ONOS " + str(node) + " didn't start!" )
+        
+        lastOutput = "--"
+        origin = time.time()
+        clockStarted = False
+        while True:
+            main.ONOSbench.handle.sendline("onos $OC1 summary")
+            main.ONOSbench.handle.expect(":~")
+            clusterCheck = ((main.ONOSbench.handle.before).splitlines())[3]
+            print("\nBefore: " + str(clusterCheck))
+            if "SCC(s)=1," in clusterCheck and ("nodes=" + str(clusterCount)) in clusterCheck and ("devices=" + str(numSwitches)) in clusterCheck:  
+                break
+            if clusterCheck != lastOutput:
+                sameOutput = False
+            elif clusterCheck == lastOutput:
+                if clockStarted == False:
+                    start = time.time()
+                    clockStarted = True
+                if time.time() > (start + 60):
+                    main.log.error("TIMEOUT EXCEEDED: Clusters have not converged, continuing anyway...")
+                    break
+            lastOutput = clusterCheck
+            time.sleep(5)
+        
+            
+    def CASE3( self, main ):   
+        import time
+        import json
+        import string 
+        import csv
+
+        main.log.info("Cluster Count = " + str(clusterCount))
+
+        intentsRate = main.params['METRICS']['intents_rate']
+        intentsWithdrawn = main.params[ 'METRICS' ][ 'intents_withdrawn' ]
+        intentsFailed  = main.params[ 'METRICS' ][ 'intents_failed' ]
+        testDuration = main.params[ 'TEST' ][ 'duration' ]
+        logInterval = main.params[ 'TEST' ][ 'log_interval' ]
+        debug = main.params[ 'debugMode' ]
+
+        metricList = [intentsRate, intentsWithdrawn, intentsFailed]
+        
+        tempsleep =40
+        main.log.info("sleeping " + str(tempsleep)) 
+        time.sleep(tempsleep)
+        
+        loadFrom = ['0']
+        loadFrom.extend((main.params[ 'TEST' ][ 'loadFrom' ]).split(","))
+
+        for node in range(1, clusterCount+1):
+            if loadFrom[node] == "1": 
+                cmd = "onos $OC" + str(node) + " feature:install onos-app-intent-perf"
+                main.ONOSbench.handle.sendline(cmd)
+                main.ONOSbench.handle.expect(":~")
+                main.log.info("Load initiated on node " + str(node))
+       
+        main.log.info( "Starting test loop for " + str(testDuration) + " seconds...\n" )
+        stop = time.time() + float( testDuration )
+        
+        while time.time() < stop:
+            time.sleep( float( logInterval ) )
+            for node in range (1, clusterCount + 1):
+                myResults = ['0','0','0']
+                for metric in metricList: 
+
+                    onosEnv = "onos $OC" + str(node)  
+                    cmd = onosEnv + " " + metric
+                    main.log.info("COMMAND: " + cmd)
+                    main.ONOSbench.handle.sendline( cmd )
+                    time.sleep(10)
+                    main.ONOSbench.handle.expect(":~")                   
+                    rawResult = main.ONOSbench.handle.before
+                    rawResult = (rawResult.splitlines())
+
+                    tempResult = "--"
+                    for word in rawResult:
+                        if debug: print("word: " + word)
+                        if "m1" in str(word): 
+                            tempResult = word
+                            break
+
+                    if tempResult == "--": 
+                        main.log.error("WRONG pexepct.before data\n" + str(rawResult))
+                        main.log.info("retrying command... ")
+                        main.ONOSbench.handle.sendline(cmd)
+                        main.ONOSbench.handle.expect(":~")
+                        test = main.ONOSbench.handle.before
+                        print ("\n\n" + str(test))
+
+                    tempResult = round(float(tempResult.replace("m1=","")),1)
+                    tempResult = str(tempResult)                        # easy way to clean up number/prep to log
+                    resultIndex = metricList.index(metric)
+                    myResults[resultIndex] = tempResult
+                
+                main.log.info("\tNode " + str(node))
+                main.log.info("Installed\tWithdrawn\tFailed")
+                main.log.info(myResults[0] + "\t\t " + myResults[1] + "\t\t" + myResults[2] + "\n")
+                
+
diff --git a/TestON/tests/IntentEventTP/IntentEventTP.topo b/TestON/tests/IntentEventTP/IntentEventTP.topo
new file mode 100644
index 0000000..30a1467
--- /dev/null
+++ b/TestON/tests/IntentEventTP/IntentEventTP.topo
@@ -0,0 +1,146 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>10.128.5.55</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS><home>~/onos</home></COMPONENTS>
+        </ONOSbench>
+
+        <ONOS1cli>
+            <host>10.128.5.55</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1cli>
+
+        <ONOS2cli>
+            <host>10.128.5.55</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2cli>
+
+        <ONOS3cli>
+            <host>10.128.5.55</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3cli>
+
+        <ONOS4cli>
+            <host>10.128.5.55</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4cli>
+
+        <ONOS5cli>
+            <host>10.128.5.55</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5cli>
+
+        <ONOS6cli>
+            <host>10.128.5.55</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6cli>
+
+        <ONOS7cli>
+            <host>10.128.5.55</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>8</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS7cli>
+
+        <ONOS1>
+            <host>10.128.5.51</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>9</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1>
+
+        <ONOS2>
+            <host>10.128.5.52</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>10</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2>
+
+        <ONOS3>
+            <host>10.128.5.53</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>11</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3>
+
+        <ONOS4>
+            <host>10.128.5.54</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>12</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4>
+
+    
+        <ONOS5>
+            <host>10.128.5.65</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>13</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5>
+
+        <ONOS6>
+            <host>10.128.5.66</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>14</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6>
+
+        <ONOS7>
+            <host>10.128.5.67</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>15</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS7>
+
+    </COMPONENT>
+
+</TOPOLOGY>
+
+
+    
diff --git a/TestON/tests/IntentsLoad/__init__.py b/TestON/tests/IntentEventTP/__init__.py
similarity index 100%
rename from TestON/tests/IntentsLoad/__init__.py
rename to TestON/tests/IntentEventTP/__init__.py
diff --git a/TestON/tests/IntentPerfNext/IntentPerfNext.params b/TestON/tests/IntentPerfNext/IntentPerfNext.params
index 7b3f876..90ef160 100644
--- a/TestON/tests/IntentPerfNext/IntentPerfNext.params
+++ b/TestON/tests/IntentPerfNext/IntentPerfNext.params
@@ -49,7 +49,7 @@
 
     <DB>
         <intentFilePath>
-        /home/admin/ONLabTest/TestON/tests/IntentPerfNext/intentInstallPathDb.log
+        /home/admin/ONLabTest/TestON/tests/IntentPerfNext/intentLatencyResultDb.log
         </intentFilePath>
     </DB>
 
diff --git a/TestON/tests/IntentPerfNext/IntentPerfNext.py b/TestON/tests/IntentPerfNext/IntentPerfNext.py
index 422f1c9..cb226e7 100644
--- a/TestON/tests/IntentPerfNext/IntentPerfNext.py
+++ b/TestON/tests/IntentPerfNext/IntentPerfNext.py
@@ -375,6 +375,10 @@
         ONOS2Ip = main.params[ 'CTRL' ][ 'ip2' ]
         ONOS3Ip = main.params[ 'CTRL' ][ 'ip3' ]
         ONOSUser = main.params[ 'CTRL' ][ 'user' ]
+       
+        ONOSIpList = []
+        for i in range( 1, 8 ):
+            ONOSIpList.append( main.params[ 'CTRL' ][ 'ip' + str( i ) ] )
 
         defaultSwPort = main.params[ 'CTRL' ][ 'port1' ]
 
@@ -391,6 +395,51 @@
 
         # NOTE: May need to configure interface depending on topology
         intfs = main.params[ 'TEST' ][ 'intfs' ]
+        
+        # Distribute switches according to cluster count
+        for i in range( 1, 9 ):
+            if clusterCount == 1:
+                main.Mininet1.assignSwController(
+                    sw=str( i ), ip1=ONOSIpList[ 0 ],
+                    port1=defaultSwPort
+                )
+            elif clusterCount == 3:
+                if i < 3:
+                    index = 0
+                elif i < 6 and i >= 3:
+                    index = 1
+                else:
+                    index = 2
+                main.Mininet1.assignSwController(
+                    sw=str( i ), ip1=ONOSIpList[ index ],
+                    port1=defaultSwPort
+                )
+            elif clusterCount == 5:
+                if i < 3:
+                    index = 0
+                elif i < 5 and i >= 3:
+                    index = 1
+                elif i < 7 and i >= 5:
+                    index = 2
+                elif i == 7:
+                    index = 3
+                else:
+                    index = 4
+                main.Mininet1.assignSwController(
+                    sw=str( i ), ip1=ONOSIpList[ index ],
+                    port1=defaultSwPort
+                )
+            elif clusterCount == 7:
+                if i < 6:
+                    index = i
+                else:
+                    index = 6
+                main.Mininet1.assignSwController(
+                    sw=str( i ), ip1=ONOSIpList[ index ],
+                    port1=defaultSwPort
+                )
+
+        time.sleep(10)
 
         devicesJsonStr = main.ONOS1cli.devices()
         devicesJsonObj = json.loads( devicesJsonStr )
@@ -418,14 +467,15 @@
             intentsStr = main.ONOS1cli.intents( jsonFormat=True )
             intentsObj = json.loads( intentsStr )
             for intent in intentsObj:
+                main.log.info(intent)
                 if intent[ 'state' ] == "INSTALLED":
                     main.log.info( "Intent installed successfully" )
                     intentId = intent[ 'id' ]
                     main.log.info( "Intent id: " + str( intentId ) )
-                else:
-                    # TODO: Add error handling
-                    main.log.info( "Intent installation failed" )
-                    intentId = ""
+                #else:
+                    #TODO: Add error handling
+                    #main.log.info( "Intent installation failed" )
+                    #intentId = ""
 
             main.log.info( "Disabling interface " + intfs )
             t0System = time.time() * 1000
@@ -509,7 +559,7 @@
                   intentRerouteLat7 ) / clusterCount
 
             main.log.info( "Intent reroute latency avg for iteration " +
-                           str( i ) + ": " + str( intentRerouteLatAvg ) )
+                           str( i ) + ": " + str( intentRerouteLatAvg )+ " ms")
 
             if intentRerouteLatAvg > 0.0 and \
                intentRerouteLatAvg < 1000 and i > numIgnore:
@@ -690,6 +740,11 @@
             # Resets after each batch calculation
             maxInstallLat = []
             maxWithdrawLat = []
+            # Max single intent install measurement of all nodes
+            # For example, if batch size is 1000, result latency
+            # will be divided by 1000
+            maxSingleInstallLat = []
+            maxSingleWithdrawLat = []
             # Statistical gathering loop over number of iterations
             for i in range( 0, int( numIter ) ):
                 main.log.info( "Pushing " +
@@ -703,7 +758,7 @@
                         deviceIdList[ 7 ] + "/2",
                         batchIntentSize,
                         saveDir, ONOSIpList[ node - 1 ],
-                        numMult=nThread, appId=node )
+                        numMult=nThread )
 
                 # Wait sufficient time for intents to start
                 # installing
@@ -731,25 +786,36 @@
                     with open( saveDir ) as fOnos:
                         lineCount = 0
                         for line in fOnos:
-                            line = line[ 1: ]
-                            line = line.split( ": " )
+                            line_temp = ""
                             main.log.info( "Line read: " + str( line ) )
+                            line_temp = line[ 1: ]
+                            line_temp = line_temp.split( ": " )
                             #Prevent split method if line doesn't have
                             #space
-                            if " " in str(line):
-                                result = line[ 1 ].split( " " )[ 0 ]
+                            if " " in str(line_temp):
+                                result = line_temp[ 1 ].split( " " )[ 0 ]
                             else:
                                 main.log.warn( "Empty line read" )
                                 result = 0
                             # TODO: add parameters before appending latency
                             if lineCount == 0:
-                                batchInstallLat.append( int( result ) )
+                                if "Failure" in str(line):
+                                    main.log.warn("Intent installation failed")
+                                    result = 'NA' 
+                                else:
+                                    main.log.info("Install result: "+result)
+                                    batchInstallLat.append( int( result ) )
                                 installResult = result
                             elif lineCount == 1:
-                                batchWithdrawLat.append( int( result ) )
+                                if "Failure" in str(line):
+                                    main.log.warn("Intent withdraw failed")
+                                    result = 'NA'
+                                else:
+                                    main.log.info("Withdraw result: "+result)
+                                    batchWithdrawLat.append( int( result ) )
                                 withdrawResult = result
                             else:
-                                main.log.warn("Invalid results")
+                                main.log.warn("Invalid results: excess lines")
                                 installResult = 'NA'
                                 withdrawResult = 'NA'
                             lineCount += 1
@@ -762,16 +828,33 @@
                                    str( batchIntentSize ) + "intents: " +
                                    str( withdrawResult ) + " ms" )
 
+                    main.log.info( "Single intent install latency ONOS" +
+                                    str( node ) + " with " +
+                                    str( batchIntentSize ) + "intents: " +
+                                    str( float(installResult) /\
+                                         int(batchIntentSize) ) + " ms" )
+                    main.log.info( "Single intent withdraw latency ONOS" +
+                                    str( node ) + " with " +
+                                    str( batchIntentSize ) + "intents: " +
+                                    str( float(withdrawResult) /\
+                                         int(batchIntentSize) ) + " ms" )
+
                 #NOTE: END node loop
 
                 if len( batchInstallLat ) > 0 and int( i ) > numIgnore:
                     maxInstallLat.append( max( batchInstallLat ) )
+                    maxSingleInstallLat.append( 
+                            max( batchInstallLat ) / int( batchIntentSize ) 
+                    )
                 elif len( batchInstallLat ) == 0:
                     # If I failed to read anything from the file,
                     # increase the wait time before checking intents
                     sleepTime += 30
                 if len( batchWithdrawLat ) > 0 and int( i ) > numIgnore:
                     maxWithdrawLat.append( max( batchWithdrawLat ) )
+                    maxSingleWithdrawLat.append( 
+                            max( batchWithdrawLat ) / int( batchIntentSize ) 
+                    )
                 batchInstallLat = []
                 batchWithdrawLat = []
 
@@ -781,12 +864,16 @@
             #NOTE: END iteration loop
 
             if maxInstallLat:
-                avgInstallLat = str( round(
-                                            sum( maxInstallLat ) /
-                                            len( maxInstallLat )
+                avgInstallLat = str( round( numpy.average(maxInstallLat)
                                           , 2 ))
                 stdInstallLat = str( round(
                                     numpy.std(maxInstallLat), 2))
+                avgSingleInstallLat = str( round( 
+                                            numpy.average(maxSingleInstallLat)
+                                           , 3 ))
+                stdSingleInstallLat = str( round(
+                                            numpy.std(maxSingleInstallLat),
+                                            3 ))
             else:
                 avgInstallLat = "NA"
                 stdInstallLat = "NA"
@@ -794,12 +881,16 @@
                 assertion = main.FALSE
 
             if maxWithdrawLat:
-                avgWithdrawLat = str( round(
-                                            sum( maxWithdrawLat ) /
-                                            len( maxWithdrawLat )
+                avgWithdrawLat = str( round( numpy.average(maxWithdrawLat)
                                             , 2 ))
                 stdWithdrawLat = str( round(
                                     numpy.std(maxWithdrawLat), 2))
+                avgSingleWithdrawLat = str( round( 
+                                            numpy.average(maxSingleWithdrawLat)
+                                           , 3 ))
+                stdSingleWithdrawLat = str( round(
+                                            numpy.std(maxSingleWithdrawLat),
+                                            3 ))
             else:
                 avgWithdrawLat = "NA"
                 stdWithdrawLat = "NA"
@@ -812,6 +903,12 @@
             main.log.report( "Std Deviation of batch installation latency " +
                              ": " +
                              str( stdInstallLat ) + " ms" )
+            main.log.report( "Avg of single installation latency " +
+                             "of size " + str( batchIntentSize ) + ": " +
+                             str( avgSingleInstallLat ) + " ms" )
+            main.log.report( "Std Deviation of single installation latency " +
+                             ": " +
+                             str( stdSingleInstallLat ) + " ms" )
 
             main.log.report( "Avg of batch withdraw latency " +
                              "of size " + str( batchIntentSize ) + ": " +
@@ -819,10 +916,16 @@
             main.log.report( "Std Deviation of batch withdraw latency " +
                              ": " +
                              str( stdWithdrawLat ) + " ms" )
+            main.log.report( "Avg of single withdraw latency " +
+                             "of size " + str( batchIntentSize ) + ": " +
+                             str( avgSingleWithdrawLat ) + " ms" )
+            main.log.report( "Std Deviation of single withdraw latency " +
+                             ": " +
+                             str( stdSingleWithdrawLat ) + " ms" )
 
             dbCmd = (
-                "INSERT INTO intent_latency_tests VALUES("
-                "'"+timeToPost+"','intent_latency_results',"
+                "INSERT INTO intents_latency_tests VALUES("
+                "'"+timeToPost+"','intents_latency_results',"
                 ""+runNum+","+str(clusterCount)+","+str(batchIntentSize)+","
                 ""+str(avgInstallLat)+","+str(stdInstallLat)+","
                 ""+str(avgWithdrawLat)+","+str(stdWithdrawLat)+");"
diff --git a/TestON/tests/IntentsLoad/__init__.py b/TestON/tests/IntentPerfNext/__init__.py
similarity index 100%
copy from TestON/tests/IntentsLoad/__init__.py
copy to TestON/tests/IntentPerfNext/__init__.py
diff --git a/TestON/tests/IntentPerfNextBM/IntentPerfNextBM.params b/TestON/tests/IntentPerfNextBM/IntentPerfNextBM.params
new file mode 100644
index 0000000..194a783
--- /dev/null
+++ b/TestON/tests/IntentPerfNextBM/IntentPerfNextBM.params
@@ -0,0 +1,66 @@
+<PARAMS>
+    <testcases>1,2,3,4,2,3,4,2,3,4,2,3</testcases>
+
+    <ENV>
+        <cellName>intent_perf_test</cellName>
+    </ENV>
+
+    <GIT>
+        #autoPull 'on' or 'off'
+        <autoPull>off</autoPull>
+        <checkout>master</checkout>
+    </GIT>
+
+    <CTRL>
+        <user>sdn</user>
+        <ip1>10.254.1.201</ip1>
+        <port1>6633</port1>
+        <ip2>10.254.1.202</ip2>
+        <port2>6633</port2>
+        <ip3>10.254.1.203</ip3>
+        <port3>6633</port3>
+        <ip4>10.254.1.204</ip4>
+        <ip5>10.254.1.205</ip5>
+        <ip6>10.254.1.206</ip6>
+        <ip7>10.254.1.207</ip7>
+    </CTRL>
+
+    <TSHARK>
+        <ofpPortStatus>OF 1.3 146</ofpPortStatus>
+    </TSHARK>
+
+    <MN>
+        <ip1>10.254.1.200</ip1>
+        <ip2>10.254.1.200</ip2>
+    </MN>
+
+    <BENCH>
+        <ip>10.254.1.200</ip>
+    </BENCH>
+
+    <TEST>
+        #Number of times to iterate each case
+        <numIter>8</numIter>
+        <numIgnore>2</numIgnore>
+        <numSwitch>8</numSwitch>
+        <batchThresholdMin>0</batchThresholdMin>
+        <batchThresholdMax>1000</batchThresholdMax>
+        <batchIntentSize>1</batchIntentSize>
+        <numMult>1</numMult>
+        #Interface to bring down for intent reroute case
+        <intfs>s3-eth2</intfs>
+    </TEST>
+
+    <DB>
+        <intentFilePath>
+        /home/admin/ONLabTest/TestON/tests/IntentPerfNextBM/intentLatencyResultDb.log
+        </intentFilePath>
+    </DB>
+
+    <JSON>
+        <submittedTime>intentSubmittedTimestamp</submittedTime>
+        <installedTime>intentInstalledTimestamp</installedTime>
+        <wdRequestTime>intentWithdrawRequestedTimestamp</wdRequestTime>
+        <withdrawnTime>intentWithdrawnTimestamp</withdrawnTime>
+    </JSON>
+</PARAMS>
diff --git a/TestON/tests/IntentPerfNextBM/IntentPerfNextBM.py b/TestON/tests/IntentPerfNextBM/IntentPerfNextBM.py
new file mode 100644
index 0000000..8f23b29
--- /dev/null
+++ b/TestON/tests/IntentPerfNextBM/IntentPerfNextBM.py
@@ -0,0 +1,735 @@
+# 2015.03.12 10:28:21 PDT
+#Embedded file name: ../tests/IntentPerfNextBM/IntentPerfNextBM.py
+
+
+class IntentPerfNextBM:
+
+    def __init__(self):
+        self.default = ''
+
+    def CASE1(self, main):
+        """
+        ONOS startup sequence
+        """
+        global clusterCount
+        global timeToPost
+        global runNum
+        import time
+        
+        clusterCount = 1
+        timeToPost = time.strftime('%Y-%m-%d %H:%M:%S')
+        runNum = time.strftime('%d%H%M%S')
+        cellName = main.params['ENV']['cellName']
+        gitPull = main.params['GIT']['autoPull']
+        checkoutBranch = main.params['GIT']['checkout']
+        intentFilePath = main.params['DB']['intentFilePath']
+        ONOSIp = []
+        
+        for i in range(1, 8):
+            ONOSIp.append(main.params['CTRL']['ip' + str(i)])
+            main.ONOSbench.onosUninstall(nodeIp=ONOSIp[i - 1])
+
+        MN1Ip = main.params['MN']['ip1']
+        BENCHIp = main.params['BENCH']['ip']
+        main.case('Setting up test environment')
+        main.step('Clearing previous DB log file')
+        fIntentLog = open(intentFilePath, 'w')
+        fIntentLog.write('')
+        fIntentLog.close()
+        main.step('Starting mininet topology')
+        main.Mininet1.startNet()
+        main.step('Creating cell file')
+        cellFileResult = main.TRUE
+        main.step('Applying cell file to environment')
+        cellApplyResult = main.ONOSbench.setCell(cellName)
+        verifyCellResult = main.ONOSbench.verifyCell()
+        main.step('Removing raft logs')
+        main.ONOSbench.onosRemoveRaftLogs()
+        main.step('Git checkout and pull ' + checkoutBranch)
+        
+        if gitPull == 'on':
+            checkoutResult = main.ONOSbench.gitCheckout(checkoutBranch)
+            pullResult = main.ONOSbench.gitPull()
+            main.step('Using onos-build to compile ONOS')
+            buildResult = main.ONOSbench.onosBuild()
+        else:
+            checkoutResult = main.TRUE
+            pullResult = main.TRUE
+            buildResult = main.TRUE
+            main.log.info('Git pull skipped by configuration')
+        
+        main.log.report('Commit information - ')
+        main.ONOSbench.getVersion(report=True)
+        main.step('Creating ONOS package')
+        packageResult = main.ONOSbench.onosPackage()
+        main.step('Installing ONOS package')
+        install1Result = main.ONOSbench.onosInstall(node=ONOSIp[0])
+        main.step('Set cell for ONOScli env')
+        main.ONOS1cli.setCell(cellName)
+        time.sleep(5)
+        main.step('Start onos cli')
+        cli1 = main.ONOS1cli.startOnosCli(ONOSIp[0])
+        utilities.assert_equals(expect=main.TRUE, 
+                actual=cellFileResult and cellApplyResult and\
+                        verifyCellResult and checkoutResult and\
+                        pullResult and buildResult and install1Result, 
+                        onpass='ONOS started successfully',
+                        onfail='Failed to start ONOS')
+
+    def CASE2(self, main):
+        """
+        Batch intent install
+        
+        Supports scale-out scenarios and increasing
+        number of intents within each iteration
+        """
+        import time
+        import json
+        import requests
+        import os
+        import numpy
+        ONOS1Ip = main.params['CTRL']['ip1']
+        ONOS2Ip = main.params['CTRL']['ip2']
+        ONOS3Ip = main.params['CTRL']['ip3']
+        ONOS4Ip = main.params['CTRL']['ip4']
+        ONOS5Ip = main.params['CTRL']['ip5']
+        ONOS6Ip = main.params['CTRL']['ip6']
+        ONOS7Ip = main.params['CTRL']['ip7']
+        assertion = main.TRUE
+        ONOSIpList = []
+        
+        for i in range(1, 8):
+            ONOSIpList.append(main.params['CTRL']['ip' + str(i)])
+
+        ONOSUser = main.params['CTRL']['user']
+        defaultSwPort = main.params['CTRL']['port1']
+        batchIntentSize = int(main.params['TEST']['batchIntentSize'])
+        batchThreshMin = int(main.params['TEST']['batchThresholdMin'])
+        batchThreshMax = int(main.params['TEST']['batchThresholdMax'])
+        numIter = main.params['TEST']['numIter']
+        numIgnore = int(main.params['TEST']['numIgnore'])
+        numSwitch = int(main.params['TEST']['numSwitch'])
+        nThread = main.params['TEST']['numMult']
+        intentFilePath = main.params['DB']['intentFilePath']
+        
+        if clusterCount == 1:
+            for i in range(1, numSwitch + 1):
+                main.Mininet1.assignSwController(sw=str(i),
+                        ip1=ONOS1Ip, port1=defaultSwPort)
+        if clusterCount == 3:
+            for i in range(1, 3):
+                main.Mininet1.assignSwController(sw=str(i),
+                        ip1=ONOS1Ip, port1=defaultSwPort)
+            for i in range(3, 6):
+                main.Mininet1.assignSwController(sw=str(i),
+                        ip1=ONOS2Ip, port1=defaultSwPort)
+            for i in range(6, 9):
+                main.Mininet1.assignSwController(sw=str(i),
+                        ip1=ONOS3Ip, port1=defaultSwPort)
+        if clusterCount == 5:
+            main.Mininet1.assignSwController(sw='1',
+                    ip1=ONOS1Ip, port1=defaultSwPort)
+            main.Mininet1.assignSwController(sw='2',
+                    ip1=ONOS2Ip, port1=defaultSwPort)
+            for i in range(3, 6):
+                main.Mininet1.assignSwController(sw=str(i),
+                        ip1=ONOS3Ip, port1=defaultSwPort)
+            main.Mininet1.assignSwController(sw='6',
+                    ip1=ONOS4Ip, port1=defaultSwPort)
+            main.Mininet1.assignSwController(sw='7', 
+                    ip1=ONOS5Ip, port1=defaultSwPort)
+            main.Mininet1.assignSwController(sw='8',
+                    ip1=ONOS5Ip, port1=defaultSwPort)
+        if clusterCount == 7:
+            for i in range(1, 9):
+                if i < 8:
+                    main.Mininet1.assignSwController(sw=str(i),
+                            ip1=ONOSIpList[i - 1], port1=defaultSwPort)
+                elif i >= 8:
+                    main.Mininet1.assignSwController(sw=str(i),
+                            ip1=ONOSIpList[6], port1=defaultSwPort)
+
+        time.sleep(20)
+        
+        batchResultList = []
+        deviceIdList = []
+        batchInstallLat = []
+        batchWithdrawLat = []
+
+        main.log.report('Batch intent installation test of ' +
+                str(batchIntentSize) + ' intent(s)')
+        main.log.info('Getting list of available devices')
+        
+        jsonStr = main.ONOS1cli.devices()
+        jsonObj = json.loads(jsonStr)
+        for device in jsonObj:
+            deviceIdList.append(device['id'])
+
+        sleepTime = 10
+        baseDir = '/tmp/'
+        for batch in range(0, 5):
+            maxInstallLat = []
+            maxWithdrawLat = []
+            maxSingleInstallLat = []
+            maxSingleWithdrawLat = []
+            for i in range(0, int(numIter)):
+                main.log.info('Pushing ' + str(
+                    int(batchIntentSize) * int(nThread)) +
+                    ' intents. Iteration ' + str(i))
+                saveDir = baseDir + 'batch_intent_1.txt'
+                main.ONOSbench.pushTestIntentsShell(deviceIdList[0] +
+                        '/2', deviceIdList[7] + '/2', batchIntentSize,
+                        saveDir, ONOSIpList[0], numMult=nThread)
+                time.sleep(sleepTime)
+                intent = ''
+                counter = 300
+                while len(intent) > 0 and counter > 0:
+                    main.ONOS1cli.handle.sendline('intents | wc -l')
+                    main.ONOS1cli.handle.expect('intents | wc -l')
+                    main.ONOS1cli.handle.expect('onos>')
+                    intentTemp = main.ONOS1cli.handle.before()
+                    intent = main.ONOS1cli.intents()
+                    intent = json.loads(intent)
+                    counter = counter - 1
+                    time.sleep(1)
+
+                time.sleep(5)
+                saveDir = baseDir + 'batch_intent_1.txt'
+                with open(saveDir) as fOnos:
+                    lineCount = 0
+                    for line in fOnos:
+                        line_temp = ''
+                        main.log.info('Line read: ' + str(line))
+                        line_temp = line[1:]
+                        line_temp = line_temp.split(': ')
+                        if ' ' in str(line_temp):
+                            result = line_temp[1].split(' ')[0]
+                        else:
+                            main.log.warn('Empty line read')
+                            result = 0
+                        if lineCount == 0:
+                            if 'Failure' in str(line):
+                                main.log.warn('Intent installation failed')
+                                result = 'NA'
+                            else:
+                                main.log.info('Install result: ' + result)
+                                batchInstallLat.append(int(result))
+                            installResult = result
+                        elif lineCount == 1:
+                            if 'Failure' in str(line):
+                                main.log.warn('Intent withdraw failed')
+                                result = 'NA'
+                            else:
+                                main.log.info('Withdraw result: ' + result)
+                                batchWithdrawLat.append(int(result))
+                            withdrawResult = result
+                        else:
+                            main.log.warn('Invalid results')
+                            installResult = 'NA'
+                            withdrawResult = 'NA'
+                        lineCount += 1
+
+                main.log.info('Batch install latency with' +
+                        str(batchIntentSize) + 'intents: ' +
+                        str(installResult) + ' ms')
+                main.log.info('Batch withdraw latency with' +
+                        str(batchIntentSize) + 'intents: ' +
+                        str(withdrawResult) + ' ms')
+                main.log.info('Single intent install latency with' +
+                        str(batchIntentSize) + 'intents: ' +
+                        str(float(installResult) / int(batchIntentSize))+' ms')
+                main.log.info('Single intent withdraw latency with' +
+                        str(batchIntentSize) + 'intents: ' +
+                        str(float(withdrawResult)/ int(batchIntentSize))+' ms')
+                if len(batchInstallLat) > 0 and int(i) > numIgnore:
+                    maxInstallLat.append(max(batchInstallLat))
+                    maxSingleInstallLat.append(
+                            max(batchInstallLat) / int(batchIntentSize))
+                elif len(batchInstallLat) == 0:
+                    sleepTime += 30
+                if len(batchWithdrawLat) > 0 and int(i) > numIgnore:
+                    maxWithdrawLat.append(max(batchWithdrawLat))
+                    maxSingleWithdrawLat.append(
+                            max(batchWithdrawLat) / int(batchIntentSize))
+                batchInstallLat = []
+                batchWithdrawLat = []
+                time.sleep(5)
+
+            if maxInstallLat:
+                avgInstallLat = str(round(
+                    numpy.average(maxInstallLat), 2))
+                stdInstallLat = str(round(
+                    numpy.std(maxInstallLat), 2))
+                avgSingleInstallLat = str(round(
+                    numpy.average(maxSingleInstallLat), 3))
+                stdSingleInstallLat = str(round(
+                    numpy.std(maxSingleInstallLat), 3))
+            else:
+                avgInstallLat = 'NA'
+                stdInstallLat = 'NA'
+                main.log.report('Batch installation failed')
+                assertion = main.FALSE
+            if maxWithdrawLat:
+                avgWithdrawLat = str(round(
+                    numpy.average(maxWithdrawLat), 2))
+                stdWithdrawLat = str(round(
+                    numpy.std(maxWithdrawLat), 2))
+                avgSingleWithdrawLat = str(round(
+                    numpy.average(maxSingleWithdrawLat), 3))
+                stdSingleWithdrawLat = str(round(
+                    numpy.std(maxSingleWithdrawLat), 3))
+            else:
+                avgWithdrawLat = 'NA'
+                stdWithdrawLat = 'NA'
+                main.log.report('Batch withdraw failed')
+                assertion = main.FALSE
+            main.log.report('Avg of batch installation latency ' +
+                    'of size ' + str(batchIntentSize) + ': ' +
+                    str(avgInstallLat) + ' ms')
+            main.log.report('Std Deviation of batch installation latency ' +
+                    ': ' + str(round(numpy.std(maxInstallLat), 2)) + ' ms')
+            main.log.report('Avg of batch withdraw latency ' +
+                    'of size ' + str(batchIntentSize) + ': ' +
+                    str(avgWithdrawLat) + ' ms')
+            main.log.report('Std Deviation of batch withdraw latency ' +
+                    ': ' + str(round(numpy.std(maxWithdrawLat), 2)) + ' ms')
+            main.log.report('Avg of batch withdraw latency ' + 'of size ' +
+                    str(batchIntentSize) + ': ' + str(avgWithdrawLat) + ' ms')
+            main.log.report('Std Deviation of batch withdraw latency ' +
+                    ': ' + str(stdWithdrawLat) + ' ms')
+            main.log.report('Avg of single withdraw latency ' + 'of size ' +
+                    str(batchIntentSize) + ': ' +
+                    str(avgSingleWithdrawLat) + ' ms')
+            main.log.report('Std Deviation of single withdraw latency ' +
+                    ': ' + str(stdSingleWithdrawLat) + ' ms')
+            dbCmd = "INSERT INTO intents_latency_tests VALUES('" +\
+                    timeToPost + "','intents_latency_results'," +\
+                    runNum + ',' + str(clusterCount) + ',' +\
+                    str(batchIntentSize) + ',' + str(avgInstallLat) +\
+                    ',' + str(stdInstallLat) + ',' + str(avgWithdrawLat) +\
+                    ',' + str(stdWithdrawLat) + ');'
+            
+            fResult = open(intentFilePath, 'a')
+            if dbCmd:
+                fResult.write(dbCmd + '\n')
+            fResult.close()
+            if batch == 0:
+                batchIntentSize = 10
+            elif batch == 1:
+                batchIntentSize = 100
+            elif batch == 2:
+                batchIntentSize = 1000
+            elif batch == 3:
+                batchIntentSize = 1500
+            if batch < 4:
+                main.log.report('Increasing batch intent size to ' +
+                        str(batchIntentSize))
+
+        utilities.assert_equals(expect=main.TRUE, actual=assertion,
+                onpass='Batch intent install/withdraw test successful',
+                onfail='Batch intent install/withdraw test failed')
+
+    def CASE3(self, main):
+        """
+        Batch intent reroute latency
+        """
+        import time
+        import json
+        import requests
+        import os
+        import numpy
+        
+        ONOS1Ip = main.params['CTRL']['ip1']
+        ONOS2Ip = main.params['CTRL']['ip2']
+        ONOS3Ip = main.params['CTRL']['ip3']
+        ONOS4Ip = main.params['CTRL']['ip4']
+        ONOS5Ip = main.params['CTRL']['ip5']
+        ONOS6Ip = main.params['CTRL']['ip6']
+        ONOS7Ip = main.params['CTRL']['ip7']
+        
+        ONOSIpList = []
+        for i in range(1, 8):
+            ONOSIpList.append(main.params['CTRL']['ip' + str(i)])
+
+        ONOSUser = main.params['CTRL']['user']
+        defaultSwPort = main.params['CTRL']['port1']
+        batchIntentSize = main.params['TEST']['batchIntentSize']
+        thresholdMin = int(main.params['TEST']['batchThresholdMin'])
+        thresholdMax = int(main.params['TEST']['batchThresholdMax'])
+        
+        intfs = main.params['TEST']['intfs']
+        installTime = main.params['JSON']['installedTime']
+        numIter = main.params['TEST']['numIter']
+        numIgnore = int(main.params['TEST']['numIgnore'])
+        numSwitch = int(main.params['TEST']['numSwitch'])
+        nThread = main.params['TEST']['numMult']
+        
+        tsharkPortStatus = main.params[ 'TSHARK' ][ 'ofpPortStatus' ]
+        tsharkPortDown = '/tmp/tshark_port_down_reroute.txt'
+        
+        if clusterCount == 1:
+            for i in range(1, numSwitch + 1):
+                main.Mininet1.assignSwController(sw=str(i),
+                        ip1=ONOS1Ip, port1=defaultSwPort)
+        if clusterCount == 3:
+            for i in range(1, 3):
+                main.Mininet1.assignSwController(sw=str(i),
+                        ip1=ONOS1Ip, port1=defaultSwPort)
+            for i in range(3, 6):
+                main.Mininet1.assignSwController(sw=str(i),
+                        ip1=ONOS2Ip, port1=defaultSwPort)
+            for i in range(6, 9):
+                main.Mininet1.assignSwController(sw=str(i),
+                        ip1=ONOS3Ip, port1=defaultSwPort)
+        if clusterCount == 5:
+            main.Mininet1.assignSwController(sw='1',
+                    ip1=ONOS1Ip, port1=defaultSwPort)
+            main.Mininet1.assignSwController(sw='2',
+                    ip1=ONOS2Ip, port1=defaultSwPort)
+            for i in range(3, 6):
+                main.Mininet1.assignSwController(sw=str(i),
+                        ip1=ONOS3Ip, port1=defaultSwPort)
+            main.Mininet1.assignSwController(sw='6', 
+                    ip1=ONOS4Ip, port1=defaultSwPort)
+            main.Mininet1.assignSwController(sw='7',
+                    ip1=ONOS5Ip, port1=defaultSwPort)
+            main.Mininet1.assignSwController(sw='8',
+                    ip1=ONOS5Ip, port1=defaultSwPort)
+        if clusterCount == 7:
+            for i in range(1, 9):
+                if i < 8:
+                    main.Mininet1.assignSwController(sw=str(i),
+                            ip1=ONOSIpList[i - 1], port1=defaultSwPort)
+                elif i >= 8:
+                    main.Mininet1.assignSwController(sw=str(i),
+                            ip1=ONOSIpList[6], port1=defaultSwPort)
+
+        main.log.report('Batch intent reroute test ')
+
+        batchIntentRerouteAvgSystem = numpy.zeros((
+            clusterCount, int(numIter)))
+        batchIntentRerouteStdSystem = numpy.zeros((
+            clusterCount, int(numIter)))
+        batchIntentRerouteAvgPort = numpy.zeros((
+            clusterCount, int(numIter)))
+        batchIntentRerouteStdSystem = numpy.zeros((
+            clusterCount, int(numIter)))
+        
+        time.sleep(10)
+        
+        main.log.info('Getting list of available devices')
+        
+        deviceIdList = []
+        jsonStr = main.ONOS1cli.devices()
+        jsonObj = json.loads(jsonStr)
+        for device in jsonObj:
+            deviceIdList.append(device['id'])
+        if not jsonObj:
+            main.log.warn('No devices have been discovered')
+            assertion = main.FALSE
+        
+        sleepTime = 10
+        
+        baseDir = '/tmp/'
+        for batch in range(0, 5):
+            maxRerouteLatSystem = []
+            maxRerouteLatPort = []
+            for i in range(0, int(numIter)):
+                rerouteLatSystem = []
+                rerouteLatPort = []
+                main.log.info('Pushing ' + str(
+                    int(batchIntentSize) * int(nThread)) +
+                    ' intents. Iteration ' + str(i))
+                main.ONOSbench.pushTestIntentsShell(
+                        deviceIdList[0] + '/2', deviceIdList[7] +
+                        '/2', batchIntentSize, '/tmp/batch_install.txt',
+                        ONOSIpList[0], numMult='1', report=False,
+                        options='-i')
+                
+                time.sleep(10)
+                
+                main.ONOS1.tsharkGrep(tsharkPortStatus, tsharkPortDown)
+                main.log.info('Disabling interface ' + intfs)
+                main.Mininet1.handle.sendline(
+                        'sh ifconfig ' + intfs + ' down')
+                t0System = time.time() * 1000
+                
+                time.sleep(3)
+                
+                main.ONOS1.tsharkStop()
+                
+                time.sleep(2)
+                
+                os.system('scp ' + ONOSUser + '@' + ONOSIpList[0] +
+                        ':' + tsharkPortDown + ' /tmp/')
+                time.sleep(5)
+                
+                fPortDown = open(tsharkPortDown, 'r')
+                fLine = fPortDown.readline()
+                objDown = fLine.split(' ')
+                if len(fLine) > 0:
+                    timestampBeginPtDown = int(float(objDown[1]) * 1000)
+                    if timestampBeginPtDown < 1400000000000:
+                        timestampBeginPtDown = int(float(objDown[2]) * 1000)
+                    main.log.info('Port down begin timestamp: ' +
+                            str(timestampBeginPtDown))
+                else:
+                    main.log.info('Tshark output file returned unexpected' +
+                            ' results: ' + str(fLine))
+                fPortDown.close()
+                
+                intentsJsonStr1 = main.ONOS1cli.intentsEventsMetrics()
+                intentsJsonObj1 = json.loads(intentsJsonStr1)
+                intentInstall1 = intentsJsonObj1[installTime]['value']
+                intentRerouteLat1 = int(intentInstall1) - int(t0System)
+                intentRerouteLatPort1 =\
+                        int(intentInstall1) - int(timestampBeginPtDown)
+                
+                if intentRerouteLat1 > thresholdMin and \
+                        intentRerouteLat1 < thresholdMax and\
+                        i > numIgnore:
+                    rerouteLatSystem.append(intentRerouteLat1)
+                main.log.info('ONOS1 Intent Reroute Lat ' +
+                        ' size: ' + str(batchIntentSize) +
+                        ' system-to-install: ' +
+                        str(intentRerouteLat1) + ' ms')
+                if intentRerouteLatPort1 > thresholdMin and\
+                        intentRerouteLatPort1 < thresholdMax and\
+                        i > numIgnore:
+                    rerouteLatPort.append(intentRerouteLatPort1)
+                
+                main.log.info('ONOS1 Intent Reroute Lat ' +
+                        ' size: ' + str(batchIntentSize) +
+                        ' system-to-install: ' +
+                        str(intentRerouteLatPort1) + ' ms')
+                
+                if clusterCount == 3:
+                    intentsJsonStr2 = main.ONOS2cli.intentsEventsMetrics()
+                    intentsJsonStr3 = main.ONOS3cli.intentsEventsMetrics()
+                    intentsJsonObj2 = json.loads(intentsJsonStr2)
+                    intentsJsonObj3 = json.loads(intentsJsonStr3)
+                    intentInstall2 = intentsJsonObj2[installTime]['value']
+                    intentInstall3 = intentsJsonObj3[installTime]['value']
+                    intentRerouteLat2 = int(intentInstall2) - int(t0System)
+                    intentRerouteLat3 = int(intentInstall3) - int(t0System)
+                    intentRerouteLatPort2 = int(intentInstall2) - int(timestampBeginPtDown)
+                    intentRerouteLatPort3 = int(intentInstall3) - int(timestampBeginPtDown)
+                    
+                    if intentRerouteLat2 > thresholdMin and\
+                            intentRerouteLat2 < thresholdMax and\
+                            i > numIgnore:
+                        rerouteLatSystem.append(intentRerouteLat2)
+                        main.log.info('ONOS2 Intent Reroute Lat' +
+                                ' size: ' + str(batchIntentSize) +
+                                ' system-to-install: ' + str(intentRerouteLat2) + ' ms')
+                    if intentRerouteLat3 > thresholdMin and\
+                            intentRerouteLat3 < thresholdMax and\
+                            i > numIgnore:
+                        rerouteLatSystem.append(intentRerouteLat3)
+                        main.log.info('ONOS3 Intent Reroute Lat' +
+                                ' size: ' + str(batchIntentSize) +
+                                ' system-to-install: ' + str(intentRerouteLat3) +
+                                ' ms')
+                    if intentRerouteLatPort2 > thresholdMin and\
+                            intentRerouteLatPort2 < thresholdMax and\
+                            i > numIgnore:
+                        rerouteLatPort.append(intentRerouteLatPort2)
+                        main.log.info('ONOS2 Intent Reroute Lat' +
+                                ' size: ' + str(batchIntentSize) +
+                                ' port-to-install: ' +
+                                str(intentRerouteLatPort2) + ' ms')
+                    if intentRerouteLatPort3 > thresholdMin and\
+                            intentRerouteLatPort3 < thresholdMax and\
+                            i > numIgnore:
+                        rerouteLatPort.append(intentRerouteLatPort3)
+                        main.log.info('ONOS3 Intent Reroute Lat' +
+                                ' size: ' + str(batchIntentSize) +
+                                ' port-to-install: ' +
+                                str(intentRerouteLatPort2) + ' ms')
+                
+                if clusterCount == 5:
+                    intentsJsonStr4 = main.ONOS4cli.intentsEventsMetrics()
+                    intentsJsonStr5 = main.ONOS5cli.intentsEventsMetrics()
+                    intentsJsonObj4 = json.loads(intentsJsonStr4)
+                    intentsJsonObj5 = json.loads(intentsJsonStr5)
+                    intentInstall4 = intentsJsonObj4[installTime]['value']
+                    intentInstall5 = intentsJsonObj5[installTime]['value']
+                    intentRerouteLat4 = int(intentInstall4) - int(t0System)
+                    intentRerouteLat5 = int(intentInstall5) - int(t0System)
+                    intentRerouteLatPort4 =\
+                            int(intentInstall4) - int(timestampBeginPtDown)
+                    intentRerouteLatPort5 =\
+                            int(intentInstall5) - int(timestampBeginPtDown)
+                    if intentRerouteLat4 > thresholdMin and\
+                            intentRerouteLat4 < thresholdMax and \
+                            i > numIgnore:
+                        rerouteLatSystem.append(intentRerouteLat4)
+                        main.log.info('ONOS4 Intent Reroute Lat' +
+                                ' size: ' + str(batchIntentSize) +
+                                ' system-to-install: ' + str(intentRerouteLat4) +
+                                ' ms')
+                    if intentRerouteLat5 > thresholdMin and\
+                            intentRerouteLat5 < thresholdMax and\
+                            i > numIgnore:
+                        rerouteLatSystem.append(intentRerouteLat5)
+                        main.log.info('ONOS5 Intent Reroute Lat' +
+                                ' size: ' + str(batchIntentSize) +
+                                ' system-to-install: ' +
+                                str(intentRerouteLat5) + ' ms')
+                    if intentRerouteLatPort4 > thresholdMin and\
+                            intentRerouteLatPort4 < thresholdMax and\
+                            i > numIgnore:
+                        rerouteLatPort.append(intentRerouteLatPort4)
+                        main.log.info('ONOS4 Intent Reroute Lat' +
+                                ' size: ' + str(batchIntentSize) +
+                                ' port-to-install: ' +
+                                str(intentRerouteLatPort4) + ' ms')
+                    if intentRerouteLatPort5 > thresholdMin and\
+                            intentRerouteLatPort5 < thresholdMax and\
+                            i > numIgnore:
+                        rerouteLatPort.append(intentRerouteLatPort5)
+                        main.log.info('ONOS5 Intent Reroute Lat' +
+                                ' size: ' + str(batchIntentSize) +
+                                ' port-to-install: ' +
+                                str(intentRerouteLatPort5) + ' ms')
+                
+                if clusterCount == 7:
+                    intentsJsonStr6 = main.ONOS6cli.intentsEventsMetrics()
+                    intentsJsonStr7 = main.ONOS7cli.intentsEventsMetrics()
+                    intentsJsonObj6 = json.loads(intentsJsonStr6)
+                    intentsJsonObj7 = json.loads(intentsJsonStr7)
+                    intentInstall6 = intentsJsonObj6[installTime]['value']
+                    intentInstall7 = intentsJsonObj7[installTime]['value']
+                    intentRerouteLat6 = int(intentInstall6) - int(t0System)
+                    intentRerouteLat7 = int(intentInstall7) - int(t0System)
+                    intentRerouteLatPort4 =\
+                            int(intentInstall4) - int(timestampBeginPtDown)
+                    intentRerouteLatPort5 =\
+                            int(intentInstall5) - int(timestampBeginPtDown)
+                    if intentRerouteLat6 > thresholdMin and\
+                            intentRerouteLat6 < thresholdMax and\
+                            i > numIgnore:
+                        rerouteLatSystem.append(intentRerouteLat6)
+                        main.log.info('ONOS6 Intent Reroute Lat' +
+                                ' size: ' + str(batchIntentSize) +
+                                ' system-to-install: ' +
+                                str(intentRerouteLat6) + ' ms')
+                    if intentRerouteLat7 > thresholdMin and\
+                            intentRerouteLat7 < thresholdMax and\
+                            i > numIgnore:
+                        rerouteLatSystem.append(intentRerouteLat7)
+                        main.log.info('ONOS7 Intent Reroute Lat' +
+                                ' size: ' + str(batchIntentSize) +
+                                ' system-to-install: ' + 
+                                str(intentRerouteLat7) + ' ms')
+                    if intentRerouteLatPort6 > thresholdMin and\
+                            intentRerouteLatPort6 < thresholdMax and\
+                            i > numIgnore:
+                        rerouteLatPort.append(intentRerouteLatPort6)
+                        main.log.info('ONOS6 Intent Reroute Lat' +
+                                ' size: ' + str(batchIntentSize) +
+                                ' port-to-install: ' +
+                                str(intentRerouteLatPort6) + ' ms')
+                    if intentRerouteLatPort7 > thresholdMin and\
+                            intentRerouteLatPort7 < thresholdMax and\
+                            i > numIgnore:
+                        rerouteLatPort.append(intentRerouteLatPort7)
+                        main.log.info('ONOS7 Intent Reroute Lat' +
+                                ' size: ' + str(batchIntentSize) +
+                                ' port-to-install: ' +
+                                str(intentRerouteLatPort7) + ' ms')
+
+                time.sleep(5)
+                
+                main.log.info('System: ' + str(rerouteLatSystem))
+                main.log.info('Port: ' + str(rerouteLatPort))
+                if rerouteLatSystem:
+                    maxRerouteLatSystem = max(rerouteLatSystem)
+                    main.log.info('Max system: ' + str(maxRerouteLatSystem))
+                if rerouteLatPort:
+                    maxRerouteLatPort = max(rerouteLatPort)
+                    main.log.info('Max port: ' + str(maxRerouteLatPort))
+               
+                # Bring port back up for next iteration
+                main.Mininet1.handle.sendline('sh ifconfig ' + intfs + ' up')
+                time.sleep(5)
+
+                # Use 'withdraw' option to withdraw batch intents
+                main.ONOSbench.pushTestIntentsShell(
+                        deviceIdList[0] + '/2', deviceIdList[7] + '/2',
+                        batchIntentSize, '/tmp/batch_install.txt',
+                        ONOSIpList[0], numMult='1', report=False, options='-w')
+                main.log.info('Intents removed and port back up')
+             
+            # NOTE: End iteration loop
+            if batch == 1:
+                batchIntentSize = 10
+            elif batch == 2:
+                batchIntentSize = 100
+            elif batch == 3:
+                batchIntentSize = 500
+            elif batch == 4:
+                batchIntentSize = 1000
+            main.log.info('Batch intent size increased to ' + str(batchIntentSize))
+
+    def CASE4(self, main):
+        """
+        Increase number of nodes and initiate CLI
+        """
+        global clusterCount
+        import time
+        import json
+        
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        features = main.params[ 'ENV' ][ 'cellFeatures' ]
+        benchIp = main.params[ 'BENCH' ][ 'ip' ]
+        mininetIp = main.params[ 'TEST' ][ 'MN' ]
+        
+        clusterCount += 2
+        main.log.report('Increasing cluster size to ' + str(clusterCount))
+        
+        ONOSIp = []
+        for i in range( 1, 8 ):
+            ONOSIp.append( main.params[ 'CTRL' ][ 'ip'+str(i) ]
+
+        main.step( "Cleaning environment" )
+        for i in range( 1, 8 ):
+            main.ONOSbench.onosDie( ONOSIp[i] )
+            main.log.info( "Uninstalling ONOS "+str(i) )
+            main.ONOSbench.onosUninstall( ONOSIp[i] )
+
+        main.step( "Creating new cell file" )
+        cellIp = []
+        for node in range( 1, clusterCount + 1 )
+            cellIp.append( ONOSIp[node] )
+        main.ONOSbench.createCellFile( benchIp, cellName,
+                                       mininetIp, str(features), *cellIp )
+
+        main.step( "Setting cell definition" )
+        main.ONOSbench.setCell( cellName )
+
+        main.step( "Packaging cell definition" )
+        main.ONOSbench.onosPackage()
+
+        for node in range( 1, clusterCount + 1 ):
+            time.sleep(10)
+            main.log.info( "Starting ONOS "+str(node) +
+                            " at IP: "+ONOSIp[node] )
+            main.ONOSbench.onosInstall( ONOSIp[node] )
+            exec "a = main.ONOS%scli.startOnosCli" %str(node)
+            a( ONOSIp[node] )
+
+        for node in range( 1, clusterCount + 1 ):
+            for i in range( 2 ):
+                isup = main.ONOSbench.isup( ONOSIp[node] )
+                if isup:
+                    main.log.info( "ONOS "+str(node) + " is up\n")
+                    assertion = main.TRUE
+                    break
+                if not isup:
+                    main.log.info( "ONOS" + str(node) + " did not start")
+        
+        utilities.assert_equals(expect=main.TRUE, actual=assertion,
+            onpass='Scale out to ' + str(clusterCount) + ' nodes successful',
+            onfail='Scale out to ' + str(clusterCount) + ' nodes failed')
+
diff --git a/TestON/tests/IntentPerfNextBM/IntentPerfNextBM.topo b/TestON/tests/IntentPerfNextBM/IntentPerfNextBM.topo
new file mode 100644
index 0000000..197acfa
--- /dev/null
+++ b/TestON/tests/IntentPerfNextBM/IntentPerfNextBM.topo
@@ -0,0 +1,109 @@
+<TOPOLOGY>
+    <COMPONENT>
+        
+        <ONOSbench>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOSbench>
+
+        <ONOS1cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1cli>
+
+        <ONOS2cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2cli>
+        
+        <ONOS3cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3cli>
+        
+        <ONOS4cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4cli>
+        
+        <ONOS5cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5cli>
+        
+        <ONOS6cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6cli>
+        
+        <ONOS7cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>8</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS7cli>
+
+        <ONOS1>
+            <host>10.254.1.201</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>9</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1>
+
+        <Mininet1>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>MininetCliDriver</type>
+            <connect_order>10</connect_order>
+            <COMPONENTS>
+                <arg1> --custom topo-intent-8sw.py </arg1>
+                <arg2> --arp --mac --topo mytopo </arg2>
+                <arg3> </arg3>
+                <controller> remote </controller>
+            </COMPONENTS>
+        </Mininet1>
+
+        <Mininet2>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>RemoteMininetDriver</type>
+            <connect_order>11</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </Mininet2>
+
+    </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/IntentsLoad/IntentsLoad.params b/TestON/tests/IntentsLoad/IntentsLoad.params
deleted file mode 100644
index b60621c..0000000
--- a/TestON/tests/IntentsLoad/IntentsLoad.params
+++ /dev/null
@@ -1,49 +0,0 @@
-<PARAMS>
-
-    <testcases>1,2,4</testcases>
-
-    <ENV>
-    <cellName>cam_cells</cellName>
-    </ENV>
-
-    <SCALE>1</SCALE>
-
-    <GIT>
-        <autopull>off</autopull>
-        <checkout>master</checkout>
-    </GIT>
-
-    <CTRL>
-        <USER>admin</USER>
-        <ip1>10.128.5.51</ip1>
-        <port1>6633</port1>
-        <ip2>10.128.5.52</ip2>
-        <port2>6633</port2>
-        <ip3>10.128.5.53</ip3>
-        <port3>6633</port3>
-    </CTRL>
-
-    <MN>
-        <ip1>10.128.5.59</ip1>
-        <ip2>10.128.5.59</ip2>
-    </MN>
-
-    <BENCH>
-        <user>admin</user>
-        <ip1>10.128.5.55</ip1>
-    </BENCH>
-
-    <TEST>
-    <loadstart>curl --fail http://localhost:8181/onos/demo/intents/setup -H "Content-Type:application/json" -d '{"type" : "random"}'</loadstart>
-    <loadstop>curl --fail http://localhost:8181/onos/demo/intents/teardown</loadstop>
-    <arping>py [h.cmd("arping -c 1 -w 1 10.0.0.225") for h in net.hosts]</arping>
-    <metric1>intents-events-metrics|grep "Intent Installed Events"</metric1>
-    <duration>90</duration>
-    <log_interval>5</log_interval>
-    </TEST>
-
-    <JSON>
-        <intents_rate>intentInstalledRate</intents_rate>
-    </JSON>
-
-</PARAMS>
diff --git a/TestON/tests/IntentsLoad/IntentsLoad.py b/TestON/tests/IntentsLoad/IntentsLoad.py
deleted file mode 100644
index f13e60d..0000000
--- a/TestON/tests/IntentsLoad/IntentsLoad.py
+++ /dev/null
@@ -1,263 +0,0 @@
-# ScaleOutTemplate --> IntentsLoad
-#
-# CASE1 starts number of nodes specified in param file
-#
-# cameron@onlab.us
-
-import sys 
-import os 
-
-
-class IntentsLoad:
-    def __init__(self):
-        self.default = ''
-   
-    def CASE1(self, main):
-        
-        global cluster_count 
-        cluster_count = 1        
-
-        checkout_branch = main.params['GIT']['checkout']
-        git_pull = main.params['GIT']['autopull']
-        cell_name = main.params['ENV']['cellName']
-        BENCH_ip = main.params['BENCH']['ip1']
-        BENCH_user = main.params['BENCH']['user']
-        ONOS1_ip = main.params['CTRL']['ip1']
-        ONOS2_ip = main.params['CTRL']['ip2']
-        ONOS3_ip = main.params['CTRL']['ip3']
-        MN1_ip = main.params['MN']['ip1']
-
-        main.log.step("Cleaning Enviornment...")
-        main.ONOSbench.onos_uninstall(ONOS1_ip)
-        main.ONOSbench.onos_uninstall(ONOS2_ip)
-        main.ONOSbench.onos_uninstall(ONOS3_ip)                                     
-        
-        main.step("Git checkout and pull "+checkout_branch)
-        if git_pull == 'on':
-            checkout_result = main.ONOSbench.git_checkout(checkout_branch)       
-            pull_result = main.ONOSbench.git_pull()
-            
-        else:
-            checkout_result = main.TRUE
-            pull_result = main.TRUE
-            main.log.info("Skipped git checkout and pull")
-
-        #mvn_result = main.ONOSbench.clean_install()
-                                                                   
-        main.step("Set cell for ONOS cli env")
-        main.ONOS1cli.set_cell(cell_name)
-        main.ONOS2cli.set_cell(cell_name)
-        main.ONOS3cli.set_cell(cell_name)
-
-        main.step("Creating ONOS package")
-        package_result = main.ONOSbench.onos_package()                             #no file or directory 
-
-        main.step("Installing ONOS package")
-        install1_result = main.ONOSbench.onos_install(node=ONOS1_ip)
-
-        cell_name = main.params['ENV']['cellName']
-        main.step("Applying cell file to environment")
-        cell_apply_result = main.ONOSbench.set_cell(cell_name)
-        main.step("verify cells")
-        verify_cell_result = main.ONOSbench.verify_cell()
-
-        main.step("Set cell for ONOS cli env")
-        main.ONOS1cli.set_cell(cell_name) 
- 
-        cli1 = main.ONOS1cli.start_onos_cli(ONOS1_ip) 
-
-    def CASE2(self, main):
-
-        '''  
-        Increase number of nodes and initiate CLI
-        '''
-        import time 
-        
-        global cluster_count
-        
-        ONOS1_ip = main.params['CTRL']['ip1']
-        ONOS2_ip = main.params['CTRL']['ip2']
-        ONOS3_ip = main.params['CTRL']['ip3']
-        #ONOS4_ip = main.params['CTRL']['ip4']
-        #ONOS5_ip = main.params['CTRL']['ip5']
-        #ONOS6_ip = main.params['CTRL']['ip6']
-        #ONOS7_ip = main.params['CTRL']['ip7']
-        cell_name = main.params['ENV']['cellName']
-        scale = int(main.params['SCALE'])
-
-
-        #Cluster size increased everytime the case is defined
-        cluster_count += scale
- 
-        main.log.report("Increasing cluster size to "+
-                str(cluster_count))
-        install_result = main.FALSE
-        
-        if scale == 2:
-            if cluster_count == 3:
-                main.log.info("Installing nodes 2 and 3")
-                install2_result = main.ONOSbench.onos_install(node=ONOS2_ip)
-                install3_result = main.ONOSbench.onos_install(node=ONOS3_ip)
-                cli2 = main.ONOS2cli.start_onos_cli(ONOS2_ip)
-                cli3 = main.ONOS3cli.start_onos_cli(ONOS3_ip) 
-            '''
-            elif cluster_count == 5:
-
-                main.log.info("Installing nodes 4 and 5")
-                node4_result = main.ONOSbench.onos_install(node=ONOS4_ip)
-                node5_result = main.ONOSbench.onos_install(node=ONOS5_ip)
-                install_result = node4_result and node5_result
-                time.sleep(5)
-
-                main.ONOS4cli.start_onos_cli(ONOS4_ip)
-                main.ONOS5cli.start_onos_cli(ONOS5_ip)
-
-            elif cluster_count == 7:
-
-                main.log.info("Installing nodes 4 and 5")
-                node6_result = main.ONOSbench.onos_install(node=ONOS6_ip)
-                node7_result = main.ONOSbench.onos_install(node=ONOS7_ip)
-                install_result = node6_result and node7_result
-                time.sleep(5)
-
-                main.ONOS6cli.start_onos_cli(ONOS6_ip)
-                main.ONOS7cli.start_onos_cli(ONOS7_ip)
-            '''
-        if scale == 1: 
-            if cluster_count == 2:
-                main.log.info("Installing node 2")
-                install2_result = main.ONOSbench.onos_install(node=ONOS2_ip)
-                cli2 = main.ONOS2cli.start_onos_cli(ONOS2_ip)
-
-            if cluster_count == 3:
-                main.log.info("Installing node 3")
-                install3_result = main.ONOSbench.onos_install(node=ONOS3_ip)
-                cli3 = main.ONOS3cli.start_onos_cli(ONOS3_ip)
-    
-    
-    
-    def CASE3(self,main):
-        import time 
-        import json
-        import string
-        
-        intents_rate = main.params['JSON']['intents_rate']
-
-        default_sw_port = main.params[ 'CTRL' ][ 'port1' ]
-
-        main.Mininet1.assign_sw_controller(sw="1", ip1=ONOS1_ip, port1=default_sw_port )
-        main.Mininet1.assign_sw_controller(sw="2", ip1=ONOS1_ip, port1=default_sw_port )
-        main.Mininet1.assign_sw_controller(sw="3", ip1=ONOS1_ip, port1=default_sw_port )
-        main.Mininet1.assign_sw_controller(sw="4", ip1=ONOS1_ip, port1=default_sw_port )
-        main.Mininet1.assign_sw_controller(sw="5", ip1=ONOS1_ip, port1=default_sw_port )
-        main.Mininet1.assign_sw_controller(sw="6", ip1=ONOS1_ip, port1=default_sw_port )
-        main.Mininet1.assign_sw_controller(sw="7", ip1=ONOS1_ip, port1=default_sw_port )
-        
-        mn_arp = main.params['TEST']['arping']
-        main.Mininet1.handle.sendline(mn_arp)
-
-        generate_load = main.params['TEST']['loadstart']
-   
-        main.ONOS1.handle.sendline(generate_load)
-        main.ONOS1.handle.expect("sdn")
-        print("before: ", main.ONOS1.handle.before)
-        print("after: ",main.ONOS1.handle.after)
-        
-        load_confirm = main.ONOS1.handle.after
-        if load_confirm == "{}":
-            main.log.info("Load started")
-
-        else: 
-            main.log.error("Load start failure")
-            main.log.error("expected '{}', got: " + str(load_confirm))
-     
-        devices_json_str = main.ONOS1cli.devices()
-        devices_json_obj = json.loads(devices_json_str)
-
-        get_metric = main.params['TEST']['metric1']
-        test_duration = main.params['TEST']['duration']
-        stop = time.time() + float(test_duration)
-
-
-        main.log.info("Starting test loop...")
-        log_interval = main.params['TEST']['log_interval']
-
-        while time.time() < stop: 
-            time.sleep(float(log_interval))
-         
-            intents_json_str_1 = main.ONOS1cli.intents_events_metrics()
-            intents_json_obj_1 = json.loads(intents_json_str_1)
-            main.log.info("Node 1 rate: " + str(intents_json_obj_1[intents_rate]['m1_rate']))
-            last_rate_1 = intents_json_obj_1[intents_rate]['m1_rate']
-        
-        stop_load = main.params['TEST']['loadstop']
-        main.ONOS1.handle.sendline(stop_load)
-        
-        
-        msg = ("Final rate on node 1: " + str(last_rate_1))
-        main.log.report(msg)
-
-    def CASE4(self, main):      #2 node scale 
-        import time
-        import json
-        import string
-
-        intents_rate = main.params['JSON']['intents_rate']
-        
-        default_sw_port = main.params[ 'CTRL' ][ 'port1' ]
-
-        main.Mininet1.assign_sw_controller(sw="1", ip1=ONOS1_ip, port1=default_sw_port )
-        main.Mininet1.assign_sw_controller(sw="2", ip1=ONOS2_ip, port1=default_sw_port )
-        main.Mininet1.assign_sw_controller(sw="3", ip1=ONOS1_ip, port1=default_sw_port )
-        main.Mininet1.assign_sw_controller(sw="4", ip1=ONOS2_ip, port1=default_sw_port )
-        main.Mininet1.assign_sw_controller(sw="5", ip1=ONOS1_ip, port1=default_sw_port )
-        main.Mininet1.assign_sw_controller(sw="6", ip1=ONOS2_ip, port1=default_sw_port )
-        main.Mininet1.assign_sw_controller(sw="7", ip1=ONOS1_ip, port1=default_sw_port )
-
-        mn_arp = main.params['TEST']['arping']
-        main.Mininet1.handle.sendline(mn_arp)
-
-        generate_load = main.params['TEST']['loadstart']
-
-        main.ONOS1.handle.sendline(generate_load)
-        main.ONOS2.handle.sendline(generate_load)
-
-        devices_json_str_1 = main.ONOS1cli.devices()
-        devices_json_obj_1 = json.loads(devices_json_str_1)
-        devices_json_str_2 = main.ONOS2cli.devices()
-        devices_json_obj_2 = json.loads(devices_json_str_2)
-
-        get_metric = main.params['TEST']['metric1']
-        test_duration = main.params['TEST']['duration']
-        stop = time.time() + float(test_duration)
-
-
-        main.log.info("Starting test loop...")
-        log_interval = main.params['TEST']['log_interval']
-
-        while time.time() < stop:
-            time.sleep(float(log_interval))
-
-            intents_json_str_1 = main.ONOS1cli.intents_events_metrics()
-            intents_json_obj_1 = json.loads(intents_json_str_1)
-            main.log.info("Node 1 rate: " + str(intents_json_obj_1[intents_rate]['m1_rate']))
-            last_rate_1 = intents_json_obj_1[intents_rate]['m1_rate']
-            
-            intents_json_str_2 = main.ONOS2cli.intents_events_metrics()
-            intents_json_obj_2 = json.loads(intents_json_str_2)
-            main.log.info("Node 2 rate: " + str(intents_json_obj_2[intents_rate]['m1_rate']))
-            last_rate_2 = intents_json_obj_2[intents_rate]['m1_rate']
-
-        stop_load = main.params['TEST']['loadstop']
-        main.ONOS1.handle.sendline(stop_load)
-        main.ONOS2.handle.sendline(stop_load)
-
-
-        msg = ("Final rate on node 1: " + str(last_rate_1))
-        main.log.report(msg)
-    
-        msg = ("Final rate on node 2: " + str(last_rate_2))
-        main.log.report(msg)
-
-
-
diff --git a/TestON/tests/IntentsLoad/IntentsLoad.topo b/TestON/tests/IntentsLoad/IntentsLoad.topo
deleted file mode 100644
index 985baf9..0000000
--- a/TestON/tests/IntentsLoad/IntentsLoad.topo
+++ /dev/null
@@ -1,94 +0,0 @@
-<TOPOLOGY>
-
-    <COMPONENT>
-
-        <ONOSbench>
-            <host>10.128.5.55</host>
-            <user>admin</user>
-            <password>onos_test</password>
-            <type>OnosDriver</type>
-            <connect_order>1</connect_order>
-            <COMPONENTS> </COMPONENTS>
-        </ONOSbench>
-
-        <ONOS1cli>
-            <host>10.128.5.55</host>
-            <user>admin</user>
-            <password>onos_test</password>
-            <type>OnosCliDriver</type>
-            <connect_order>2</connect_order>
-            <COMPONENTS> </COMPONENTS>
-        </ONOS1cli>
-        
-        <ONOS2cli>
-            <host>10.128.5.55</host>
-            <user>admin</user>
-            <password>onos_test</password>
-            <type>OnosCliDriver</type>
-            <connect_order>3</connect_order>
-            <COMPONENTS> </COMPONENTS>
-        </ONOS2cli>
-
-        <ONOS3cli>
-            <host>10.128.5.55</host>
-            <user>admin</user>
-            <password>onos_test</password>
-            <type>OnosCliDriver</type>
-            <connect_order>4</connect_order>
-            <COMPONENTS> </COMPONENTS>
-        </ONOS3cli>
-
-        <ONOS1>
-            <host>10.128.5.51</host>
-            <user>sdn</user>
-            <password>rocks</password>
-            <type>OnosDriver</type>
-            <connect_order>5</connect_order>
-            <COMPONENTS> </COMPONENTS>
-        </ONOS1>
-
-        <ONOS2>
-            <host>10.128.5.52</host>
-            <user>sdn</user>
-            <password>rocks</password>
-            <type>OnosDriver</type>
-            <connect_order>6</connect_order>
-            <COMPONENTS> </COMPONENTS>
-        </ONOS2>
-
-        <ONOS3>
-            <host>10.128.5.53</host>
-            <user>sdn</user>
-            <password>rocks</password>
-            <type>OnosDriver</type>
-            <connect_order>7</connect_order>
-            <COMPONENTS> </COMPONENTS>
-        </ONOS3>
-
-        <Mininet1>
-            <host>10.128.5.59</host>
-            <user>admin</user>
-            <password>onos_test</password>
-            <type>MininetCliDriver</type>
-            <connect_order>8</connect_order>
-            <COMPONENTS>
-                <arg1> --custom ~/topo-intentTPtest.py </arg1>
-                <arg2> --mac --topo mytopo </arg2>
-                <arg3> </arg3>
-                <controller> remote </controller>
-            </COMPONENTS>
-        </Mininet1>
-        
-        <Mininet2>
-            <host>10.128.5.59</host>
-            <user>admin</user>
-            <password>onos_test</password>
-            <type>RemoteMininetDriver</type>
-            <connect_order>9</connect_order>
-            <COMPONENTS> </COMPONENTS>
-        </Mininet2>
-
-    </COMPONENT>
-
-</TOPOLOGY>
-
diff --git a/TestON/tests/IntentsLoad/__init__.py b/TestON/tests/LincOETest/__init__.py
similarity index 100%
copy from TestON/tests/IntentsLoad/__init__.py
copy to TestON/tests/LincOETest/__init__.py
diff --git a/TestON/tests/LinkEventTP/LinkEventTP.params b/TestON/tests/LinkEventTP/LinkEventTP.params
index 2beb9aa..b4d50e5 100644
--- a/TestON/tests/LinkEventTP/LinkEventTP.params
+++ b/TestON/tests/LinkEventTP/LinkEventTP.params
@@ -1,12 +1,9 @@
 <PARAMS>
-
     <testcases>1,3,2,3,2,3,2,3</testcases>
-
     <ENV>
     <cellName>network_tp_test</cellName>
     <cellFeatures>"webconsole,onos-core,onos-api,onos-cli,onos-null,onos-rest,onos-app-metrics,onos-app-metrics-intent,onos-app-metrics-topology"</cellFeatures>
     </ENV>
-
     <SCALE>2</SCALE>
     <availableNodes>7</availableNodes>
 
@@ -38,20 +35,20 @@
         <ip1>localhost</ip1>
     </BENCH>
 
-    <TEST>                              #   duration =      time the test loop runs
-                                        #   log_interval =  how often the data is reported 
-                                        #   wait =          time between tests, used to let the averages run down 
-                                         
-        <metric1>topologyLinkEventRate</metric1>
-        <metric2>topologyGraphEventRate</metric2>
-        <flickerRate>2</flickerRate>
-        <duration>180</duration>
-        <log_interval>20</log_interval>
-        <wait>30</wait>
-        <configFile>/onos/tools/package/etc/org.onosproject.net.topology.impl.DefaultTopologyProvider.cfg</configFile>
+    <TEST>          #   duration =      time the test loop runs
+                    #   log_interval =  how often the data is reported 
+                    #   wait =          time between tests, used to let the averages run down 
+               
+        <flickerRates>1000,0,0,0,0,0,0</flickerRates>
+        <devicesPerNode>20,0,0,0,0,0,0</devicesPerNode>
+        <flickerRate>1000</flickerRate>
+        <linkgraphdif>.03</linkgraphdif>          # 0-1 indicated link/graph rate dif tolerance
+        <duration>120</duration>
+        <log_interval>15</log_interval>
+        <wait>60</wait>
         <skipCleanInstall>yes</skipCleanInstall>
         <MN>localhost</MN>
-	<logFile>link_event_tp_results_LOG</logFile>
+	    <logFile>link_event_tp_results_LOG</logFile>
     </TEST>
 
     <JSON>
diff --git a/TestON/tests/LinkEventTP/LinkEventTP.py b/TestON/tests/LinkEventTP/LinkEventTP.py
index 1f5861e..e7d2133 100644
--- a/TestON/tests/LinkEventTP/LinkEventTP.py
+++ b/TestON/tests/LinkEventTP/LinkEventTP.py
@@ -34,14 +34,18 @@
         Features = main.params[ 'ENV' ][ 'cellFeatures' ]
         skipMvn = main.params[ 'TEST' ][ 'skipCleanInstall' ]
         flickerRate = main.params[ 'TEST' ][ 'flickerRate']
+        deviceDistribution = (main.params[ 'TEST' ][ 'devicesPerNode']).split(",")    
         MNip = main.params[ 'TEST' ][ 'MN' ]
-       
- 	#Populate ONOSIp with ips from params 
+      
+        main.ONOSbench.handle.sendline("export TERM=vt100")
+        main.ONOSbench.handle.expect(":~") 	    
+
+        #Populate ONOSIp with ips from params 
         for i in range(1, maxNodes + 1): 
  	    ipString = 'ip' + str(i) 
      	    ONOSIp.append(main.params[ 'CTRL' ][ ipString ]) 
         
-	#kill off all onos processes 
+	    #kill off all onos processes 
         main.log.step("Safety check, killing all ONOS processes")
         main.log.step("before initiating enviornment setup")
         for node in range(1, maxNodes + 1):
@@ -49,11 +53,10 @@
 
         #construct the cell file
         main.log.step("Creating cell file")
-        exec "a = main.ONOSbench.createCellFile"
         cellIp = []
-        for node in range (1, maxNodes + 1):
-            	cellIp.append(ONOSIp[node])
-        a(BENCHIp,cellName,MNip,str(Features), *cellIp)    #'0' as third arg because we are not using mininet
+        for node in range (1, clusterCount + 1):
+            	cellIp.append(ONOSIp[node]) 
+        main.ONOSbench.createCellFile(BENCHIp,cellName,MNip,str(Features), *cellIp)
 
         main.step( "Set Cell" )
         main.ONOSbench.setCell(cellName)
@@ -64,6 +67,14 @@
             main.log.info(" Uninstalling ONOS " + str(i) )
             main.ONOSbench.onosUninstall( ONOSIp[i] )
 
+        myDistribution = []
+        for node in range (1, clusterCount + 1): 
+            myDistribution.append(deviceDistribution[node-1]) 
+
+        main.ONOSbench.createLinkGraphFile( BENCHIp,cellIp,myDistribution) 
+        main.ONOSbench.createNullDevProviderFile( BENCHIp, cellIp, myDistribution) 
+        main.ONOSbench.createNullLinkProviderFile(BENCHIp)
+        
         #git step - skipable 
         main.step( "Git checkout and pull " + checkoutBranch )
         if gitPull == 'on':
@@ -153,8 +164,8 @@
         main.step( "Enviornment setup and verification complete." )
         main.ONOS1cli.startOnosCli( ONOSIp[1] )
         main.step( "ONOS 1 is up and running." )
-	
-
+        main.ONOSbench.handle.expect(":~") #there is a dangling sendline somewhere...	
+    
     def CASE2( self, main ):
         # This case increases the cluster size by whatever scale is
         # Note: 'scale' is the size of the step
@@ -168,18 +179,55 @@
         ''
         import time
         global clusterCount
+    
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        Features= main.params[ 'ENV' ][ 'cellFeatures' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        MNip = main.params[ 'TEST' ][ 'MN' ]        
+        deviceDistribution = (main.params[ 'TEST' ][ 'devicesPerNode']).split(",")
 
         scale = int( main.params[ 'SCALE' ] )
         clusterCount += scale
 
+        main.log.step( "Cleaning Enviornment..." )
+        for i in range(1, maxNodes + 1):
+            main.ONOSbench.onosDie(ONOSIp[i])
+            main.log.info(" Uninstalling ONOS " + str(i) )
+            main.ONOSbench.onosUninstall( ONOSIp[i] )
+
+        myDistribution = []
+        for node in range (1, clusterCount + 1):
+            myDistribution.append(deviceDistribution[node-1])
+
+        main.log.step("Creating cell file")
+        cellIp = []
+        for node in range (1, clusterCount + 1):
+                cellIp.append(ONOSIp[node])
+        main.ONOSbench.createCellFile(BENCHIp,cellName,MNip,str(Features), *cellIp)
+
+        main.ONOSbench.createLinkGraphFile( BENCHIp,cellIp,myDistribution)
+        main.ONOSbench.createNullDevProviderFile( BENCHIp, cellIp, myDistribution)
+        main.ONOSbench.createNullLinkProviderFile(BENCHIp)
+
+        main.step( "Set Cell" )
+        main.ONOSbench.setCell(cellName)
+
         main.log.report( "Increasing cluster size to " + str( clusterCount ) )
-        for node in range((clusterCount - scale) + 1, clusterCount + 1):
-            main.ONOSbench.onosDie(ONOSIp[node])
+        for node in range(1, clusterCount + 1):
             time.sleep(10)
             main.log.info("Starting ONOS " + str(node) + " at IP: " + ONOSIp[node])
             main.ONOSbench.onosInstall( ONOSIp[node] )
             exec "a = main.ONOS%scli.startOnosCli" %str(node)
             a(ONOSIp[node])
+        
+        for node in range(1, clusterCount + 1):
+            for i in range( 2 ):
+                isup = main.ONOSbench.isup( ONOSIp[node] )
+                if isup:
+                    main.log.info("ONOS " + str(node) + " is up\n")
+                    break
+            if not isup:
+                main.log.report( "ONOS " + str(node) + " didn't start!" )
     
     def CASE3( self, main ):   
         import time
@@ -187,16 +235,23 @@
         import string 
         import csv
         import os.path
+        import requests
+        import numpy
 
+        sustainability = float(main.params[ 'TEST' ][ 'linkgraphdif' ])
+        flickerRates = (main.params[ 'TEST' ][ 'flickerRates']).split(",")        
+        homeDir = os.path.expanduser('~')     
 
         linkResult = main.FALSE
         scale = int( main.params[ 'SCALE' ] )
 
         testDelay = main.params[ 'TEST' ][ 'wait']
         time.sleep( float( testDelay ) )
+                
+        for node in range(1, clusterCount + 1): 
+            main.log.info("Writing flicker file to node " + str(node))
+            main.ONOSbench.createNullLinkProviderFile( ONOSIp[node], eventRate=flickerRates[node-1], onNode=True  )     
 
-        metric1 = main.params[ 'TEST' ][ 'metric1' ]
-        metric2 = main.params[ 'TEST' ][ 'metric2' ]
         testDuration = main.params[ 'TEST' ][ 'duration' ]
         stop = time.time() + float( testDuration )
 
@@ -211,33 +266,62 @@
         
         while time.time() < stop:
             time.sleep( float( logInterval ) )
-            for node in range(1, clusterCount+1):
-                exec "a = main.ONOS%scli.topologyEventsMetrics" %str(node)    
-                JsonStr[node] = a()
-                JsonObj[node] = json.loads( JsonStr[node] )
-                msg = ( "Node " + str(node)  +  " Link Event TP: " + str( JsonObj[node][ metric1 ][ 'm1_rate' ] ) )
+            for node in range(1, clusterCount+1):         
+                main.ONOSbench.handle.sendline("""onos $OC1 topology-events-metrics|grep "Topology Link Events"|cut -d ' ' -f7 """)
+                main.ONOSbench.handle.expect(":~") 
+                raw = (main.ONOSbench.handle.before).splitlines() 
+                myresult = "--"
+                for word in raw: 
+                    if "m1" in word: 
+                        myresult = word 
+                        myresult = myresult.replace("m1=","")
+                        break 
+                if myresult == "--": 
+                    main.log.error("Parse error or no data error") 
+                msg = ( "Node " + str(node)  +  " Link Event TP: " + str(myresult) )
                 main.log.info( msg )
-                msg = ( "Node " + str(node) + " Graph Event TP: " + str( JsonObj[node][ metric2 ][ 'm1_rate' ] ) )
+                linkResults[node] = round(float(myresult),2)
+                myLinkRate = round(float(myresult),2)
+
+                main.ONOSbench.handle.sendline("""onos $OC1 topology-events-metrics|grep "Topology Graph Events"|cut -d ' ' -f7 """)
+                main.ONOSbench.handle.expect(":~")
+                raw = (main.ONOSbench.handle.before).splitlines()
+                myresult = "--"
+                for word in raw:
+                    if "m1" in word:
+                        myresult = word
+                        myresult = myresult.replace("m1=","")
+                        break
+                if myresult == "--":
+                    main.log.error("Parse error or no data error")
+                msg = ( "Node " + str(node) + " Graph Event TP: " + str(myresult) )
                 main.log.info( msg )
-               
-                linkResults[node] = round(JsonObj[node][ metric2 ][ 'm1_rate' ],2)
-                graphResults[node] = round(JsonObj[node][ metric1  ][ 'm1_rate' ],2)
+                graphResults[node] = round(float(myresult),2)
+                myGraphRate = round(float(myresult),2)
+                
+                difLinkGraph = float(myLinkRate - myGraphRate)
+                difLinkGraph = numpy.absolute(difLinkGraph)
+                main.log.info("Node " + str(node) + " abs(Link event - Graph event) = " + str(difLinkGraph)) 
+                tempx = numpy.divide(difLinkGraph,float(myLinkRate)) 
+                if tempx > sustainability:
+                    main.log.error("Difference in link event rate and graph event rate above " + str(sustainability) + " tolerance") 
+                print("")
 
         print("")
         print("")
 
-        main.log.info("Final Link Event TP Results on " + str(clusterCount) + " node cluster")
-        main.log.info("_______________________________________________")
+        main.log.report("Final Link Event TP Results on " + str(clusterCount) + " node cluster")
+        main.log.report("_______________________________________________")
         for node in range(1, clusterCount+1):
-            main.log.info("Node " + str(node) + ": " + str(linkResults[node])) 
+            main.log.report("Node " + str(node) + ": " + str(linkResults[node])) 
 
         print("")
         print("")
 
-        main.log.info("Final Graph Event TP Results on " + str(clusterCount) + " node cluster")
-        main.log.info("_______________________________________________")
+        main.log.report("Final Graph Event TP Results on " + str(clusterCount) + " node cluster")
+        main.log.report("_______________________________________________")
         for node in range(1, clusterCount+1):
-            main.log.info("Node " + str(node) + ": " + str(graphResults[node]))           
+            main.log.report("Node " + str(node) + ": " + str(graphResults[node]))           
           
         ################################################################################# 
 				# 	Data Logging
@@ -248,7 +332,7 @@
         flickerRate = main.params[ 'TEST' ][ 'flickerRate']
 
         for node in range (1, clusterCount + 1):
-            logFile.write( str(clusterCount) + "," )
+            # replare ->  logFile.write( str(clusterCount) + "," + flickerNodes + "," )
             logFile.write("'" + "baremetal" + str(node)  + "'," )
             logFile.write( testDuration + "," )
             logFile.write( flickerRate + "," )
diff --git a/TestON/tests/LinkEventTP/LinkEventTP.topo b/TestON/tests/LinkEventTP/LinkEventTP.topo
index 1c48a85..cf5fc94 100644
--- a/TestON/tests/LinkEventTP/LinkEventTP.topo
+++ b/TestON/tests/LinkEventTP/LinkEventTP.topo
@@ -3,7 +3,7 @@
     <COMPONENT>
 
         <ONOSbench>
-            <host>localhost</host>
+            <host>10.128.5.55</host>
             <user>admin</user>
             <password>onos_test</password>
             <type>OnosDriver</type>
@@ -15,7 +15,7 @@
         </ONOSbench>
 
         <ONOS1cli>
-            <host>localhost</host>
+            <host>10.128.5.55</host>
             <user>admin</user>
             <password>onos_test</password>
             <type>OnosCliDriver</type>
@@ -24,7 +24,7 @@
         </ONOS1cli>
 
         <ONOS2cli>
-            <host>localhost</host>
+            <host>10.128.5.55</host>
             <user>admin</user>
             <password>onos_test</password>
             <type>OnosCliDriver</type>
@@ -33,7 +33,7 @@
         </ONOS2cli>
 
         <ONOS3cli>
-            <host>localhost</host>
+            <host>10.128.5.55</host>
             <user>admin</user>
             <password>onos_test</password>
             <type>OnosCliDriver</type>
@@ -42,7 +42,7 @@
         </ONOS3cli>
 
         <ONOS4cli>
-            <host>localhost</host>
+            <host>10.128.5.55</host>
             <user>admin</user>
             <password>onos_test</password>
             <type>OnosCliDriver</type>
@@ -51,7 +51,7 @@
         </ONOS4cli>
 
         <ONOS5cli>
-            <host>localhost</host>
+            <host>10.128.5.55</host>
             <user>admin</user>
             <password>onos_test</password>
             <type>OnosCliDriver</type>
@@ -60,7 +60,7 @@
         </ONOS5cli>
 
 	<ONOS6cli>
-            <host>localhost</host>
+            <host>10.128.5.55</host>
             <user>admin</user>
             <password>onos_test</password>
             <type>OnosCliDriver</type>
@@ -69,7 +69,7 @@
         </ONOS6cli>
 
         <ONOS7cli>
-            <host>localhost</host>
+            <host>10.128.5.55</host>
             <user>admin</user>
             <password>onos_test</password>
             <type>OnosCliDriver</type>
@@ -78,7 +78,7 @@
         </ONOS7cli>
 
         <ONOS1>
-            <host>10.254.1.201</host>
+            <host>10.128.5.51</host>
             <user>sdn</user>
             <password>rocks</password>
             <type>OnosDriver</type>
@@ -87,7 +87,7 @@
         </ONOS1>
 
         <ONOS2>
-            <host>10.254.1.202</host>
+            <host>10.128.5.52</host>
             <user>sdn</user>
             <password>rocks</password>
             <type>OnosDriver</type>
@@ -96,7 +96,7 @@
         </ONOS2>
 
         <ONOS3>
-            <host>10.254.1.203</host>
+            <host>10.128.5.53</host>
             <user>sdn</user>
             <password>rocks</password>
             <type>OnosDriver</type>
@@ -105,7 +105,7 @@
         </ONOS3>
 
         <ONOS4>
-            <host>10.254.1.204</host>
+            <host>10.128.5.54</host>
             <user>sdn</user>
             <password>rocks</password>
             <type>OnosDriver</type>
@@ -115,7 +115,7 @@
 
 	
         <ONOS5>
-            <host>10.254.1.205</host>
+            <host>10.128.5.65</host>
             <user>sdn</user>
             <password>rocks</password>
             <type>OnosDriver</type>
@@ -124,7 +124,7 @@
         </ONOS5>
 
         <ONOS6>
-            <host>10.254.1.206</host>
+            <host>10.128.5.66</host>
             <user>sdn</user>
             <password>rocks</password>
             <type>OnosDriver</type>
@@ -133,7 +133,7 @@
         </ONOS6>
 
         <ONOS7>
-            <host>10.254.1.207</host>
+            <host>10.128.5.67</host>
             <user>sdn</user>
             <password>rocks</password>
             <type>OnosDriver</type>
diff --git a/TestON/tests/LinkEventTP/OLDLinkEventTP.py b/TestON/tests/LinkEventTP/OLDLinkEventTP.py
deleted file mode 100644
index e12befa..0000000
--- a/TestON/tests/LinkEventTP/OLDLinkEventTP.py
+++ /dev/null
@@ -1,348 +0,0 @@
-# ScaleOutTemplate --> LinkEventTp
-#
-# CASE1 starts number of nodes specified in param file
-#
-# cameron@onlab.us
-
-import sys
-import os
-
-
-class LinkEventTP:
-
-    def __init__( self ):
-        self.default = ''
-
-    def CASE1( self, main ):
-        import os.path
-        global clusterCount
-        clusterCount = 1
-
-        checkoutBranch = main.params[ 'GIT' ][ 'checkout' ]
-        gitPull = main.params[ 'GIT' ][ 'autopull' ]
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
-        BENCHUser = main.params[ 'BENCH' ][ 'user' ]
-        ONOS1Ip = main.params[ 'CTRL' ][ 'ip1' ]
-        ONOS2Ip = main.params[ 'CTRL' ][ 'ip2' ]
-        ONOS3Ip = main.params[ 'CTRL' ][ 'ip3' ]
-        flickerRate = main.params[ 'TEST' ][ 'flickerRate']
-        
-
-        main.log.step( "Cleaning Enviornment..." )
-        main.ONOSbench.onosUninstall( ONOS1Ip )
-        main.ONOSbench.onosUninstall( ONOS2Ip )
-        main.ONOSbench.onosUninstall( ONOS3Ip )
-
-        main.step( "Git checkout and pull " + checkoutBranch )
-        if gitPull == 'on':
-            checkoutResult = main.ONOSbench.gitCheckout( checkoutBranch )
-            pullResult = main.ONOSbench.gitPull()
-
-        else:
-            checkoutResult = main.TRUE
-            pullResult = main.TRUE
-            main.log.info( "Skipped git checkout and pull" )
-
-        #mvnResult = main.ONOSbench.cleanInstall()
-
-        main.step( "Set cell for ONOS cli env" )
-        main.ONOS1cli.setCell( cellName )
-        main.ONOS2cli.setCell( cellName )
-        main.ONOS3cli.setCell( cellName )
-        
-        ### configuring file to enable flicker ###
-        main.log.info(" Configuring null provider to enable flicker. Flicker Rate = " + flickerRate ) 
-        homeDir = os.path.expanduser('~')
-        main.log.info(homeDir)
-        localPath = "/ONOS/tools/package/etc/org.onosproject.provider.nil.link.impl.NullLinkProvider.cfg"
-        filePath = homeDir + localPath
-        main.log.info(filePath)
-
-        configFile = open(filePath, 'w+')
-        main.log.info("File opened")
-        configFile.write("# Sample configurations for the NullLinkProvider.\n")
-        configFile.write("# \n")
-        configFile.write("# If enabled, generates LinkDetected and LinkVanished events\n")
-        configFile.write("# to make the link appear to be flapping.\n")
-        configFile.write("#\n")
-        configFile.write("flicker = true\n")
-        configFile.write("#\n")
-        configFile.write("# If enabled, sets the time between LinkEvent generation,\n")
-        configFile.write("# in milliseconds.\n")
-        configFile.write("#\n")
-        configFile.write("eventRate = " + flickerRate)
-        configFile.close()
-        main.log.info("Configuration completed")
-        
-        #############################
-        #config file default topo provider 
-        ###########################
-
-        ### configure deafult topo provider event rate ###??????????????????
-        localPath = main.params[ 'TEST' ][ 'configFile' ]
-        filePath = homeDir + localPath
-        main.log.info(filePath)
-        configFile = open(filePath, 'w+')
-        main.log.info("File Opened")
-        configFile.write("maxEvents = 1\n") 
-        configFile.write("maxIdleMs = 0\n")
-        configFile.write("maxBatchMs = 0\n")
-        main.log.info("File written and closed") 
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.onosPackage()  # no file or directory
-
-        main.step( "Installing ONOS package" )
-        install1Result = main.ONOSbench.onosInstall( node=ONOS1Ip )
-
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-        main.step( "Applying cell file to environment" )
-        cellApplyResult = main.ONOSbench.setCell( cellName )
-        main.step( "verify cells" )
-        verifyCellResult = main.ONOSbench.verifyCell()
-
-        main.step( "Set cell for ONOS cli env" )
-        main.ONOS1cli.setCell( cellName )
-
-        cli1 = main.ONOS1cli.startOnosCli( ONOS1Ip )
-
-    def CASE2( self, main ):
-        """
-        Increase number of nodes and initiate CLI
-        """
-        import time
-        global clusterCount
-
-        ONOS1Ip = main.params[ 'CTRL' ][ 'ip1' ]
-        ONOS2Ip = main.params[ 'CTRL' ][ 'ip2' ]
-        ONOS3Ip = main.params[ 'CTRL' ][ 'ip3' ]
-        #ONOS4Ip = main.params[ 'CTRL' ][ 'ip4' ]
-        #ONOS5Ip = main.params[ 'CTRL' ][ 'ip5' ]
-        #ONOS6Ip = main.params[ 'CTRL' ][ 'ip6' ]
-        #ONOS7Ip = main.params[ 'CTRL' ][ 'ip7' ]
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-        scale = int( main.params[ 'SCALE' ] )
-
-        # Cluster size increased everytime the case is defined
-        clusterCount += scale
-
-        main.log.report( "Increasing cluster size to " +
-                         str( clusterCount ) )
-        installResult = main.FALSE
-
-        if scale == 2:
-            if clusterCount == 3:
-                main.log.info( "Installing nodes 2 and 3" )
-                install2Result = main.ONOSbench.onosInstall( node=ONOS2Ip )
-                install3Result = main.ONOSbench.onosInstall( node=ONOS3Ip )
-                cli2 = main.ONOS2cli.startOnosCli( ONOS2Ip )
-                cli3 = main.ONOS3cli.startOnosCli( ONOS3Ip )
-                installResult = main.TRUE 
-              
-        if scale == 1:
-            if clusterCount == 2:
-                main.log.info( "Installing node 2" )
-                install2Result = main.ONOSbench.onosInstall( node=ONOS2Ip )
-                cli2 = main.ONOS2cli.startOnosCli( ONOS2Ip )
-                installResult = main.TRUE 
-
-            if clusterCount == 3:
-                main.log.info( "Installing node 3" )
-                install3Result = main.ONOSbench.onosInstall( node=ONOS3Ip )
-                cli3 = main.ONOS3cli.startOnosCli( ONOS3Ip )
-                installResult = main.TRUE 
-
-
-    def CASE3( self, main ):
-        import time
-        import json
-        import string
-        import csv
-        
-        linkResult = main.FALSE 
-        
-        testDelay = main.params[ 'TEST' ][ 'wait']
-        time.sleep( float( testDelay ) )
-
-        metric1 = main.params[ 'TEST' ][ 'metric1' ]
-        metric2 = main.params[ 'TEST' ][ 'metric2' ]
-        testDuration = main.params[ 'TEST' ][ 'duration' ]
-        stop = time.time() + float( testDuration )
-    
-        main.ONOS1cli.featureInstall("onos-null")
-
-        msg = ( "Starting test loop for " + str(testDuration) + " seconds" )
-        main.log.info( msg )
-        logInterval = main.params[ 'TEST' ][ 'log_interval' ]
-
-        while time.time() < stop:
-            time.sleep( float( logInterval ) )
-
-            JsonStr1 = main.ONOS1cli.topologyEventsMetrics() 
-            JsonObj1 = json.loads( JsonStr1 ) 
-            msg = ( "Node 1 Link Event TP: " + str( JsonObj1[ metric1  ][ 'm1_rate' ] ) )
-            main.log.info( msg )
-            msg = ( "Node 1 Graph Event TP: " + str( JsonObj1[ metric2  ][ 'm1_rate' ] ) )
-            main.log.info( msg ) 
-            
-            lastGraphRate = round(JsonObj1[ metric2 ][ 'm1_rate' ],2)
-            lastLinkRate = round(JsonObj1[ metric1  ][ 'm1_rate' ],2)
-
-        msg = ( "Final Link Event TP: " + str( lastLinkRate ) ) 
-        main.log.report( msg )
-        msg = ( "Final Graph Event TP: " + str( lastGraphRate ) )
-        main.log.report( msg )
-       
-        linkResult = main.TRUE 
-        '''
-        jenkinsReport = open('LinkEventTP.csv', 'w')
-        jenkinsReport.write("T1 - Node 1, T2 - Node 1, T2 - Node 2, T3 - Node 1, T3 - Node 2, T3 - Node 3\n")
-        jenkinsReport.write(str(lastRate1))
-        jenkinsReport.write("\n")
-        jenkinsReport.close()
-        
-        dbReportS1 = open('LinkEventTP-S1.csv','w')         #must be the name of the test "-S" followed by the scale 
-        dbReportS1.write(str(linkResult))
-        dbReportS1.write("\n")
-        dbReportS1.write(str(lastRate1))
-        dbReportS1.write("\n")                              #additional newline needed for bash script reading
-        dbReportS1.close()
-        '''
-
-
-    def CASE4( self, main ):
-        import time
-        import json
-        import string
-
-        linkResult = main.FALSE
-
-        testDelay = main.params[ 'TEST' ][ 'wait']
-        time.sleep( float( testDelay ) )
-
-        getMetric = main.params[ 'TEST' ][ 'metric1' ]
-        testDuration = main.params[ 'TEST' ][ 'duration' ]
-        stop = time.time() + float( testDuration )
-
-        main.ONOS2cli.featureInstall("onos-null")
-
-        msg = ( "Starting test loop for " + str(testDuration) + " seconds" )
-        main.log.info( msg )
-        logInterval = main.params[ 'TEST' ][ 'log_interval' ]
-
-        while time.time() < stop:
-            time.sleep( float( logInterval ) )
-
-            JsonStr1 = main.ONOS1cli.topologyEventsMetrics() 
-            JsonObj1 = json.loads( JsonStr1 )
-            msg = ( "Node 1 TP: " + str( JsonObj1[ getMetric  ][ 'm1_rate' ] ) )
-            main.log.info( msg )
-            lastRate1 = round(JsonObj1[ getMetric  ][ 'm1_rate' ],2)
-
-
-            JsonStr2 = main.ONOS2cli.topologyEventsMetrics() 
-            JsonObj2 = json.loads( JsonStr2 )
-            msg = ( "Node 2 TP: " + str( JsonObj2[ getMetric  ][ 'm1_rate' ] ) )
-            main.log.info( msg )
-            lastRate2 = round(JsonObj2[ getMetric  ][ 'm1_rate' ],2)
-
-
-        msg = ( "Final TP on node 1: " + str( lastRate1 ) )
-        main.log.report( msg )
-
-        msg = ( "Final TP on node 2: " + str( lastRate2 ) )
-        main.log.report( msg )
-
-        linkResult = main.TRUE
-
-        jenkinsReport = open('LinkEventTP.csv', 'a')
-        jenkinsReport.write(str(lastRate1))
-        jenkinsReport.write(", ")
-        jenkinsReport.write(str(lastRate2))
-        jenkinsReport.write(", ")
-        jenkinsReport.close()
-
-        dbReportS2 = open('LinkEventTP-S2.csv','w')         #must be the name of the test "-S" followed by the scale
-        dbReportS2.write(str(linkResult))
-        dbReportS2.write("\n")
-        dbReportS2.write(str(lastRate1))
-        dbReportS2.write("\n")
-        dbReportS2.write(str(lastRate2))
-        dbReportS2.write("\n")
-        dbReportS2.close()
-
-
-
-    def CASE5( self, main ):
-        import time
-        import json
-        import string
-
-        linkResult = main.FALSE
-
-        testDelay = main.params[ 'TEST' ][ 'wait']
-        time.sleep( float( testDelay ) )
-
-        getMetric = main.params[ 'TEST' ][ 'metric1' ]
-        testDuration = main.params[ 'TEST' ][ 'duration' ]
-        stop = time.time() + float( testDuration )
-
-        main.ONOS3cli.featureInstall("onos-null")
-
-        msg = ( "Starting test loop for " + str(testDuration) + " seconds" )
-        main.log.info( msg )
-        logInterval = main.params[ 'TEST' ][ 'log_interval' ]
-
-        while time.time() < stop:
-            time.sleep( float( logInterval ) )
-
-            JsonStr1 = main.ONOS1cli.topologyEventsMetrics()
-            JsonObj1 = json.loads( JsonStr1 )
-            msg = ( "Node 1 TP: " + str( JsonObj1[ getMetric  ][ 'm1_rate' ] ) )
-            main.log.info( msg )
-            lastRate1 = round(JsonObj1[ getMetric  ][ 'm1_rate' ],2)
-
-            JsonStr2 = main.ONOS2cli.topologyEventsMetrics()
-            JsonObj2 = json.loads( JsonStr2 )
-            msg = ( "Node 2 TP: " + str( JsonObj2[ getMetric  ][ 'm1_rate' ] ) )
-            main.log.info( msg )
-            lastRate2 = round(JsonObj2[ getMetric  ][ 'm1_rate' ],2)
-    
-            JsonStr3 = main.ONOS3cli.topologyEventsMetrics()
-            JsonObj3 = json.loads( JsonStr3 )
-            msg = ( "Node 3 TP: " + str( JsonObj3[ getMetric  ][ 'm1_rate' ] ) )
-            main.log.info( msg )
-            lastRate3 = round(JsonObj3[ getMetric  ][ 'm1_rate' ],2)
-
-        msg = ( "Final TP on node 1: " + str( lastRate1 ) )
-        main.log.report( msg )
-
-        msg = ( "Final TP on node 2: " + str( lastRate2 ) )
-        main.log.report( msg )
-
-        msg = ( "Final TP on node 3: " + str( lastRate3 ) )
-        main.log.report( msg )
-
-        linkResult = main.TRUE
-
-        jenkinsReport = open('LinkEventTP.csv', 'a')
-        jenkinsReport.write(str(lastRate1))
-        jenkinsReport.write(", ")
-        jenkinsReport.write(str(lastRate2))
-        jenkinsReport.write(", ")
-        jenkinsReport.write(str(lastRate3))
-        jenkinsReport.close()
-       
-        dbReportS3 = open('LinkEventTP-S3.csv','w')         #must be the name of the test "-S" followed by the scale
-        dbReportS3.write(str(linkResult))
-        dbReportS3.write("\n")
-        dbReportS3.write(str(lastRate1))
-        dbReportS3.write("\n")
-        dbReportS3.write(str(lastRate2))
-        dbReportS3.write("\n")
-        dbReportS3.write(str(lastRate3))
-        dbReportS3.write("\n")
-        dbReportS3.close() 
-
-
diff --git a/TestON/tests/MultiProd/MultiProd.bak b/TestON/tests/MultiProd/MultiProd.bak
deleted file mode 100755
index 11af10b..0000000
--- a/TestON/tests/MultiProd/MultiProd.bak
+++ /dev/null
@@ -1,1156 +0,0 @@
-
-#Testing the basic functionality of ONOS Next
-#For sanity and driver functionality excercises only.
-
-import time
-import time
-import json
-
-time.sleep(1)
-class MultiProd:
-    def __init__(self):
-        self.default = ''
-
-    def CASE1(self, main):
-        '''
-        Startup sequence:
-        cell <name>
-        onos-verify-cell
-        onos-remove-raft-logs        
-        git pull
-        mvn clean install
-        onos-package
-        onos-install -f
-        onos-wait-for-start
-        '''
-        
-        cell_name = main.params['ENV']['cellName']
-        ONOS1_ip = main.params['CTRL']['ip1']
-        ONOS2_ip = main.params['CTRL']['ip2']
-        ONOS3_ip = main.params['CTRL']['ip3']    
-       
-        main.case("Setting up test environment")
-        main.log.report("This testcase is testing setting up test environment") 
-        main.log.report("__________________________________")
- 
-        main.step("Applying cell variable to environment")
-        cell_result1 = main.ONOSbench.set_cell(cell_name)
-        #cell_result2 = main.ONOScli1.set_cell(cell_name)
-        #cell_result3 = main.ONOScli2.set_cell(cell_name)
-        #cell_result4 = main.ONOScli3.set_cell(cell_name)
-        verify_result = main.ONOSbench.verify_cell() 
-        cell_result = cell_result1
-
-        main.step("Removing raft logs before a clen installation of ONOS")
-        remove_log_Result = main.ONOSbench.onos_remove_raft_logs()        
-
-        main.step("Git checkout and pull master and get version")
-        main.ONOSbench.git_checkout("master")
-        git_pull_result = main.ONOSbench.git_pull()
-        print "git_pull_result = ", git_pull_result
-        main.ONOSbench.get_version(report=True)
-
-        if git_pull_result == 1:
-            main.step("Using mvn clean & install")
-            main.ONOSbench.clean_install()
-
-        main.step("Creating ONOS package")
-        package_result = main.ONOSbench.onos_package()
-
-        #main.step("Creating a cell")
-        #cell_create_result = main.ONOSbench.create_cell_file(**************)
-
-        main.step("Installing ONOS package")
-        onos1_install_result = main.ONOSbench.onos_install(options="-f", node=ONOS1_ip)
-        onos2_install_result = main.ONOSbench.onos_install(options="-f", node=ONOS2_ip)
-        onos3_install_result = main.ONOSbench.onos_install(options="-f", node=ONOS3_ip)
-        onos_install_result = onos1_install_result and onos2_install_result and onos3_install_result        
-        if onos_install_result == main.TRUE:
-            main.log.report("Installing ONOS package successful")
-        else:
-            main.log.report("Installing ONOS package failed")
-        	
-        onos1_isup = main.ONOSbench.isup(ONOS1_ip)
-        onos2_isup = main.ONOSbench.isup(ONOS2_ip)
-        onos3_isup = main.ONOSbench.isup(ONOS3_ip)
-        onos_isup = onos1_isup and onos2_isup and onos3_isup
-        if onos_isup == main.TRUE:
-            main.log.report("ONOS instances are up and ready")
-        else:
-            main.log.report("ONOS instances may not be up")          
-
-        main.step("Starting ONOS service")
-        start_result = main.TRUE
-        #start_result = main.ONOSbench.onos_start(ONOS1_ip)
-        startcli1 = main.ONOScli1.start_onos_cli(ONOS_ip = ONOS1_ip)
-        startcli2 = main.ONOScli2.start_onos_cli(ONOS_ip = ONOS2_ip)
-        startcli3 = main.ONOScli3.start_onos_cli(ONOS_ip = ONOS3_ip)
-        print startcli1
-        print startcli2
-        print startcli3
-            
-        case1_result = (package_result and\
-                cell_result and verify_result and onos_install_result and\
-                onos_isup and start_result )
-        utilities.assert_equals(expect=main.TRUE, actual=case1_result,
-                onpass="Test startup successful",
-                onfail="Test startup NOT successful")
-
-    def CASE11(self, main):
-        '''
-        Cleanup sequence:
-        onos-service <node_ip> stop
-        onos-uninstall
-
-        TODO: Define rest of cleanup
-        
-        '''
-
-      	ONOS1_ip = main.params['CTRL']['ip1']
-        ONOS2_ip = main.params['CTRL']['ip2']
-        ONOS3_ip = main.params['CTRL']['ip3']
-	
-        main.case("Cleaning up test environment")
-
-        main.step("Testing ONOS kill function")
-        kill_result1 = main.ONOSbench.onos_kill(ONOS1_ip)
-        kill_result2 = main.ONOSbench.onos_kill(ONOS2_ip)
-        kill_result3 = main.ONOSbench.onos_kill(ONOS3_ip)
-	
-        main.step("Stopping ONOS service")
-        stop_result1 = main.ONOSbench.onos_stop(ONOS1_ip)
-        stop_result2 = main.ONOSbench.onos_stop(ONOS2_ip)
-        stop_result3 = main.ONOSbench.onos_stop(ONOS3_ip)
-
-        main.step("Uninstalling ONOS service") 
-        uninstall_result = main.ONOSbench.onos_uninstall()
-
-    def CASE3(self, main):
-        '''
-        Test 'onos' command and its functionality in driver
-        '''
-       
-        ONOS1_ip = main.params['CTRL']['ip1']
-        ONOS2_ip = main.params['CTRL']['ip2']
-        ONOS3_ip = main.params['CTRL']['ip3']	
-
-        main.case("Testing 'onos' command")
-
-        main.step("Sending command 'onos -w <onos-ip> system:name'")
-        cmdstr1 = "system:name"
-        cmd_result1 = main.ONOSbench.onos_cli(ONOS1_ip, cmdstr1) 
-        main.log.info("onos command returned: "+cmd_result1)
-        cmd_result2 = main.ONOSbench.onos_cli(ONOS2_ip, cmdstr1)
-        main.log.info("onos command returned: "+cmd_result2)
-        cmd_result3 = main.ONOSbench.onos_cli(ONOS3_ip, cmdstr1)
-        main.log.info("onos command returned: "+cmd_result3)
-
-        main.step("Sending command 'onos -w <onos-ip> onos:topology'")
-        cmdstr2 = "onos:topology"
-        cmd_result4 = main.ONOSbench.onos_cli(ONOS1_ip, cmdstr2)
-        main.log.info("onos command returned: "+cmd_result4)
-        cmd_result5 = main.ONOSbench.onos_cli(ONOS2_ip, cmdstr2)
-        main.log.info("onos command returned: "+cmd_result5)
-        cmd_result6 = main.ONOSbench.onos_cli(ONOS6_ip, cmdstr2)
-        main.log.info("onos command returned: "+cmd_result6)
-
-
-    def CASE4(self, main):
-        import re
-        import time
-        ONOS1_ip = main.params['CTRL']['ip1']
-        ONOS2_ip = main.params['CTRL']['ip2']
-        ONOS3_ip = main.params['CTRL']['ip3']
-        ONOS1_port = main.params['CTRL']['port1']
-        ONOS2_port = main.params['CTRL']['port2']
-        ONOS3_port = main.params['CTRL']['port3']
-        
-        main.log.report("This testcase is testing the assignment of all the switches to all controllers and discovering the hosts in reactive mode")
-        main.log.report("__________________________________")        
-        main.case("Pingall Test(No intents are added)")
-        main.step("Assigning switches to controllers")
-        for i in range(1,29): #1 to (num of switches +1)
-            main.Mininet1.assign_sw_controller(sw=str(i),count=3, 
-                    ip1=ONOS1_ip, port1=ONOS1_port,
-                    ip2=ONOS2_ip, port2=ONOS2_port,
-		            ip3=ONOS3_ip, port3=ONOS3_port)
-
-        switch_mastership = main.TRUE
-        for i in range (1,29):
-            response = main.Mininet1.get_sw_controller("s"+str(i))
-            print("Response is " + str(response))
-            if re.search("tcp:"+ONOS1_ip,response):
-                switch_mastership = switch_mastership and main.TRUE
-            else:
-                switch_mastership = main.FALSE
-
-        if switch_mastership == main.TRUE:
-            main.log.report("Controller assignment successfull")
-        else:
-             main.log.report("Controller assignment failed")
-        #REACTIVE FWD test
-        main.step("Pingall")
-        ping_result = main.FALSE
-        time1 = time.time()
-        ping_result = main.Mininet1.pingall()
-        time2 = time.time()
-        print "Time for pingall: %2f seconds" % (time2 - time1)
-      
-        case4_result = switch_mastership and ping_result
-        if ping_result == main.TRUE:
-            main.log.report("Pingall Test in reactive mode to discover the hosts successful")
-        else:
-            main.log.report("Pingall Test in reactive mode to discover the hosts failed")
-
-        utilities.assert_equals(expect=main.TRUE, actual=case4_result,onpass="Controller assignment and Pingall Test successful",onfail="Controller assignment and Pingall Test NOT successful")
-
-    
-
-    def CASE5(self,main) :
-        import json
-        from subprocess import Popen, PIPE
-        from sts.topology.teston_topology import TestONTopology # assumes that sts is already in you PYTHONPATH
-        ONOS1_ip = main.params['CTRL']['ip1']
-        ONOS2_ip = main.params['CTRL']['ip2']
-        ONOS3_ip = main.params['CTRL']['ip3']
-        
-        main.log.report("This testcase is testing if all ONOS nodes are in topology sync with mininet and its peer ONOS nodes")
-        main.log.report("__________________________________")        
-        main.case ("Testing Mininet topology with the topology of multi instances ONOS") 
-        main.step("Collecting topology information from ONOS")
-        devices1 = main.ONOScli1.devices()
-        devices2 = main.ONOScli2.devices()
-        devices3 = main.ONOScli3.devices()
-        #print "devices1 = ", devices1
-        #print "devices2 = ", devices2
-        #print "devices3 = ", devices3
-        hosts1 = main.ONOScli1.hosts()
-        hosts2 = main.ONOScli2.hosts()
-        hosts3 = main.ONOScli3.hosts()
-        #print "hosts1 = ", hosts1
-        #print "hosts2 = ", hosts2
-        #print "hosts3 = ", hosts3
-        ports1 = main.ONOScli1.ports()
-        ports2 = main.ONOScli2.ports()
-        ports3 = main.ONOScli3.ports()
-        #print "ports1 = ", ports1
-        #print "ports2 = ", ports2    
-        #print "ports3 = ", ports3
-        links1 = main.ONOScli1.links()
-        links2 = main.ONOScli2.links()
-        links3 = main.ONOScli3.links()
-        #print "links1 = ", links1
-        #print "links2 = ", links2
-        #print "links3 = ", links3
-        
-        print "**************"
-        
-        main.step("Start continuous pings")
-        main.Mininet2.pingLong(src=main.params['PING']['source1'],
-                            target=main.params['PING']['target1'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source2'],
-                            target=main.params['PING']['target2'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source3'],
-                            target=main.params['PING']['target3'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source4'],
-                            target=main.params['PING']['target4'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source5'],
-                            target=main.params['PING']['target5'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source6'],
-                            target=main.params['PING']['target6'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source7'],
-                            target=main.params['PING']['target7'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source8'],
-                            target=main.params['PING']['target8'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source9'],
-                            target=main.params['PING']['target9'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source10'],
-                            target=main.params['PING']['target10'],pingTime=500)
-
-        main.step("Create TestONTopology object")
-        global ctrls
-        ctrls = []
-        count = 1
-        while True:
-            temp = ()
-            if ('ip' + str(count)) in main.params['CTRL']:
-                temp = temp + (getattr(main,('ONOS' + str(count))),)
-                temp = temp + ("ONOS"+str(count),)
-                temp = temp + (main.params['CTRL']['ip'+str(count)],)
-                temp = temp + (eval(main.params['CTRL']['port'+str(count)]),)
-                ctrls.append(temp)
-                count = count + 1
-            else:
-                break
-        global MNTopo
-        Topo = TestONTopology(main.Mininet1, ctrls) # can also add Intent API info for intent operations
-        MNTopo = Topo
-
-        Topology_Check = main.TRUE
-        main.step("Compare ONOS Topology to MN Topology")
-        
-        switches_results1 =  main.Mininet1.compare_switches(MNTopo, json.loads(devices1))
-        print "switches_Result1 = ", switches_results1
-        utilities.assert_equals(expect=main.TRUE, actual=switches_results1,
-                onpass="ONOS1 Switches view is correct",
-                onfail="ONOS1 Switches view is incorrect")
-
-        switches_results2 =  main.Mininet1.compare_switches(MNTopo, json.loads(devices2))
-        utilities.assert_equals(expect=main.TRUE, actual=switches_results2,
-                onpass="ONOS2 Switches view is correct",
-                onfail="ONOS2 Switches view is incorrect")
-    
-        switches_results3 =  main.Mininet1.compare_switches(MNTopo, json.loads(devices3))
-        utilities.assert_equals(expect=main.TRUE, actual=switches_results3,
-                onpass="ONOS3 Switches view is correct",
-                onfail="ONOS3 Switches view is incorrect")
-
-        '''
-        ports_results1 =  main.Mininet1.compare_ports(MNTopo, json.loads(ports1))
-        utilities.assert_equals(expect=main.TRUE, actual=ports_results1,
-                onpass="ONOS1 Ports view is correct",
-                onfail="ONOS1 Ports view is incorrect")
-
-        ports_results2 =  main.Mininet1.compare_ports(MNTopo, json.loads(ports2))
-        utilities.assert_equals(expect=main.TRUE, actual=ports_results2,
-                onpass="ONOS2 Ports view is correct",
-                onfail="ONOS2 Ports view is incorrect")
-
-        ports_results3 =  main.Mininet1.compare_ports(MNTopo, json.loads(ports3))
-        utilities.assert_equals(expect=main.TRUE, actual=ports_results3,
-                onpass="ONOS3 Ports view is correct",
-                onfail="ONOS3 Ports view is incorrect")
-        '''        
-
-        links_results1 =  main.Mininet1.compare_links(MNTopo, json.loads(links1))
-        utilities.assert_equals(expect=main.TRUE, actual=links_results1,
-                onpass="ONOS1 Links view is correct",
-                onfail="ONOS1 Links view is incorrect")
-
-        links_results2 =  main.Mininet1.compare_links(MNTopo, json.loads(links2))
-        utilities.assert_equals(expect=main.TRUE, actual=links_results2,
-                onpass="ONOS2 Links view is correct",
-                onfail="ONOS2 Links view is incorrect")
-
-        links_results3 =  main.Mininet1.compare_links(MNTopo, json.loads(links3))
-        utilities.assert_equals(expect=main.TRUE, actual=links_results3,
-                onpass="ONOS2 Links view is correct",
-                onfail="ONOS2 Links view is incorrect")
-
-        #topo_result = switches_results1 and switches_results2 and switches_results3\
-                #and ports_results1 and ports_results2 and ports_results3\
-                #and links_results1 and links_results2 and links_results3
-        
-        topo_result = switches_results1 and switches_results2 and switches_results3\
-                and links_results1 and links_results2 and links_results3
-
-        if topo_result == main.TRUE:
-            main.log.report("Topology Check Test with mininet and ONOS instances successful")
-        else:
-            main.log.report("Topology Check Test with mininet and ONOS instances failed")
-
-        utilities.assert_equals(expect=main.TRUE, actual=topo_result,
-                onpass="Topology Check Test successful",
-                onfail="Topology Check Test NOT successful")
-
-
-
-
-    def CASE10(self):
-        main.log.report("This testcase uninstalls the reactive forwarding app")
-        main.log.report("__________________________________")
-        main.case("Uninstalling reactive forwarding app")
-        #Unistall onos-app-fwd app to disable reactive forwarding
-        appUninstall_result1 = main.ONOScli1.feature_uninstall("onos-app-fwd")
-        appUninstall_result2 = main.ONOScli2.feature_uninstall("onos-app-fwd")
-        appUninstall_result3 = main.ONOScli3.feature_uninstall("onos-app-fwd")
-        main.log.info("onos-app-fwd uninstalled")
-
-        #After reactive forwarding is disabled, the reactive flows on switches timeout in 10-15s
-        #So sleep for 15s
-        time.sleep(15)
-        
-        hosts = main.ONOScli1.hosts()
-        main.log.info(hosts)
-        
-        case10_result = appUninstall_result1 and appUninstall_result2 and appUninstall_result3
-        utilities.assert_equals(expect=main.TRUE, actual=case10_result,onpass="Reactive forwarding app uninstallation successful",onfail="Reactive forwarding app uninstallation failed")
-
-
-    def CASE6(self):
-        main.log.report("This testcase is testing the addition of host intents and then doing pingall")
-        main.log.report("__________________________________")        
-        main.case("Obtaining hostsfor adding host intents")
-        main.step("Get hosts")
-        hosts = main.ONOScli1.hosts()
-        main.log.info(hosts)
-
-        main.step("Get all devices id")
-        devices_id_list = main.ONOScli1.get_all_devices_id()
-        main.log.info(devices_id_list) 
-
-        #ONOS displays the hosts in hex format unlike mininet which does in decimal format
-        #So take care while adding intents
-        
-        '''
-        main.step("Add host intents for mn hosts(h8-h18,h9-h19,h10-h20,h11-h21,h12-h22,h13-h23,h14-h24,h15-h25,h16-h26,h17-h27)")
-        hth_intent_result = main.ONOScli1.add_host_intent("00:00:00:00:00:08/-1", "00:00:00:00:00:12/-1")
-        hth_intent_result = main.ONOScli1.add_host_intent("00:00:00:00:00:09/-1", "00:00:00:00:00:13/-1")
-        hth_intent_result = main.ONOScli1.add_host_intent("00:00:00:00:00:0A/-1", "00:00:00:00:00:14/-1")
-        hth_intent_result = main.ONOScli1.add_host_intent("00:00:00:00:00:0B/-1", "00:00:00:00:00:15/-1")
-        hth_intent_result = main.ONOScli1.add_host_intent("00:00:00:00:00:0C/-1", "00:00:00:00:00:16/-1")
-        hth_intent_result = main.ONOScli1.add_host_intent("00:00:00:00:00:0D/-1", "00:00:00:00:00:17/-1")
-        hth_intent_result = main.ONOScli1.add_host_intent("00:00:00:00:00:0E/-1", "00:00:00:00:00:18/-1")
-        hth_intent_result = main.ONOScli1.add_host_intent("00:00:00:00:00:0F/-1", "00:00:00:00:00:19/-1")
-        hth_intent_result = main.ONOScli1.add_host_intent("00:00:00:00:00:10/-1", "00:00:00:00:00:1A/-1")
-        hth_intent_result = main.ONOScli1.add_host_intent("00:00:00:00:00:11/-1", "00:00:00:00:00:1B/-1") 
-        '''
-
-        for i in range(8,18):
-            main.log.info("Adding host intent between h"+str(i)+" and h"+str(i+10))
-            host1 =  "00:00:00:00:00:" + str(hex(i)[2:]).zfill(2).upper()
-            host2 =  "00:00:00:00:00:" + str(hex(i+10)[2:]).zfill(2).upper()
-            #NOTE: get host can return None
-            #TODO: handle this
-            host1_id = main.ONOScli1.get_host(host1)['id']
-            host2_id = main.ONOScli1.get_host(host2)['id']
-            tmp_result = main.ONOScli1.add_host_intent(host1_id, host2_id )
-
-        flowHandle = main.ONOScli1.flows()
-        #print "flowHandle = ", flowHandle
-        main.log.info("flows:" +flowHandle)
-
-        count = 1
-        i = 8
-        Ping_Result = main.TRUE
-        while i <18 :
-            main.log.info("\n\nh"+str(i)+" is Pinging h" + str(i+10))
-            ping = main.Mininet1.pingHost(src="h"+str(i),target="h"+str(i+10))
-            if ping == main.FALSE and count <5:
-                count+=1
-                #i = 8
-                Ping_Result = main.FALSE
-                main.log.report("Ping between h" + str(i) + " and h" + str(i+10) + " failed. Making attempt number "+str(count) + " in 2 seconds")
-                time.sleep(2)
-            elif ping==main.FALSE:
-                main.log.report("All ping attempts between h" + str(i) + " and h" + str(i+10) +"have failed")
-                i=19
-                Ping_Result = main.FALSE
-            elif ping==main.TRUE:
-                main.log.info("Ping test between h" + str(i) + " and h" + str(i+10) + "passed!")
-                i+=1
-                Ping_Result = main.TRUE
-            else:
-                main.log.info("Unknown error")
-                Ping_Result = main.ERROR
-        if Ping_Result==main.FALSE:
-            main.log.report("Host intents have not ben installed correctly. Cleaning up")
-            #main.cleanup()
-            #main.exit()
-        if Ping_Result==main.TRUE:
-            main.log.report("Host intents have been installed correctly")
-
-        case6_result = Ping_Result
-        utilities.assert_equals(expect=main.TRUE, actual=case6_result,
-                onpass="Host intent addition and Pingall Test successful",
-                onfail="Host intent addition and Pingall Test NOT successful")
-
-
-    def CASE7 (self,main):
-       
-        ONOS1_ip = main.params['CTRL']['ip1']
-
-        link_sleep = int(main.params['timers']['LinkDiscovery'])
-
-        main.log.report("This testscase is killing a link to ensure that link discovery is consistent")
-        main.log.report("__________________________________")        
-        main.case("Killing a link to Ensure that Link Discovery is Working Properly")
-        main.step("Start continuous pings")
-       
-        main.Mininet2.pingLong(src=main.params['PING']['source1'],
-                            target=main.params['PING']['target1'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source2'],
-                            target=main.params['PING']['target2'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source3'],
-                            target=main.params['PING']['target3'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source4'],
-                            target=main.params['PING']['target4'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source5'],
-                            target=main.params['PING']['target5'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source6'],
-                            target=main.params['PING']['target6'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source7'],
-                            target=main.params['PING']['target7'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source8'],
-                            target=main.params['PING']['target8'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source9'],
-                            target=main.params['PING']['target9'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source10'],
-                            target=main.params['PING']['target10'],pingTime=500)
-
-
-        main.step("Determine the current number of switches and links")
-        topology_output = main.ONOScli1.topology()
-        topology_result = main.ONOSbench.get_topology(topology_output)
-        activeSwitches = topology_result['devices']
-        links = topology_result['links']
-        print "activeSwitches = ", type(activeSwitches)
-        print "links = ", type(links)
-        main.log.info("Currently there are %s switches and %s links"  %(str(activeSwitches), str(links)))
-
-        main.step("Kill Link between s3 and s28")
-        main.Mininet1.link(END1="s3",END2="s28",OPTION="down")
-        time.sleep(link_sleep)
-        topology_output = main.ONOScli2.topology()
-        Link_Down = main.ONOSbench.check_status(topology_output,activeSwitches,str(int(links)-2))
-        if Link_Down == main.TRUE:
-            main.log.report("Link Down discovered properly")
-        utilities.assert_equals(expect=main.TRUE,actual=Link_Down,
-                onpass="Link Down discovered properly",
-                onfail="Link down was not discovered in "+ str(link_sleep) + " seconds")
-        
-        main.step("Bring link between s3 and s28 back up")
-        Link_Up = main.Mininet1.link(END1="s3",END2="s28",OPTION="up")
-        time.sleep(link_sleep)
-        topology_output = main.ONOScli2.topology()
-        Link_Up = main.ONOSbench.check_status(topology_output,activeSwitches,str(links))
-        if Link_Up == main.TRUE:
-            main.log.report("Link up discovered properly")
-        utilities.assert_equals(expect=main.TRUE,actual=Link_Up,
-                onpass="Link up discovered properly",
-                onfail="Link up was not discovered in "+ str(link_sleep) + " seconds")
-
-        main.step("Compare ONOS Topology to MN Topology")
-        main.case ("Testing Mininet topology with the topology of multi instances ONOS") 
-        main.step("Collecting topology information from ONOS")
-        devices1 = main.ONOScli1.devices()
-        devices2 = main.ONOScli2.devices()
-        devices3 = main.ONOScli3.devices()
-        print "devices1 = ", devices1
-        print "devices2 = ", devices2
-        print "devices3 = ", devices3
-        hosts1 = main.ONOScli1.hosts()
-        hosts2 = main.ONOScli2.hosts()
-        hosts3 = main.ONOScli3.hosts()
-        #print "hosts1 = ", hosts1
-        #print "hosts2 = ", hosts2
-        #print "hosts3 = ", hosts3
-        ports1 = main.ONOScli1.ports()
-        ports2 = main.ONOScli2.ports()
-        ports3 = main.ONOScli3.ports()
-        #print "ports1 = ", ports1
-        #print "ports2 = ", ports2    
-        #print "ports3 = ", ports3
-        links1 = main.ONOScli1.links()
-        links2 = main.ONOScli2.links()
-        links3 = main.ONOScli3.links()
-        #print "links1 = ", links1
-        #print "links2 = ", links2
-        #print "links3 = ", links3
-        
-        print "**************"
-        
-        main.step("Start continuous pings")
-        main.Mininet2.pingLong(src=main.params['PING']['source1'],
-                            target=main.params['PING']['target1'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source2'],
-                            target=main.params['PING']['target2'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source3'],
-                            target=main.params['PING']['target3'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source4'],
-                            target=main.params['PING']['target4'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source5'],
-                            target=main.params['PING']['target5'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source6'],
-                            target=main.params['PING']['target6'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source7'],
-                            target=main.params['PING']['target7'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source8'],
-                            target=main.params['PING']['target8'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source9'],
-                            target=main.params['PING']['target9'],pingTime=500)
-        main.Mininet2.pingLong(src=main.params['PING']['source10'],
-                            target=main.params['PING']['target10'],pingTime=500)
-
-        main.step("Create TestONTopology object")
-        global ctrls
-        ctrls = []
-        count = 1
-        while True:
-            temp = ()
-            if ('ip' + str(count)) in main.params['CTRL']:
-                temp = temp + (getattr(main,('ONOS' + str(count))),)
-                temp = temp + ("ONOS"+str(count),)
-                temp = temp + (main.params['CTRL']['ip'+str(count)],)
-                temp = temp + (eval(main.params['CTRL']['port'+str(count)]),)
-                ctrls.append(temp)
-                count = count + 1
-            else:
-                break
-        global MNTopo
-        Topo = TestONTopology(main.Mininet1, ctrls) # can also add Intent API info for intent operations
-        MNTopo = Topo
-
-        Topology_Check = main.TRUE
-        main.step("Compare ONOS Topology to MN Topology")
-        
-        switches_results1 =  main.Mininet1.compare_switches(MNTopo, json.loads(devices1))
-        print "switches_Result1 = ", switches_results1
-        utilities.assert_equals(expect=main.TRUE, actual=switches_results1,
-                onpass="ONOS1 Switches view is correct",
-                onfail="ONOS1 Switches view is incorrect")
-
-        switches_results2 =  main.Mininet1.compare_switches(MNTopo, json.loads(devices2))
-        utilities.assert_equals(expect=main.TRUE, actual=switches_results2,
-                onpass="ONOS2 Switches view is correct",
-                onfail="ONOS2 Switches view is incorrect")
-    
-        switches_results3 =  main.Mininet1.compare_switches(MNTopo, json.loads(devices3))
-        utilities.assert_equals(expect=main.TRUE, actual=switches_results3,
-                onpass="ONOS3 Switches view is correct",
-                onfail="ONOS3 Switches view is incorrect")
-
-        '''
-        ports_results1 =  main.Mininet1.compare_ports(MNTopo, json.loads(ports1))
-        utilities.assert_equals(expect=main.TRUE, actual=ports_results1,
-                onpass="ONOS1 Ports view is correct",
-                onfail="ONOS1 Ports view is incorrect")
-
-        ports_results2 =  main.Mininet1.compare_ports(MNTopo, json.loads(ports2))
-        utilities.assert_equals(expect=main.TRUE, actual=ports_results2,
-                onpass="ONOS2 Ports view is correct",
-                onfail="ONOS2 Ports view is incorrect")
-
-        ports_results3 =  main.Mininet1.compare_ports(MNTopo, json.loads(ports3))
-        utilities.assert_equals(expect=main.TRUE, actual=ports_results3,
-                onpass="ONOS3 Ports view is correct",
-                onfail="ONOS3 Ports view is incorrect")
-        '''        
-
-        links_results1 =  main.Mininet1.compare_links(MNTopo, json.loads(links1))
-        utilities.assert_equals(expect=main.TRUE, actual=links_results1,
-                onpass="ONOS1 Links view is correct",
-                onfail="ONOS1 Links view is incorrect")
-
-        links_results2 =  main.Mininet1.compare_links(MNTopo, json.loads(links2))
-        utilities.assert_equals(expect=main.TRUE, actual=links_results2,
-                onpass="ONOS2 Links view is correct",
-                onfail="ONOS2 Links view is incorrect")
-
-        links_results3 =  main.Mininet1.compare_links(MNTopo, json.loads(links3))
-        utilities.assert_equals(expect=main.TRUE, actual=links_results3,
-                onpass="ONOS2 Links view is correct",
-                onfail="ONOS2 Links view is incorrect")
-               
-        #topo_result = switches_results1 and switches_results2 and switches_results3\
-                #and ports_results1 and ports_results2 and ports_results3\
-                #and links_results1 and links_results2 and links_results3
-        
-        topo_result = switches_results1 and switches_results2 and switches_results3\
-                and links_results1 and links_results2 and links_results3
-
-        utilities.assert_equals(expect=main.TRUE, actual=topo_result and Link_Up and Link_Down,
-                onpass="Topology Check Test successful",
-                onfail="Topology Check Test NOT successful")
-
-
-    def CASE8(self):
-        '''
-        Intent removal
-        ''' 
-        main.log.report("This testcase removes host any previously added intents")
-        main.log.report("__________________________________")        
-        main.log.info("Removing any previously installed intents")
-        main.case("Removing intents")
-        main.step("Obtain the intent id's")
-        intent_result = main.ONOScli1.intents(json_format = False)
-        
-        intent_linewise = intent_result.split("\n")
-        intentList = []
-        for line in intent_linewise:
-            if line.startswith("id="):
-                intentList.append(line)
-
-        intentids = []
-        for line in intentList:
-            intentids.append(line.split(",")[0].split("=")[1])
-        for id in intentids:
-            main.log.info("id = " +id)
-
-        main.step("Iterate through the intentids list and remove each intent")
-        for id in intentids:
-            main.ONOScli1.remove_intent(intent_id = id)
-
-        intent_result = main.ONOScli1.intents(json_format = False)
-        main.log.info("intent_result = " +intent_result)
-        case8_result = main.TRUE
-        
-        i = 8
-        Ping_Result = main.TRUE
-        while i <18 :
-            main.log.info("\n\nh"+str(i)+" is Pinging h" + str(i+10))
-            ping = main.Mininet1.pingHost(src="h"+str(i),target="h"+str(i+10))
-            if ping==main.TRUE:
-                i = 19
-                Ping_Result = main.TRUE
-            elif ping==main.FALSE:
-                i+=1
-                Ping_Result = main.FALSE
-            else:
-                main.log.info("Unknown error")
-                Ping_Result = main.ERROR
-        
-        #Note: If the ping result failed, that means the intents have been withdrawn correctly.
-        if Ping_Result==main.TRUE:
-            main.log.report("Host intents have not been withdrawn correctly")
-            #main.cleanup()
-            #main.exit()
-        if Ping_Result==main.FALSE:
-            main.log.report("Host intents have been withdrawn correctly")
-
-        case8_result = case8_result and Ping_Result
-
-        if case8_result == main.FALSE:
-            main.log.report("Intent removal successful")
-        else:
-            main.log.report("Intent removal failed")
-                        
-        utilities.assert_equals(expect=main.FALSE, actual=case8_result,
-                onpass="Intent removal test failed",
-                onfail="Intent removal test successful")
-             
-
-    def CASE9(self):
-        '''
-        This test case adds point intents. Make sure you run test case 8 which is host intent removal before executing this test case.
-        Else the host intent's flows will persist on switches and the pings would work even if there is some issue with the point intent's flows
-        '''
-        main.log.report("This testcase adds point intents and then does pingall")
-        main.log.report("__________________________________")        
-        main.log.info("Adding point intents")
-        main.case("Adding bidirectional point for mn hosts(h8-h18,h9-h19,h10-h20,h11-h21,h12-h22,h13-h23,h14-h24,h15-h25,h16-h26,h17-h27)") 
-        main.step("Add point-to-point intents for mininet hosts h8 and h18 or ONOS hosts h8 and h12")
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000003008/1", "of:0000000000006018/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-       
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000006018/1", "of:0000000000003008/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-       
-        main.step("Add point-to-point intents for mininet hosts h9 and h19 or ONOS hosts h9 and h13")
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000003009/1", "of:0000000000006019/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-       
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000006019/1", "of:0000000000003009/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-        
-        main.step("Add point-to-point intents for mininet hosts h10 and h20 or ONOS hosts hA and h14")
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000003010/1", "of:0000000000006020/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-       
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000006020/1", "of:0000000000003010/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-
-        main.step("Add point-to-point intents for mininet hosts h11 and h21 or ONOS hosts hB and h15")
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000003011/1", "of:0000000000006021/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-       
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000006021/1", "of:0000000000003011/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-            
-        main.step("Add point-to-point intents for mininet hosts h12 and h22 or ONOS hosts hC and h16")
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000003012/1", "of:0000000000006022/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-       
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000006022/1", "of:0000000000003012/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-            
-        main.step("Add point-to-point intents for mininet hosts h13 and h23 or ONOS hosts hD and h17")
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000003013/1", "of:0000000000006023/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-       
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000006023/1", "of:0000000000003013/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-
-        main.step("Add point-to-point intents for mininet hosts h14 and h24 or ONOS hosts hE and h18")
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000003014/1", "of:0000000000006024/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-       
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000006024/1", "of:0000000000003014/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-            
-        main.step("Add point-to-point intents for mininet hosts h15 and h25 or ONOS hosts hF and h19")
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000003015/1", "of:0000000000006025/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-       
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000006025/1", "of:0000000000003015/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-            
-        main.step("Add point-to-point intents for mininet hosts h16 and h26 or ONOS hosts h10 and h1A")
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000003016/1", "of:0000000000006026/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-       
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000006026/1", "of:0000000000003016/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-
-
-        main.step("Add point-to-point intents for mininet hosts h17 and h27 or ONOS hosts h11 and h1B")
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000003017/1", "of:0000000000006027/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-       
-        ptp_intent_result = main.ONOScli1.add_point_intent("of:0000000000006027/1", "of:0000000000003017/1")
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info("Point to point intent install successful")
-            #main.log.info(get_intent_result)
-
-        print("_______________________________________________________________________________________")
-
-        flowHandle = main.ONOScli1.flows()
-        #print "flowHandle = ", flowHandle
-        main.log.info("flows :" + flowHandle)        
-
-        count = 1
-        i = 8
-        Ping_Result = main.TRUE
-        while i <18 :
-            main.log.info("\n\nh"+str(i)+" is Pinging h" + str(i+10))
-            ping = main.Mininet1.pingHost(src="h"+str(i),target="h"+str(i+10))
-            if ping == main.FALSE and count <5:
-                count+=1
-                #i = 8
-                Ping_Result = main.FALSE
-                main.log.report("Ping between h" + str(i) + " and h" + str(i+10) + " failed. Making attempt number "+str(count) + " in 2 seconds")
-                time.sleep(2)
-            elif ping==main.FALSE:
-                main.log.report("All ping attempts between h" + str(i) + " and h" + str(i+10) +"have failed")
-                i=19
-                Ping_Result = main.FALSE
-            elif ping==main.TRUE:
-                main.log.info("Ping test between h" + str(i) + " and h" + str(i+10) + "passed!")
-                i+=1
-                Ping_Result = main.TRUE
-            else:
-                main.log.info("Unknown error")
-                Ping_Result = main.ERROR
-        if Ping_Result==main.FALSE:
-            main.log.report("Ping all test after Point intents addition failed. Cleaning up")
-            #main.cleanup()
-            #main.exit()
-        if Ping_Result==main.TRUE:
-            main.log.report("Ping all test after Point intents addition successful")
-
-        case8_result = Ping_Result
-        utilities.assert_equals(expect=main.TRUE, actual=case8_result,
-                onpass="Ping all test after Point intents addition successful",
-                onfail="Ping all test after Point intents addition failed")
-
-    def CASE31(self):
-        ''' 
-            This test case adds point intent related to SDN-IP matching on ICMP (ethertype=IPV4, ipProto=1)
-        '''
-        import json
-
-        main.log.report("This test case adds point intent related to SDN-IP matching on ICMP")
-        main.case("Adding bidirectional point intent related to SDN-IP matching on ICMP")
-        main.step("Adding bidirectional point intent")
-        #add-point-intent --ipSrc=10.0.0.8/32 --ipDst=10.0.0.18/32 --ethType=IPV4 --ipProto=1  of:0000000000003008/1 of:0000000000006018/1
-        
-        hosts_json = json.loads(main.ONOScli1.hosts())
-        for  i in range(8,11):
-            main.log.info("Adding point intent between h"+str(i)+" and h"+str(i+10))
-            host1 =  "00:00:00:00:00:" + str(hex(i)[2:]).zfill(2).upper()
-            host2 =  "00:00:00:00:00:" + str(hex(i+10)[2:]).zfill(2).upper()
-            host1_id = main.ONOScli1.get_host(host1)['id']
-            host2_id = main.ONOScli1.get_host(host2)['id']
-            for host in hosts_json:
-                if host['id'] == host1_id:
-                    ip1 = host['ips'][0]
-                    ip1 = str(ip1+"/32")
-                    device1 = host['location']['device']
-                    device1 = str(device1+"/1")
-                elif host['id'] == host2_id:
-                    ip2 = str(host['ips'][0])+"/32"
-                    device2 = host['location']["device"]
-                    device2 = str(device2+"/1")
-                
-            p_intent_result1 = main.ONOScli1.add_point_intent(ingress_device=device1, egress_device=device2, ipSrc=ip1, ipDst=ip2,
-                                  ethType=main.params['SDNIP']['ethType'], ipProto=main.params['SDNIP']['icmpProto'])
-            
-            get_intent_result = main.ONOScli1.intents(json_format = False)
-            main.log.info(get_intent_result)
- 
-            p_intent_result2 = main.ONOScli1.add_point_intent(ingress_device=device2, egress_device=device1, ipSrc=ip2, ipDst=ip1, 
-                                  ethType=main.params['SDNIP']['ethType'], ipProto=main.params['SDNIP']['icmpProto']) 
-            
-            get_intent_result = main.ONOScli1.intents(json_format = False)
-            main.log.info(get_intent_result)
-            if (p_intent_result1 and p_intent_result2) == main.TRUE:
-                #get_intent_result = main.ONOScli1.intents()
-                #main.log.info(get_intent_result)
-                main.log.info("Point intent related to SDN-IP matching on ICMP install successful")
-       
-        time.sleep(15) 
-        get_intent_result = main.ONOScli1.intents(json_format = False)
-        main.log.info("intents = "+ get_intent_result)
-        get_flows_result = main.ONOScli1.flows()
-        main.log.info("flows = " + get_flows_result)
-        
-        count = 1
-        i = 8
-        Ping_Result = main.TRUE
-        while i <11 :
-            main.log.info("\n\nh"+str(i)+" is Pinging h" + str(i+10))
-            ping = main.Mininet1.pingHost(src="h"+str(i),target="h"+str(i+10))
-            if ping == main.FALSE and count <3:
-                count+=1
-                #i = 8
-                Ping_Result = main.FALSE
-                main.log.report("Ping between h" + str(i) + " and h" + str(i+10) + " failed. Making attempt number "+str(count) + " in 2 seconds")
-                time.sleep(2)
-            elif ping==main.FALSE:
-                main.log.report("All ping attempts between h" + str(i) + " and h" + str(i+10) +"have failed")
-                i=19
-                Ping_Result = main.FALSE
-            elif ping==main.TRUE:
-                main.log.info("Ping test between h" + str(i) + " and h" + str(i+10) + "passed!")
-                i+=1
-                Ping_Result = main.TRUE
-            else:
-                main.log.info("Unknown error")
-                Ping_Result = main.ERROR
-        if Ping_Result==main.FALSE:
-            main.log.report("Ping test after Point intents related to SDN-IP matching on ICMP failed.")
-            #main.cleanup()
-            #main.exit()
-        if Ping_Result==main.TRUE:
-            main.log.report("Ping all test after Point intents related to SDN-IP matching on ICMP successful")
-                   
-        case31_result = Ping_Result and p_intent_result1 and p_intent_result2
-        utilities.assert_equals(expect=main.TRUE, actual=case31_result,
-                onpass="Point intent related to SDN-IP matching on ICMP and ping test successful",
-                onfail="Point intent related to SDN-IP matching on ICMP and ping test failed")
-   
-    def CASE32(self):
-        ''' 
-            This test case adds point intent related to SDN-IP matching on TCP (ethertype=IPV4, ipProto=6, DefaultPort for iperf=5001)
-            Note: Although BGP port is 179, we are using 5001 because iperf is used for verifying and iperf's default port is 5001
-        '''
-        import json
-
-        main.log.report("This test case adds point intent related to SDN-IP matching on TCP")
-        main.case("Adding bidirectional point intent related to SDN-IP matching on TCP")
-        main.step("Adding bidirectional point intent")
-        """
-        add-point-intent --ipSrc=10.0.0.8/32 --ipDst=10.0.0.18/32 --ethType=IPV4 --ipProto=6 --tcpDst=5001  of:0000000000003008/1 of:0000000000006018/1
-
-        add-point-intent --ipSrc=10.0.0.18/32 --ipDst=10.0.0.8/32 --ethType=IPV4 --ipProto=6 --tcpDst=5001  of:0000000000006018/1 of:0000000000003008/1
-    
-        add-point-intent --ipSrc=10.0.0.8/32 --ipDst=10.0.0.18/32 --ethType=IPV4 --ipProto=6 --tcpSrc=5001  of:0000000000003008/1 of:0000000000006018/1
-
-        add-point-intent --ipSrc=10.0.0.18/32 --ipDst=10.0.0.8/32 --ethType=IPV4 --ipProto=6 --tcpSrc=5001  of:0000000000006018/1 of:0000000000003008/1
-
-        """           
-    
-        hosts_json = json.loads(main.ONOScli1.hosts())
-        for  i in range(8,9):
-            main.log.info("Adding point intent between h"+str(i)+" and h"+str(i+10))
-            host1 =  "00:00:00:00:00:" + str(hex(i)[2:]).zfill(2).upper()
-            host2 =  "00:00:00:00:00:" + str(hex(i+10)[2:]).zfill(2).upper()
-            host1_id = main.ONOScli1.get_host(host1)['id']
-            host2_id = main.ONOScli1.get_host(host2)['id']
-            for host in hosts_json:
-                if host['id'] == host1_id:
-                    ip1 = host['ips'][0]
-                    ip1 = str(ip1+"/32")
-                    device1 = host['location']['device']
-                    device1 = str(device1+"/1")
-                elif host['id'] == host2_id:
-                    ip2 = str(host['ips'][0])+"/32"
-                    device2 = host['location']["device"]
-                    device2 = str(device2+"/1")
-                
-            p_intent_result1 = main.ONOScli1.add_point_intent(ingress_device=device1, egress_device=device2, ipSrc=ip1, ipDst=ip2,
-                                  ethType=main.params['SDNIP']['ethType'], ipProto=main.params['SDNIP']['tcpProto'], tcpDst=main.params['SDNIP']['dstPort']) 
-            p_intent_result2 = main.ONOScli1.add_point_intent(ingress_device=device2, egress_device=device1, ipSrc=ip2, ipDst=ip1, 
-                                  ethType=main.params['SDNIP']['ethType'], ipProto=main.params['SDNIP']['tcpProto'], tcpDst=main.params['SDNIP']['dstPort'])
-
-            p_intent_result3 = main.ONOScli1.add_point_intent(ingress_device=device1, egress_device=device2, ipSrc=ip1, ipDst=ip2,
-                                  ethType=main.params['SDNIP']['ethType'], ipProto=main.params['SDNIP']['tcpProto'], tcpSrc=main.params['SDNIP']['srcPort'])
-            p_intent_result4 = main.ONOScli1.add_point_intent(ingress_device=device2, egress_device=device1, ipSrc=ip2, ipDst=ip1,
-                                  ethType=main.params['SDNIP']['ethType'], ipProto=main.params['SDNIP']['tcpProto'], tcpSrc=main.params['SDNIP']['srcPort']) 
-
-            p_intent_result = p_intent_result1 and p_intent_result2 and p_intent_result3 and p_intent_result4
-            if p_intent_result ==main.TRUE:
-                get_intent_result = main.ONOScli1.intents(json_format = False)
-                main.log.info(get_intent_result)
-                main.log.info("Point intent related to SDN-IP matching on TCP install successful")
-        
-        iperf_result = main.Mininet1.iperf('h8', 'h18') 
-        if iperf_result == main.TRUE:
-            main.log.report("iperf test successful")
-        else:
-            main.log.report("iperf test failed")
-
-
-        case32_result = p_intent_result and iperf_result
-        utilities.assert_equals(expect=main.TRUE, actual=case32_result,
-                onpass="Ping all test after Point intents addition related to SDN-IP on TCP match successful",
-                onfail="Ping all test after Point intents addition related to SDN-IP on TCP match failed")
-
-
-    def CASE33(self):
-        ''' 
-            This test case adds multipoint to singlepoint  intent related to SDN-IP matching on destination ip and the action is to rewrite the mac address 
-            Here the mac address to be rewritten is the mac address of the egress device
-        '''
-        import json
-        import time
-
-        main.log.report("This test case adds multipoint to singlepoint intent related to SDN-IP matching on destination ip and rewrite mac address action")
-        main.case("Adding multipoint to singlepoint intent related to SDN-IP matching on destination ip")
-        main.step("Adding bidirectional multipoint to singlepoint intent")
-        """
-        add-multi-to-single-intent --ipDst=10.0.3.0/24 --setEthDst=00:00:00:00:00:12 of:0000000000003008/1 0000000000003009/1 of:0000000000006018/1
-        
-        add-multi-to-single-intent --ipDst=10.0.1.0/24 --setEthDst=00:00:00:00:00:08 of:0000000000006018/1 0000000000003009/1 of:0000000000003008/1 
-        """    
-        
-        main.case("Installing multipoint to single point intent with rewrite mac address")
-        main.step("Uninstalling proxy arp app")
-        #Unistall onos-app-proxyarp app to disable reactive forwarding
-        appUninstall_result1 = main.ONOScli1.feature_uninstall("onos-app-proxyarp")
-        appUninstall_result2 = main.ONOScli2.feature_uninstall("onos-app-proxyarp")
-        appUninstall_result3 = main.ONOScli3.feature_uninstall("onos-app-proxyarp")
-        main.log.info("onos-app-proxyarp uninstalled") 
-
-        main.step("Changing ipaddress of hosts h8,h9 and h18")
-        main.Mininet1.changeIP(host='h8', intf='h8-eth0', newIP='10.0.1.1', newNetmask='255.255.255.0') 
-        main.Mininet1.changeIP(host='h9', intf='h9-eth0', newIP='10.0.2.1', newNetmask='255.255.255.0')
-        main.Mininet1.changeIP(host='h10', intf='h10-eth0', newIP='10.0.3.1', newNetmask='255.255.255.0')
-
-        main.step("Changing default gateway of hosts h8,h9 and h18")
-        main.Mininet1.changeDefaultGateway(host='h8', newGW='10.0.1.254')
-        main.Mininet1.changeDefaultGateway(host='h9', newGW='10.0.2.254')
-        main.Mininet1.changeDefaultGateway(host='h10', newGW='10.0.3.254')
-
-        main.step("Assigning random mac address to the default gateways since proxyarp app is uninstalled")
-        main.Mininet1.addStaticMACAddress(host='h8', GW='10.0.1.254', macaddr='00:00:00:00:11:11')
-        main.Mininet1.addStaticMACAddress(host='h9', GW='10.0.2.254', macaddr='00:00:00:00:22:22')
-        main.Mininet1.addStaticMACAddress(host='h10', GW='10.0.3.254', macaddr='00:00:00:00:33:33')
-         
-        main.step("Verify static gateway and MAC address assignment")
-        main.Mininet1.verifyStaticGWandMAC(host='h8')
-        main.Mininet1.verifyStaticGWandMAC(host='h9')
-        main.Mininet1.verifyStaticGWandMAC(host='h10')
-        
-        main.step("Adding multipoint to singlepoint intent")               
-        p_intent_result1 = main.ONOScli1.add_multipoint_to_singlepoint_intent(ingress_device1=main.params['MULTIPOINT_INTENT']['device1'], ingress_device2=main.params['MULTIPOINT_INTENT']['device2'],
-                                 egress_device=main.params['MULTIPOINT_INTENT']['device3'], ipDst=main.params['MULTIPOINT_INTENT']['ip1'], setEthDst=main.params['MULTIPOINT_INTENT']['mac1']) 
-        
-        p_intent_result2 = main.ONOScli1.add_multipoint_to_singlepoint_intent(ingress_device1=main.params['MULTIPOINT_INTENT']['device3'], ingress_device2=main.params['MULTIPOINT_INTENT']['device2'],                            
-                                egress_device=main.params['MULTIPOINT_INTENT']['device1'], ipDst=main.params['MULTIPOINT_INTENT']['ip2'], setEthDst=main.params['MULTIPOINT_INTENT']['mac2'])    
-
-
-        get_intent_result = main.ONOScli1.intents(json_format = False)
-        main.log.info("intents = "+ get_intent_result)
-        
-        time.sleep(10)
-        get_flows_result = main.ONOScli1.flows(json_format = False)
-        main.log.info("flows = " + get_flows_result) 
-
-        count = 1
-        i = 8
-        Ping_Result = main.TRUE
-       
-        main.log.info("\n\nh"+str(i)+" is Pinging h" + str(i+2))
-        ping = main.Mininet1.pingHost(src="h"+str(i),target="h"+str(i+2))
-        if ping == main.FALSE and count <3:
-            count+=1
-            Ping_Result = main.FALSE
-            main.log.report("Ping between h" + str(i) + " and h" + str(i+2) + " failed. Making attempt number "+str(count) + " in 2 seconds")
-            time.sleep(2)
-        elif ping==main.FALSE:
-            main.log.report("All ping attempts between h" + str(i) + " and h" + str(i+10) +"have failed")
-            Ping_Result = main.FALSE
-        elif ping==main.TRUE:
-            main.log.info("Ping test between h" + str(i) + " and h" + str(i+2) + "passed!")
-            Ping_Result = main.TRUE
-        else:
-            main.log.info("Unknown error")
-            Ping_Result = main.ERROR
-        
-        if Ping_Result==main.FALSE:
-            main.log.report("Ping test failed.")
-            #main.cleanup()
-            #main.exit()
-        if Ping_Result==main.TRUE:
-            main.log.report("Ping all successful")
-
-
-        p_intent_result = p_intent_result1 and p_intent_result2
-        if p_intent_result ==main.TRUE:
-            main.log.info("Multi point intent with rewrite mac address installation successful")
-        else:
-            main.log.info("Multi point intent with rewrite mac address installation failed")
-      
-        case33_result = p_intent_result and Ping_Result
-        utilities.assert_equals(expect=main.TRUE, actual=case33_result,
-                onpass="Ping all test after multipoint to single point intent addition with rewrite mac address successful",
-                onfail="Ping all test after multipoint to single point intent addition with rewrite mac address failed")  
diff --git a/TestON/tests/MultiProd/MultiProd.bak1 b/TestON/tests/MultiProd/MultiProd.bak1
deleted file mode 100644
index 6b67f63..0000000
--- a/TestON/tests/MultiProd/MultiProd.bak1
+++ /dev/null
@@ -1,1523 +0,0 @@
-
-# Testing the basic functionality of ONOS Next
-# For sanity and driver functionality excercises only.
-
-import time
-import sys
-import os
-import re
-import time
-import json
-
-time.sleep( 1 )
-
-
-class MultiProd:
-
-    def __init__( self ):
-        self.default = ''
-
-    def CASE1( self, main ):
-        """
-        Startup sequence:
-        cell <name>
-        onos-verify-cell
-        onos-remove-raft-logs
-        git pull
-        mvn clean install
-        onos-package
-        onos-install -f
-        onos-wait-for-start
-        """
-        cell_name = main.params[ 'ENV' ][ 'cellName' ]
-        ONOS1_ip = main.params[ 'CTRL' ][ 'ip1' ]
-        ONOS2_ip = main.params[ 'CTRL' ][ 'ip2' ]
-        ONOS3_ip = main.params[ 'CTRL' ][ 'ip3' ]
-        ONOS1_port = main.params[ 'CTRL' ][ 'port1' ]
-        ONOS2_port = main.params[ 'CTRL' ][ 'port2' ]
-        ONOS3_port = main.params[ 'CTRL' ][ 'port3' ]
-
-        main.case( "Setting up test environment" )
-        main.log.report(
-            "This testcase is testing setting up test environment" )
-        main.log.report( "__________________________________" )
-
-        main.step( "Applying cell variable to environment" )
-        cell_result1 = main.ONOSbench.set_cell( cell_name )
-        #cell_result2 = main.ONOScli1.set_cell( cell_name )
-        #cell_result3 = main.ONOScli2.set_cell( cell_name )
-        #cell_result4 = main.ONOScli3.set_cell( cell_name )
-        verify_result = main.ONOSbench.verify_cell()
-        cell_result = cell_result1
-
-        main.step( "Removing raft logs before a clen installation of ONOS" )
-        remove_log_Result = main.ONOSbench.onos_remove_raft_logs()
-
-        main.step( "Git checkout and pull master and get version" )
-        main.ONOSbench.git_checkout( "master" )
-        git_pull_result = main.ONOSbench.git_pull()
-        print "git_pull_result = ", git_pull_result
-        version_result = main.ONOSbench.get_version( report=True )
-
-        if git_pull_result == 1:
-            main.step( "Using mvn clean & install" )
-            clean_install_result = main.ONOSbench.clean_install()
-            #clean_install_result = main.TRUE
-
-        main.step( "Creating ONOS package" )
-        package_result = main.ONOSbench.onos_package()
-
-        #main.step( "Creating a cell" )
-        # cell_create_result = main.ONOSbench.create_cell_file( **************
-        # )
-
-        main.step( "Installing ONOS package" )
-        onos1_install_result = main.ONOSbench.onos_install(
-            options="-f",
-            node=ONOS1_ip )
-        onos2_install_result = main.ONOSbench.onos_install(
-            options="-f",
-            node=ONOS2_ip )
-        onos3_install_result = main.ONOSbench.onos_install(
-            options="-f",
-            node=ONOS3_ip )
-        onos_install_result = onos1_install_result and onos2_install_result and onos3_install_result
-        if onos_install_result == main.TRUE:
-            main.log.report( "Installing ONOS package successful" )
-        else:
-            main.log.report( "Installing ONOS package failed" )
-
-        onos1_isup = main.ONOSbench.isup( ONOS1_ip )
-        onos2_isup = main.ONOSbench.isup( ONOS2_ip )
-        onos3_isup = main.ONOSbench.isup( ONOS3_ip )
-        onos_isup = onos1_isup and onos2_isup and onos3_isup
-        if onos_isup == main.TRUE:
-            main.log.report( "ONOS instances are up and ready" )
-        else:
-            main.log.report( "ONOS instances may not be up" )
-
-        main.step( "Starting ONOS service" )
-        start_result = main.TRUE
-        #start_result = main.ONOSbench.onos_start( ONOS1_ip )
-        startcli1 = main.ONOScli1.start_onos_cli( ONOS_ip=ONOS1_ip )
-        startcli2 = main.ONOScli2.start_onos_cli( ONOS_ip=ONOS2_ip )
-        startcli3 = main.ONOScli3.start_onos_cli( ONOS_ip=ONOS3_ip )
-        print startcli1
-        print startcli2
-        print startcli3
-
-        case1_result = ( package_result and
-                         cell_result and verify_result and onos_install_result and
-                         onos_isup and start_result )
-        utilities.assert_equals( expect=main.TRUE, actual=case1_result,
-                                 onpass="Test startup successful",
-                                 onfail="Test startup NOT successful" )
-
-    def CASE11( self, main ):
-        """
-        Cleanup sequence:
-        onos-service <node_ip> stop
-        onos-uninstall
-
-        TODO: Define rest of cleanup
-
-        """
-        ONOS1_ip = main.params[ 'CTRL' ][ 'ip1' ]
-        ONOS2_ip = main.params[ 'CTRL' ][ 'ip2' ]
-        ONOS3_ip = main.params[ 'CTRL' ][ 'ip3' ]
-
-        main.case( "Cleaning up test environment" )
-
-        main.step( "Testing ONOS kill function" )
-        kill_result1 = main.ONOSbench.onos_kill( ONOS1_ip )
-        kill_result2 = main.ONOSbench.onos_kill( ONOS2_ip )
-        kill_result3 = main.ONOSbench.onos_kill( ONOS3_ip )
-
-        main.step( "Stopping ONOS service" )
-        stop_result1 = main.ONOSbench.onos_stop( ONOS1_ip )
-        stop_result2 = main.ONOSbench.onos_stop( ONOS2_ip )
-        stop_result3 = main.ONOSbench.onos_stop( ONOS3_ip )
-
-        main.step( "Uninstalling ONOS service" )
-        uninstall_result = main.ONOSbench.onos_uninstall()
-
-    def CASE3( self, main ):
-        """
-        Test 'onos' command and its functionality in driver
-        """
-        ONOS1_ip = main.params[ 'CTRL' ][ 'ip1' ]
-        ONOS2_ip = main.params[ 'CTRL' ][ 'ip2' ]
-        ONOS3_ip = main.params[ 'CTRL' ][ 'ip3' ]
-
-        main.case( "Testing 'onos' command" )
-
-        main.step( "Sending command 'onos -w <onos-ip> system:name'" )
-        cmdstr1 = "system:name"
-        cmd_result1 = main.ONOSbench.onos_cli( ONOS1_ip, cmdstr1 )
-        main.log.info( "onos command returned: " + cmd_result1 )
-        cmd_result2 = main.ONOSbench.onos_cli( ONOS2_ip, cmdstr1 )
-        main.log.info( "onos command returned: " + cmd_result2 )
-        cmd_result3 = main.ONOSbench.onos_cli( ONOS3_ip, cmdstr1 )
-        main.log.info( "onos command returned: " + cmd_result3 )
-
-        main.step( "Sending command 'onos -w <onos-ip> onos:topology'" )
-        cmdstr2 = "onos:topology"
-        cmd_result4 = main.ONOSbench.onos_cli( ONOS1_ip, cmdstr2 )
-        main.log.info( "onos command returned: " + cmd_result4 )
-        cmd_result5 = main.ONOSbench.onos_cli( ONOS2_ip, cmdstr2 )
-        main.log.info( "onos command returned: " + cmd_result5 )
-        cmd_result6 = main.ONOSbench.onos_cli( ONOS6_ip, cmdstr2 )
-        main.log.info( "onos command returned: " + cmd_result6 )
-
-    def CASE4( self, main ):
-        import re
-        import time
-        ONOS1_ip = main.params[ 'CTRL' ][ 'ip1' ]
-        ONOS2_ip = main.params[ 'CTRL' ][ 'ip2' ]
-        ONOS3_ip = main.params[ 'CTRL' ][ 'ip3' ]
-        ONOS1_port = main.params[ 'CTRL' ][ 'port1' ]
-        ONOS2_port = main.params[ 'CTRL' ][ 'port2' ]
-        ONOS3_port = main.params[ 'CTRL' ][ 'port3' ]
-
-        main.log.report(
-            "This testcase is testing the assignment of all the switches to all controllers and discovering the hosts in reactive mode" )
-        main.log.report( "__________________________________" )
-        main.case( "Pingall Test(No intents are added)" )
-        main.step( "Assigning switches to controllers" )
-        for i in range( 1, 29 ):  # 1 to ( num of switches +1 )
-            main.Mininet1.assign_sw_controller(
-                sw=str( i ),
-                count=3,
-                ip1=ONOS1_ip,
-                port1=ONOS1_port,
-                ip2=ONOS2_ip,
-                port2=ONOS2_port,
-                ip3=ONOS3_ip,
-                port3=ONOS3_port )
-
-        switch_mastership = main.TRUE
-        for i in range( 1, 29 ):
-            response = main.Mininet1.get_sw_controller( "s" + str( i ) )
-            print( "Response is " + str( response ) )
-            if re.search( "tcp:" + ONOS1_ip, response ):
-                switch_mastership = switch_mastership and main.TRUE
-            else:
-                switch_mastership = main.FALSE
-
-        if switch_mastership == main.TRUE:
-            main.log.report( "Controller assignment successfull" )
-        else:
-            main.log.report( "Controller assignment failed" )
-        # REACTIVE FWD test
-        main.step( "Pingall" )
-        ping_result = main.FALSE
-        time1 = time.time()
-        ping_result = main.Mininet1.pingall()
-        time2 = time.time()
-        print "Time for pingall: %2f seconds" % ( time2 - time1 )
-
-        case4_result = switch_mastership and ping_result
-        if ping_result == main.TRUE:
-            main.log.report(
-                "Pingall Test in reactive mode to discover the hosts successful" )
-        else:
-            main.log.report(
-                "Pingall Test in reactive mode to discover the hosts failed" )
-
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=case4_result,
-            onpass="Controller assignment and Pingall Test successful",
-            onfail="Controller assignment and Pingall Test NOT successful" )
-
-    def CASE5( self, main ):
-        import json
-        from subprocess import Popen, PIPE
-        # assumes that sts is already in you PYTHONPATH
-        from sts.topology.teston_topology import TestONTopology
-        ONOS1_ip = main.params[ 'CTRL' ][ 'ip1' ]
-        ONOS2_ip = main.params[ 'CTRL' ][ 'ip2' ]
-        ONOS3_ip = main.params[ 'CTRL' ][ 'ip3' ]
-
-        main.log.report(
-            "This testcase is testing if all ONOS nodes are in topology sync with mininet and its peer ONOS nodes" )
-        main.log.report( "__________________________________" )
-        main.case(
-            "Testing Mininet topology with the topology of multi instances ONOS" )
-        main.step( "Collecting topology information from ONOS" )
-        devices1 = main.ONOScli1.devices()
-        devices2 = main.ONOScli2.devices()
-        devices3 = main.ONOScli3.devices()
-        # print "devices1 = ", devices1
-        # print "devices2 = ", devices2
-        # print "devices3 = ", devices3
-        hosts1 = main.ONOScli1.hosts()
-        hosts2 = main.ONOScli2.hosts()
-        hosts3 = main.ONOScli3.hosts()
-        # print "hosts1 = ", hosts1
-        # print "hosts2 = ", hosts2
-        # print "hosts3 = ", hosts3
-        ports1 = main.ONOScli1.ports()
-        ports2 = main.ONOScli2.ports()
-        ports3 = main.ONOScli3.ports()
-        # print "ports1 = ", ports1
-        # print "ports2 = ", ports2
-        # print "ports3 = ", ports3
-        links1 = main.ONOScli1.links()
-        links2 = main.ONOScli2.links()
-        links3 = main.ONOScli3.links()
-        # print "links1 = ", links1
-        # print "links2 = ", links2
-        # print "links3 = ", links3
-
-        print "**************"
-
-        main.step( "Start continuous pings" )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source1' ],
-            target=main.params[ 'PING' ][ 'target1' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source2' ],
-            target=main.params[ 'PING' ][ 'target2' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source3' ],
-            target=main.params[ 'PING' ][ 'target3' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source4' ],
-            target=main.params[ 'PING' ][ 'target4' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source5' ],
-            target=main.params[ 'PING' ][ 'target5' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source6' ],
-            target=main.params[ 'PING' ][ 'target6' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source7' ],
-            target=main.params[ 'PING' ][ 'target7' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source8' ],
-            target=main.params[ 'PING' ][ 'target8' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source9' ],
-            target=main.params[ 'PING' ][ 'target9' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source10' ],
-            target=main.params[ 'PING' ][ 'target10' ],
-            pingTime=500 )
-
-        main.step( "Create TestONTopology object" )
-        global ctrls
-        ctrls = []
-        count = 1
-        while True:
-            temp = ()
-            if ( 'ip' + str( count ) ) in main.params[ 'CTRL' ]:
-                temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
-                temp = temp + ( "ONOS" + str( count ), )
-                temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
-                temp = temp + \
-                    ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
-                ctrls.append( temp )
-                count = count + 1
-            else:
-                break
-        global MNTopo
-        Topo = TestONTopology(
-            main.Mininet1,
-            ctrls )  # can also add Intent API info for intent operations
-        MNTopo = Topo
-
-        Topology_Check = main.TRUE
-        main.step( "Compare ONOS Topology to MN Topology" )
-
-        switches_results1 = main.Mininet1.compare_switches(
-            MNTopo,
-            json.loads( devices1 ) )
-        print "switches_Result1 = ", switches_results1
-        utilities.assert_equals( expect=main.TRUE, actual=switches_results1,
-                                 onpass="ONOS1 Switches view is correct",
-                                 onfail="ONOS1 Switches view is incorrect" )
-
-        switches_results2 = main.Mininet1.compare_switches(
-            MNTopo,
-            json.loads( devices2 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=switches_results2,
-                                 onpass="ONOS2 Switches view is correct",
-                                 onfail="ONOS2 Switches view is incorrect" )
-
-        switches_results3 = main.Mininet1.compare_switches(
-            MNTopo,
-            json.loads( devices3 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=switches_results3,
-                                 onpass="ONOS3 Switches view is correct",
-                                 onfail="ONOS3 Switches view is incorrect" )
-
-        """
-        ports_results1 =  main.Mininet1.compare_ports( MNTopo, json.loads( ports1 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=ports_results1,
-                onpass="ONOS1 Ports view is correct",
-                onfail="ONOS1 Ports view is incorrect" )
-
-        ports_results2 =  main.Mininet1.compare_ports( MNTopo, json.loads( ports2 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=ports_results2,
-                onpass="ONOS2 Ports view is correct",
-                onfail="ONOS2 Ports view is incorrect" )
-
-        ports_results3 =  main.Mininet1.compare_ports( MNTopo, json.loads( ports3 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=ports_results3,
-                onpass="ONOS3 Ports view is correct",
-                onfail="ONOS3 Ports view is incorrect" )
-        """
-        links_results1 = main.Mininet1.compare_links(
-            MNTopo,
-            json.loads( links1 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=links_results1,
-                                 onpass="ONOS1 Links view is correct",
-                                 onfail="ONOS1 Links view is incorrect" )
-
-        links_results2 = main.Mininet1.compare_links(
-            MNTopo,
-            json.loads( links2 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=links_results2,
-                                 onpass="ONOS2 Links view is correct",
-                                 onfail="ONOS2 Links view is incorrect" )
-
-        links_results3 = main.Mininet1.compare_links(
-            MNTopo,
-            json.loads( links3 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=links_results3,
-                                 onpass="ONOS2 Links view is correct",
-                                 onfail="ONOS2 Links view is incorrect" )
-
-        #topo_result = switches_results1 and switches_results2 and switches_results3\
-        # and ports_results1 and ports_results2 and ports_results3\
-        # and links_results1 and links_results2 and links_results3
-
-        topo_result = switches_results1 and switches_results2 and switches_results3\
-            and links_results1 and links_results2 and links_results3
-
-        if topo_result == main.TRUE:
-            main.log.report(
-                "Topology Check Test with mininet and ONOS instances successful" )
-        else:
-            main.log.report(
-                "Topology Check Test with mininet and ONOS instances failed" )
-
-        utilities.assert_equals( expect=main.TRUE, actual=topo_result,
-                                 onpass="Topology Check Test successful",
-                                 onfail="Topology Check Test NOT successful" )
-
-    def CASE10( self ):
-        main.log.report(
-            "This testcase uninstalls the reactive forwarding app" )
-        main.log.report( "__________________________________" )
-        main.case( "Uninstalling reactive forwarding app" )
-        # Unistall onos-app-fwd app to disable reactive forwarding
-        appUninstall_result1 = main.ONOScli1.feature_uninstall(
-            "onos-app-fwd" )
-        appUninstall_result2 = main.ONOScli2.feature_uninstall(
-            "onos-app-fwd" )
-        appUninstall_result3 = main.ONOScli3.feature_uninstall(
-            "onos-app-fwd" )
-        main.log.info( "onos-app-fwd uninstalled" )
-
-        # After reactive forwarding is disabled, the reactive flows on switches timeout in 10-15s
-        # So sleep for 15s
-        time.sleep( 15 )
-
-        hosts = main.ONOScli1.hosts()
-        main.log.info( hosts )
-
-        case10_result = appUninstall_result1 and appUninstall_result2 and appUninstall_result3
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=case10_result,
-            onpass="Reactive forwarding app uninstallation successful",
-            onfail="Reactive forwarding app uninstallation failed" )
-
-    def CASE6( self ):
-        main.log.report(
-            "This testcase is testing the addition of host intents and then doing pingall" )
-        main.log.report( "__________________________________" )
-        main.case( "Obtaining hostsfor adding host intents" )
-        main.step( "Get hosts" )
-        hosts = main.ONOScli1.hosts()
-        main.log.info( hosts )
-
-        main.step( "Get all devices id" )
-        devices_id_list = main.ONOScli1.get_all_devices_id()
-        main.log.info( devices_id_list )
-
-        # ONOS displays the hosts in hex format unlike mininet which does in decimal format
-        # So take care while adding intents
-
-        """
-        main.step( "Add host intents for mn hosts(h8-h18,h9-h19,h10-h20,h11-h21,h12-h22,h13-h23,h14-h24,h15-h25,h16-h26,h17-h27)" )
-        hth_intent_result = main.ONOScli1.add_host_intent( "00:00:00:00:00:08/-1", "00:00:00:00:00:12/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent( "00:00:00:00:00:09/-1", "00:00:00:00:00:13/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent( "00:00:00:00:00:0A/-1", "00:00:00:00:00:14/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent( "00:00:00:00:00:0B/-1", "00:00:00:00:00:15/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent( "00:00:00:00:00:0C/-1", "00:00:00:00:00:16/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent( "00:00:00:00:00:0D/-1", "00:00:00:00:00:17/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent( "00:00:00:00:00:0E/-1", "00:00:00:00:00:18/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent( "00:00:00:00:00:0F/-1", "00:00:00:00:00:19/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent( "00:00:00:00:00:10/-1", "00:00:00:00:00:1A/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent( "00:00:00:00:00:11/-1", "00:00:00:00:00:1B/-1" )
-        """
-        for i in range( 8, 18 ):
-            main.log.info(
-                "Adding host intent between h" + str( i ) + " and h" + str( i + 10 ) )
-            host1 = "00:00:00:00:00:" + \
-                str( hex( i )[ 2: ] ).zfill( 2 ).upper()
-            host2 = "00:00:00:00:00:" + \
-                str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
-            # NOTE: get host can return None
-            # TODO: handle this
-            host1_id = main.ONOScli1.get_host( host1 )[ 'id' ]
-            host2_id = main.ONOScli1.get_host( host2 )[ 'id' ]
-            tmp_result = main.ONOScli1.add_host_intent( host1_id, host2_id )
-
-        flowHandle = main.ONOScli1.flows()
-        # print "flowHandle = ", flowHandle
-        main.log.info( "flows:" + flowHandle )
-
-        count = 1
-        i = 8
-        Ping_Result = main.TRUE
-        while i < 18:
-            main.log.info(
-                "\n\nh" + str( i ) + " is Pinging h" + str( i + 10 ) )
-            ping = main.Mininet1.pingHost(
-                src="h" + str( i ), target="h" + str( i + 10 ) )
-            if ping == main.FALSE and count < 5:
-                count += 1
-                #i = 8
-                Ping_Result = main.FALSE
-                main.log.report( "Ping between h" +
-                                 str( i ) +
-                                 " and h" +
-                                 str( i +
-                                      10 ) +
-                                 " failed. Making attempt number " +
-                                 str( count ) +
-                                 " in 2 seconds" )
-                time.sleep( 2 )
-            elif ping == main.FALSE:
-                main.log.report( "All ping attempts between h" +
-                                 str( i ) +
-                                 " and h" +
-                                 str( i +
-                                      10 ) +
-                                 "have failed" )
-                i = 19
-                Ping_Result = main.FALSE
-            elif ping == main.TRUE:
-                main.log.info( "Ping test between h" +
-                               str( i ) +
-                               " and h" +
-                               str( i +
-                                    10 ) +
-                               "passed!" )
-                i += 1
-                Ping_Result = main.TRUE
-            else:
-                main.log.info( "Unknown error" )
-                Ping_Result = main.ERROR
-        if Ping_Result == main.FALSE:
-            main.log.report(
-                "Host intents have not ben installed correctly. Cleaning up" )
-            # main.cleanup()
-            # main.exit()
-        if Ping_Result == main.TRUE:
-            main.log.report( "Host intents have been installed correctly" )
-
-        case6_result = Ping_Result
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=case6_result,
-            onpass="Host intent addition and Pingall Test successful",
-            onfail="Host intent addition and Pingall Test NOT successful" )
-
-    def CASE7( self, main ):
-
-        ONOS1_ip = main.params[ 'CTRL' ][ 'ip1' ]
-
-        link_sleep = int( main.params[ 'timers' ][ 'LinkDiscovery' ] )
-
-        main.log.report(
-            "This testscase is killing a link to ensure that link discovery is consistent" )
-        main.log.report( "__________________________________" )
-        main.case(
-            "Killing a link to Ensure that Link Discovery is Working Properly" )
-        main.step( "Start continuous pings" )
-
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source1' ],
-            target=main.params[ 'PING' ][ 'target1' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source2' ],
-            target=main.params[ 'PING' ][ 'target2' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source3' ],
-            target=main.params[ 'PING' ][ 'target3' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source4' ],
-            target=main.params[ 'PING' ][ 'target4' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source5' ],
-            target=main.params[ 'PING' ][ 'target5' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source6' ],
-            target=main.params[ 'PING' ][ 'target6' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source7' ],
-            target=main.params[ 'PING' ][ 'target7' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source8' ],
-            target=main.params[ 'PING' ][ 'target8' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source9' ],
-            target=main.params[ 'PING' ][ 'target9' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source10' ],
-            target=main.params[ 'PING' ][ 'target10' ],
-            pingTime=500 )
-
-        main.step( "Determine the current number of switches and links" )
-        topology_output = main.ONOScli1.topology()
-        topology_result = main.ONOSbench.get_topology( topology_output )
-        activeSwitches = topology_result[ 'devices' ]
-        links = topology_result[ 'links' ]
-        print "activeSwitches = ", type( activeSwitches )
-        print "links = ", type( links )
-        main.log.info(
-            "Currently there are %s switches and %s links" %
-            ( str( activeSwitches ), str( links ) ) )
-
-        main.step( "Kill Link between s3 and s28" )
-        main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
-        time.sleep( link_sleep )
-        topology_output = main.ONOScli2.topology()
-        Link_Down = main.ONOSbench.check_status(
-            topology_output, activeSwitches, str(
-                int( links ) - 2 ) )
-        if Link_Down == main.TRUE:
-            main.log.report( "Link Down discovered properly" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=Link_Down,
-            onpass="Link Down discovered properly",
-            onfail="Link down was not discovered in " +
-            str( link_sleep ) +
-            " seconds" )
-
-        main.step( "Bring link between s3 and s28 back up" )
-        Link_Up = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
-        time.sleep( link_sleep )
-        topology_output = main.ONOScli2.topology()
-        Link_Up = main.ONOSbench.check_status(
-            topology_output,
-            activeSwitches,
-            str( links ) )
-        if Link_Up == main.TRUE:
-            main.log.report( "Link up discovered properly" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=Link_Up,
-            onpass="Link up discovered properly",
-            onfail="Link up was not discovered in " +
-            str( link_sleep ) +
-            " seconds" )
-
-        main.step( "Compare ONOS Topology to MN Topology" )
-        main.case(
-            "Testing Mininet topology with the topology of multi instances ONOS" )
-        main.step( "Collecting topology information from ONOS" )
-        devices1 = main.ONOScli1.devices()
-        devices2 = main.ONOScli2.devices()
-        devices3 = main.ONOScli3.devices()
-        print "devices1 = ", devices1
-        print "devices2 = ", devices2
-        print "devices3 = ", devices3
-        hosts1 = main.ONOScli1.hosts()
-        hosts2 = main.ONOScli2.hosts()
-        hosts3 = main.ONOScli3.hosts()
-        # print "hosts1 = ", hosts1
-        # print "hosts2 = ", hosts2
-        # print "hosts3 = ", hosts3
-        ports1 = main.ONOScli1.ports()
-        ports2 = main.ONOScli2.ports()
-        ports3 = main.ONOScli3.ports()
-        # print "ports1 = ", ports1
-        # print "ports2 = ", ports2
-        # print "ports3 = ", ports3
-        links1 = main.ONOScli1.links()
-        links2 = main.ONOScli2.links()
-        links3 = main.ONOScli3.links()
-        # print "links1 = ", links1
-        # print "links2 = ", links2
-        # print "links3 = ", links3
-
-        print "**************"
-
-        main.step( "Start continuous pings" )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source1' ],
-            target=main.params[ 'PING' ][ 'target1' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source2' ],
-            target=main.params[ 'PING' ][ 'target2' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source3' ],
-            target=main.params[ 'PING' ][ 'target3' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source4' ],
-            target=main.params[ 'PING' ][ 'target4' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source5' ],
-            target=main.params[ 'PING' ][ 'target5' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source6' ],
-            target=main.params[ 'PING' ][ 'target6' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source7' ],
-            target=main.params[ 'PING' ][ 'target7' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source8' ],
-            target=main.params[ 'PING' ][ 'target8' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source9' ],
-            target=main.params[ 'PING' ][ 'target9' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source10' ],
-            target=main.params[ 'PING' ][ 'target10' ],
-            pingTime=500 )
-
-        main.step( "Create TestONTopology object" )
-        global ctrls
-        ctrls = []
-        count = 1
-        while True:
-            temp = ()
-            if ( 'ip' + str( count ) ) in main.params[ 'CTRL' ]:
-                temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
-                temp = temp + ( "ONOS" + str( count ), )
-                temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
-                temp = temp + \
-                    ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
-                ctrls.append( temp )
-                count = count + 1
-            else:
-                break
-        global MNTopo
-        Topo = TestONTopology(
-            main.Mininet1,
-            ctrls )  # can also add Intent API info for intent operations
-        MNTopo = Topo
-
-        Topology_Check = main.TRUE
-        main.step( "Compare ONOS Topology to MN Topology" )
-
-        switches_results1 = main.Mininet1.compare_switches(
-            MNTopo,
-            json.loads( devices1 ) )
-        print "switches_Result1 = ", switches_results1
-        utilities.assert_equals( expect=main.TRUE, actual=switches_results1,
-                                 onpass="ONOS1 Switches view is correct",
-                                 onfail="ONOS1 Switches view is incorrect" )
-
-        switches_results2 = main.Mininet1.compare_switches(
-            MNTopo,
-            json.loads( devices2 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=switches_results2,
-                                 onpass="ONOS2 Switches view is correct",
-                                 onfail="ONOS2 Switches view is incorrect" )
-
-        switches_results3 = main.Mininet1.compare_switches(
-            MNTopo,
-            json.loads( devices3 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=switches_results3,
-                                 onpass="ONOS3 Switches view is correct",
-                                 onfail="ONOS3 Switches view is incorrect" )
-
-        """
-        ports_results1 =  main.Mininet1.compare_ports( MNTopo, json.loads( ports1 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=ports_results1,
-                onpass="ONOS1 Ports view is correct",
-                onfail="ONOS1 Ports view is incorrect" )
-
-        ports_results2 =  main.Mininet1.compare_ports( MNTopo, json.loads( ports2 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=ports_results2,
-                onpass="ONOS2 Ports view is correct",
-                onfail="ONOS2 Ports view is incorrect" )
-
-        ports_results3 =  main.Mininet1.compare_ports( MNTopo, json.loads( ports3 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=ports_results3,
-                onpass="ONOS3 Ports view is correct",
-                onfail="ONOS3 Ports view is incorrect" )
-        """
-        links_results1 = main.Mininet1.compare_links(
-            MNTopo,
-            json.loads( links1 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=links_results1,
-                                 onpass="ONOS1 Links view is correct",
-                                 onfail="ONOS1 Links view is incorrect" )
-
-        links_results2 = main.Mininet1.compare_links(
-            MNTopo,
-            json.loads( links2 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=links_results2,
-                                 onpass="ONOS2 Links view is correct",
-                                 onfail="ONOS2 Links view is incorrect" )
-
-        links_results3 = main.Mininet1.compare_links(
-            MNTopo,
-            json.loads( links3 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=links_results3,
-                                 onpass="ONOS2 Links view is correct",
-                                 onfail="ONOS2 Links view is incorrect" )
-
-        #topo_result = switches_results1 and switches_results2 and switches_results3\
-        # and ports_results1 and ports_results2 and ports_results3\
-        # and links_results1 and links_results2 and links_results3
-
-        topo_result = switches_results1 and switches_results2 and switches_results3\
-            and links_results1 and links_results2 and links_results3
-
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=topo_result and Link_Up and Link_Down,
-            onpass="Topology Check Test successful",
-            onfail="Topology Check Test NOT successful" )
-
-    def CASE8( self ):
-        """
-        Intent removal
-        """
-        main.log.report(
-            "This testcase removes host any previously added intents" )
-        main.log.report( "__________________________________" )
-        main.log.info( "Removing any previously installed intents" )
-        main.case( "Removing intents" )
-        main.step( "Obtain the intent id's" )
-        intent_result = main.ONOScli1.intents( json_format=False )
-
-        intent_linewise = intent_result.split( "\n" )
-        intentList = []
-        for line in intent_linewise:
-            if line.startswith( "id=" ):
-                intentList.append( line )
-
-        intentids = []
-        for line in intentList:
-            intentids.append( line.split( "," )[ 0 ].split( "=" )[ 1 ] )
-        for id in intentids:
-            main.log.info( "id = " + id )
-
-        main.step(
-            "Iterate through the intentids list and remove each intent" )
-        for id in intentids:
-            main.ONOScli1.remove_intent( intent_id=id )
-
-        intent_result = main.ONOScli1.intents( json_format=False )
-        main.log.info( "intent_result = " + intent_result )
-        case8_result = main.TRUE
-
-        i = 8
-        Ping_Result = main.TRUE
-        while i < 18:
-            main.log.info(
-                "\n\nh" + str( i ) + " is Pinging h" + str( i + 10 ) )
-            ping = main.Mininet1.pingHost(
-                src="h" + str( i ), target="h" + str( i + 10 ) )
-            if ping == main.TRUE:
-                i = 19
-                Ping_Result = main.TRUE
-            elif ping == main.FALSE:
-                i += 1
-                Ping_Result = main.FALSE
-            else:
-                main.log.info( "Unknown error" )
-                Ping_Result = main.ERROR
-
-        # Note: If the ping result failed, that means the intents have been
-        # withdrawn correctly.
-        if Ping_Result == main.TRUE:
-            main.log.report( "Host intents have not been withdrawn correctly" )
-            # main.cleanup()
-            # main.exit()
-        if Ping_Result == main.FALSE:
-            main.log.report( "Host intents have been withdrawn correctly" )
-
-        case8_result = case8_result and Ping_Result
-
-        if case8_result == main.FALSE:
-            main.log.report( "Intent removal successful" )
-        else:
-            main.log.report( "Intent removal failed" )
-
-        utilities.assert_equals( expect=main.FALSE, actual=case8_result,
-                                 onpass="Intent removal test failed",
-                                 onfail="Intent removal test successful" )
-
-    def CASE9( self ):
-        """
-        This test case adds point intents. Make sure you run test case 8 which is host intent removal before executing this test case.
-        Else the host intent's flows will persist on switches and the pings would work even if there is some issue with the point intent's flows
-        """
-        main.log.report(
-            "This testcase adds point intents and then does pingall" )
-        main.log.report( "__________________________________" )
-        main.log.info( "Adding point intents" )
-        main.case(
-            "Adding bidirectional point for mn hosts(h8-h18,h9-h19,h10-h20,h11-h21,h12-h22,h13-h23,h14-h24,h15-h25,h16-h26,h17-h27)" )
-        main.step(
-            "Add point-to-point intents for mininet hosts h8 and h18 or ONOS hosts h8 and h12" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003008/1",
-            "of:0000000000006018/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006018/1",
-            "of:0000000000003008/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step(
-            "Add point-to-point intents for mininet hosts h9 and h19 or ONOS hosts h9 and h13" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003009/1",
-            "of:0000000000006019/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006019/1",
-            "of:0000000000003009/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step(
-            "Add point-to-point intents for mininet hosts h10 and h20 or ONOS hosts hA and h14" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003010/1",
-            "of:0000000000006020/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006020/1",
-            "of:0000000000003010/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step(
-            "Add point-to-point intents for mininet hosts h11 and h21 or ONOS hosts hB and h15" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003011/1",
-            "of:0000000000006021/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006021/1",
-            "of:0000000000003011/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step(
-            "Add point-to-point intents for mininet hosts h12 and h22 or ONOS hosts hC and h16" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003012/1",
-            "of:0000000000006022/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006022/1",
-            "of:0000000000003012/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step(
-            "Add point-to-point intents for mininet hosts h13 and h23 or ONOS hosts hD and h17" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003013/1",
-            "of:0000000000006023/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006023/1",
-            "of:0000000000003013/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step(
-            "Add point-to-point intents for mininet hosts h14 and h24 or ONOS hosts hE and h18" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003014/1",
-            "of:0000000000006024/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006024/1",
-            "of:0000000000003014/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step(
-            "Add point-to-point intents for mininet hosts h15 and h25 or ONOS hosts hF and h19" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003015/1",
-            "of:0000000000006025/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006025/1",
-            "of:0000000000003015/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step(
-            "Add point-to-point intents for mininet hosts h16 and h26 or ONOS hosts h10 and h1A" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003016/1",
-            "of:0000000000006026/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006026/1",
-            "of:0000000000003016/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step(
-            "Add point-to-point intents for mininet hosts h17 and h27 or ONOS hosts h11 and h1B" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003017/1",
-            "of:0000000000006027/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006027/1",
-            "of:0000000000003017/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        print(
-            "_______________________________________________________________________________________" )
-
-        flowHandle = main.ONOScli1.flows()
-        # print "flowHandle = ", flowHandle
-        main.log.info( "flows :" + flowHandle )
-
-        count = 1
-        i = 8
-        Ping_Result = main.TRUE
-        while i < 18:
-            main.log.info(
-                "\n\nh" + str( i ) + " is Pinging h" + str( i + 10 ) )
-            ping = main.Mininet1.pingHost(
-                src="h" + str( i ), target="h" + str( i + 10 ) )
-            if ping == main.FALSE and count < 5:
-                count += 1
-                #i = 8
-                Ping_Result = main.FALSE
-                main.log.report( "Ping between h" +
-                                 str( i ) +
-                                 " and h" +
-                                 str( i +
-                                      10 ) +
-                                 " failed. Making attempt number " +
-                                 str( count ) +
-                                 " in 2 seconds" )
-                time.sleep( 2 )
-            elif ping == main.FALSE:
-                main.log.report( "All ping attempts between h" +
-                                 str( i ) +
-                                 " and h" +
-                                 str( i +
-                                      10 ) +
-                                 "have failed" )
-                i = 19
-                Ping_Result = main.FALSE
-            elif ping == main.TRUE:
-                main.log.info( "Ping test between h" +
-                               str( i ) +
-                               " and h" +
-                               str( i +
-                                    10 ) +
-                               "passed!" )
-                i += 1
-                Ping_Result = main.TRUE
-            else:
-                main.log.info( "Unknown error" )
-                Ping_Result = main.ERROR
-        if Ping_Result == main.FALSE:
-            main.log.report(
-                "Ping all test after Point intents addition failed. Cleaning up" )
-            # main.cleanup()
-            # main.exit()
-        if Ping_Result == main.TRUE:
-            main.log.report(
-                "Ping all test after Point intents addition successful" )
-
-        case8_result = Ping_Result
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=case8_result,
-            onpass="Ping all test after Point intents addition successful",
-            onfail="Ping all test after Point intents addition failed" )
-
-    def CASE31( self ):
-        """
-            This test case adds point intent related to SDN-IP matching on ICMP ( ethertype=IPV4, ipProto=1 )
-        """
-        import json
-
-        main.log.report(
-            "This test case adds point intent related to SDN-IP matching on ICMP" )
-        main.case(
-            "Adding bidirectional point intent related to SDN-IP matching on ICMP" )
-        main.step( "Adding bidirectional point intent" )
-        # add-point-intent --ipSrc=10.0.0.8/32 --ipDst=10.0.0.18/32
-        # --ethType=IPV4 --ipProto=1  of:0000000000003008/1
-        # of:0000000000006018/1
-
-        hosts_json = json.loads( main.ONOScli1.hosts() )
-        for i in range( 8, 11 ):
-            main.log.info(
-                "Adding point intent between h" + str( i ) + " and h" + str( i + 10 ) )
-            host1 = "00:00:00:00:00:" + \
-                str( hex( i )[ 2: ] ).zfill( 2 ).upper()
-            host2 = "00:00:00:00:00:" + \
-                str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
-            host1_id = main.ONOScli1.get_host( host1 )[ 'id' ]
-            host2_id = main.ONOScli1.get_host( host2 )[ 'id' ]
-            for host in hosts_json:
-                if host[ 'id' ] == host1_id:
-                    ip1 = host[ 'ips' ][ 0 ]
-                    ip1 = str( ip1 + "/32" )
-                    device1 = host[ 'location' ][ 'device' ]
-                    device1 = str( device1 + "/1" )
-                elif host[ 'id' ] == host2_id:
-                    ip2 = str( host[ 'ips' ][ 0 ] ) + "/32"
-                    device2 = host[ 'location' ][ "device" ]
-                    device2 = str( device2 + "/1" )
-
-            p_intent_result1 = main.ONOScli1.add_point_intent(
-                ingress_device=device1,
-                egress_device=device2,
-                ipSrc=ip1,
-                ipDst=ip2,
-                ethType=main.params[ 'SDNIP' ][ 'ethType' ],
-                ipProto=main.params[ 'SDNIP' ][ 'icmpProto' ] )
-
-            get_intent_result = main.ONOScli1.intents( json_format=False )
-            main.log.info( get_intent_result )
-
-            p_intent_result2 = main.ONOScli1.add_point_intent(
-                ingress_device=device2,
-                egress_device=device1,
-                ipSrc=ip2,
-                ipDst=ip1,
-                ethType=main.params[ 'SDNIP' ][ 'ethType' ],
-                ipProto=main.params[ 'SDNIP' ][ 'icmpProto' ] )
-
-            get_intent_result = main.ONOScli1.intents( json_format=False )
-            main.log.info( get_intent_result )
-            if ( p_intent_result1 and p_intent_result2 ) == main.TRUE:
-                #get_intent_result = main.ONOScli1.intents()
-                # main.log.info( get_intent_result )
-                main.log.info(
-                    "Point intent related to SDN-IP matching on ICMP install successful" )
-
-        time.sleep( 15 )
-        get_intent_result = main.ONOScli1.intents( json_format=False )
-        main.log.info( "intents = " + get_intent_result )
-        get_flows_result = main.ONOScli1.flows()
-        main.log.info( "flows = " + get_flows_result )
-
-        count = 1
-        i = 8
-        Ping_Result = main.TRUE
-        while i < 11:
-            main.log.info(
-                "\n\nh" + str( i ) + " is Pinging h" + str( i + 10 ) )
-            ping = main.Mininet1.pingHost(
-                src="h" + str( i ), target="h" + str( i + 10 ) )
-            if ping == main.FALSE and count < 3:
-                count += 1
-                #i = 8
-                Ping_Result = main.FALSE
-                main.log.report( "Ping between h" +
-                                 str( i ) +
-                                 " and h" +
-                                 str( i +
-                                      10 ) +
-                                 " failed. Making attempt number " +
-                                 str( count ) +
-                                 " in 2 seconds" )
-                time.sleep( 2 )
-            elif ping == main.FALSE:
-                main.log.report( "All ping attempts between h" +
-                                 str( i ) +
-                                 " and h" +
-                                 str( i +
-                                      10 ) +
-                                 "have failed" )
-                i = 19
-                Ping_Result = main.FALSE
-            elif ping == main.TRUE:
-                main.log.info( "Ping test between h" +
-                               str( i ) +
-                               " and h" +
-                               str( i +
-                                    10 ) +
-                               "passed!" )
-                i += 1
-                Ping_Result = main.TRUE
-            else:
-                main.log.info( "Unknown error" )
-                Ping_Result = main.ERROR
-        if Ping_Result == main.FALSE:
-            main.log.report(
-                "Ping test after Point intents related to SDN-IP matching on ICMP failed." )
-            # main.cleanup()
-            # main.exit()
-        if Ping_Result == main.TRUE:
-            main.log.report(
-                "Ping all test after Point intents related to SDN-IP matching on ICMP successful" )
-
-        case31_result = Ping_Result and p_intent_result1 and p_intent_result2
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=case31_result,
-            onpass="Point intent related to SDN-IP matching on ICMP and ping test successful",
-            onfail="Point intent related to SDN-IP matching on ICMP and ping test failed" )
-
-    def CASE32( self ):
-        """
-            This test case adds point intent related to SDN-IP matching on TCP ( ethertype=IPV4, ipProto=6, DefaultPort for iperf=5001 )
-            Note: Although BGP port is 179, we are using 5001 because iperf is used for verifying and iperf's default port is 5001
-        """
-        import json
-
-        main.log.report(
-            "This test case adds point intent related to SDN-IP matching on TCP" )
-        main.case(
-            "Adding bidirectional point intent related to SDN-IP matching on TCP" )
-        main.step( "Adding bidirectional point intent" )
-        """
-        add-point-intent --ipSrc=10.0.0.8/32 --ipDst=10.0.0.18/32 --ethType=IPV4 --ipProto=6 --tcpDst=5001  of:0000000000003008/1 of:0000000000006018/1
-
-        add-point-intent --ipSrc=10.0.0.18/32 --ipDst=10.0.0.8/32 --ethType=IPV4 --ipProto=6 --tcpDst=5001  of:0000000000006018/1 of:0000000000003008/1
-
-        add-point-intent --ipSrc=10.0.0.8/32 --ipDst=10.0.0.18/32 --ethType=IPV4 --ipProto=6 --tcpSrc=5001  of:0000000000003008/1 of:0000000000006018/1
-
-        add-point-intent --ipSrc=10.0.0.18/32 --ipDst=10.0.0.8/32 --ethType=IPV4 --ipProto=6 --tcpSrc=5001  of:0000000000006018/1 of:0000000000003008/1
-
-        """
-        hosts_json = json.loads( main.ONOScli1.hosts() )
-        for i in range( 8, 9 ):
-            main.log.info(
-                "Adding point intent between h" + str( i ) + " and h" + str( i + 10 ) )
-            host1 = "00:00:00:00:00:" + \
-                str( hex( i )[ 2: ] ).zfill( 2 ).upper()
-            host2 = "00:00:00:00:00:" + \
-                str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
-            host1_id = main.ONOScli1.get_host( host1 )[ 'id' ]
-            host2_id = main.ONOScli1.get_host( host2 )[ 'id' ]
-            for host in hosts_json:
-                if host[ 'id' ] == host1_id:
-                    ip1 = host[ 'ips' ][ 0 ]
-                    ip1 = str( ip1 + "/32" )
-                    device1 = host[ 'location' ][ 'device' ]
-                    device1 = str( device1 + "/1" )
-                elif host[ 'id' ] == host2_id:
-                    ip2 = str( host[ 'ips' ][ 0 ] ) + "/32"
-                    device2 = host[ 'location' ][ "device" ]
-                    device2 = str( device2 + "/1" )
-
-            p_intent_result1 = main.ONOScli1.add_point_intent(
-                ingress_device=device1,
-                egress_device=device2,
-                ipSrc=ip1,
-                ipDst=ip2,
-                ethType=main.params[ 'SDNIP' ][ 'ethType' ],
-                ipProto=main.params[ 'SDNIP' ][ 'tcpProto' ],
-                tcpDst=main.params[ 'SDNIP' ][ 'dstPort' ] )
-            p_intent_result2 = main.ONOScli1.add_point_intent(
-                ingress_device=device2,
-                egress_device=device1,
-                ipSrc=ip2,
-                ipDst=ip1,
-                ethType=main.params[ 'SDNIP' ][ 'ethType' ],
-                ipProto=main.params[ 'SDNIP' ][ 'tcpProto' ],
-                tcpDst=main.params[ 'SDNIP' ][ 'dstPort' ] )
-
-            p_intent_result3 = main.ONOScli1.add_point_intent(
-                ingress_device=device1,
-                egress_device=device2,
-                ipSrc=ip1,
-                ipDst=ip2,
-                ethType=main.params[ 'SDNIP' ][ 'ethType' ],
-                ipProto=main.params[ 'SDNIP' ][ 'tcpProto' ],
-                tcpSrc=main.params[ 'SDNIP' ][ 'srcPort' ] )
-            p_intent_result4 = main.ONOScli1.add_point_intent(
-                ingress_device=device2,
-                egress_device=device1,
-                ipSrc=ip2,
-                ipDst=ip1,
-                ethType=main.params[ 'SDNIP' ][ 'ethType' ],
-                ipProto=main.params[ 'SDNIP' ][ 'tcpProto' ],
-                tcpSrc=main.params[ 'SDNIP' ][ 'srcPort' ] )
-
-            p_intent_result = p_intent_result1 and p_intent_result2 and p_intent_result3 and p_intent_result4
-            if p_intent_result == main.TRUE:
-                get_intent_result = main.ONOScli1.intents( json_format=False )
-                main.log.info( get_intent_result )
-                main.log.info(
-                    "Point intent related to SDN-IP matching on TCP install successful" )
-
-        iperf_result = main.Mininet1.iperf( 'h8', 'h18' )
-        if iperf_result == main.TRUE:
-            main.log.report( "iperf test successful" )
-        else:
-            main.log.report( "iperf test failed" )
-
-        case32_result = p_intent_result and iperf_result
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=case32_result,
-            onpass="Ping all test after Point intents addition related to SDN-IP on TCP match successful",
-            onfail="Ping all test after Point intents addition related to SDN-IP on TCP match failed" )
-
-    def CASE33( self ):
-        """
-            This test case adds multipoint to singlepoint  intent related to SDN-IP matching on destination ip and the action is to rewrite the mac address
-            Here the mac address to be rewritten is the mac address of the egress device
-        """
-        import json
-        import time
-
-        main.log.report(
-            "This test case adds multipoint to singlepoint intent related to SDN-IP matching on destination ip and rewrite mac address action" )
-        main.case(
-            "Adding multipoint to singlepoint intent related to SDN-IP matching on destination ip" )
-        main.step( "Adding bidirectional multipoint to singlepoint intent" )
-        """
-        add-multi-to-single-intent --ipDst=10.0.3.0/24 --setEthDst=00:00:00:00:00:12 of:0000000000003008/1 0000000000003009/1 of:0000000000006018/1
-
-        add-multi-to-single-intent --ipDst=10.0.1.0/24 --setEthDst=00:00:00:00:00:08 of:0000000000006018/1 0000000000003009/1 of:0000000000003008/1
-        """
-        main.case(
-            "Installing multipoint to single point intent with rewrite mac address" )
-        main.step( "Uninstalling proxy arp app" )
-        # Unistall onos-app-proxyarp app to disable reactive forwarding
-        appUninstall_result1 = main.ONOScli1.feature_uninstall(
-            "onos-app-proxyarp" )
-        appUninstall_result2 = main.ONOScli2.feature_uninstall(
-            "onos-app-proxyarp" )
-        appUninstall_result3 = main.ONOScli3.feature_uninstall(
-            "onos-app-proxyarp" )
-        main.log.info( "onos-app-proxyarp uninstalled" )
-
-        main.step( "Changing ipaddress of hosts h8,h9 and h18" )
-        main.Mininet1.changeIP(
-            host='h8',
-            intf='h8-eth0',
-            newIP='10.0.1.1',
-            newNetmask='255.255.255.0' )
-        main.Mininet1.changeIP(
-            host='h9',
-            intf='h9-eth0',
-            newIP='10.0.2.1',
-            newNetmask='255.255.255.0' )
-        main.Mininet1.changeIP(
-            host='h10',
-            intf='h10-eth0',
-            newIP='10.0.3.1',
-            newNetmask='255.255.255.0' )
-
-        main.step( "Changing default gateway of hosts h8,h9 and h18" )
-        main.Mininet1.changeDefaultGateway( host='h8', newGW='10.0.1.254' )
-        main.Mininet1.changeDefaultGateway( host='h9', newGW='10.0.2.254' )
-        main.Mininet1.changeDefaultGateway( host='h10', newGW='10.0.3.254' )
-
-        main.step(
-            "Assigning random mac address to the default gateways since proxyarp app is uninstalled" )
-        main.Mininet1.addStaticMACAddress(
-            host='h8',
-            GW='10.0.1.254',
-            macaddr='00:00:00:00:11:11' )
-        main.Mininet1.addStaticMACAddress(
-            host='h9',
-            GW='10.0.2.254',
-            macaddr='00:00:00:00:22:22' )
-        main.Mininet1.addStaticMACAddress(
-            host='h10',
-            GW='10.0.3.254',
-            macaddr='00:00:00:00:33:33' )
-
-        main.step( "Verify static gateway and MAC address assignment" )
-        main.Mininet1.verifyStaticGWandMAC( host='h8' )
-        main.Mininet1.verifyStaticGWandMAC( host='h9' )
-        main.Mininet1.verifyStaticGWandMAC( host='h10' )
-
-        main.step( "Adding multipoint to singlepoint intent" )
-        p_intent_result1 = main.ONOScli1.add_multipoint_to_singlepoint_intent(
-            ingress_device1=main.params[ 'MULTIPOINT_INTENT' ][ 'device1' ],
-            ingress_device2=main.params[ 'MULTIPOINT_INTENT' ][ 'device2' ],
-            egress_device=main.params[ 'MULTIPOINT_INTENT' ][ 'device3' ],
-            ipDst=main.params[ 'MULTIPOINT_INTENT' ][ 'ip1' ],
-            setEthDst=main.params[ 'MULTIPOINT_INTENT' ][ 'mac1' ] )
-
-        p_intent_result2 = main.ONOScli1.add_multipoint_to_singlepoint_intent(
-            ingress_device1=main.params[ 'MULTIPOINT_INTENT' ][ 'device3' ],
-            ingress_device2=main.params[ 'MULTIPOINT_INTENT' ][ 'device2' ],
-            egress_device=main.params[ 'MULTIPOINT_INTENT' ][ 'device1' ],
-            ipDst=main.params[ 'MULTIPOINT_INTENT' ][ 'ip2' ],
-            setEthDst=main.params[ 'MULTIPOINT_INTENT' ][ 'mac2' ] )
-
-        get_intent_result = main.ONOScli1.intents( json_format=False )
-        main.log.info( "intents = " + get_intent_result )
-
-        time.sleep( 10 )
-        get_flows_result = main.ONOScli1.flows( json_format=False )
-        main.log.info( "flows = " + get_flows_result )
-
-        count = 1
-        i = 8
-        Ping_Result = main.TRUE
-
-        main.log.info( "\n\nh" + str( i ) + " is Pinging h" + str( i + 2 ) )
-        ping = main.Mininet1.pingHost(
-            src="h" + str( i ), target="h" + str( i + 2 ) )
-        if ping == main.FALSE and count < 3:
-            count += 1
-            Ping_Result = main.FALSE
-            main.log.report( "Ping between h" +
-                             str( i ) +
-                             " and h" +
-                             str( i +
-                                  2 ) +
-                             " failed. Making attempt number " +
-                             str( count ) +
-                             " in 2 seconds" )
-            time.sleep( 2 )
-        elif ping == main.FALSE:
-            main.log.report( "All ping attempts between h" +
-                             str( i ) +
-                             " and h" +
-                             str( i +
-                                  10 ) +
-                             "have failed" )
-            Ping_Result = main.FALSE
-        elif ping == main.TRUE:
-            main.log.info( "Ping test between h" +
-                           str( i ) +
-                           " and h" +
-                           str( i +
-                                2 ) +
-                           "passed!" )
-            Ping_Result = main.TRUE
-        else:
-            main.log.info( "Unknown error" )
-            Ping_Result = main.ERROR
-
-        if Ping_Result == main.FALSE:
-            main.log.report( "Ping test failed." )
-            # main.cleanup()
-            # main.exit()
-        if Ping_Result == main.TRUE:
-            main.log.report( "Ping all successful" )
-
-        p_intent_result = p_intent_result1 and p_intent_result2
-        if p_intent_result == main.TRUE:
-            main.log.info(
-                "Multi point intent with rewrite mac address installation successful" )
-        else:
-            main.log.info(
-                "Multi point intent with rewrite mac address installation failed" )
-
-        case33_result = p_intent_result and Ping_Result
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=case33_result,
-            onpass="Ping all test after multipoint to single point intent addition with rewrite mac address successful",
-            onfail="Ping all test after multipoint to single point intent addition with rewrite mac address failed" )
diff --git a/TestON/tests/MultiProd/MultiProd.params b/TestON/tests/MultiProd/MultiProd.params
index 6e5c85e..4818d09 100755
--- a/TestON/tests/MultiProd/MultiProd.params
+++ b/TestON/tests/MultiProd/MultiProd.params
@@ -1,7 +1,6 @@
 <PARAMS>
     
-    <testcases>1,4,10,5,6,7,8,6,8,9,8,31,32,8,33,8</testcases>    
-
+    <testcases>1,4,10,5,6,7,8,6,8,9,8,31,32,8,33,8</testcases>
     #Environment variables
     <ENV>
         <cellName>multi_test</cellName>
diff --git a/TestON/tests/MultiProd/MultiProd.py b/TestON/tests/MultiProd/MultiProd.py
index 52519d8..eca4da5 100644
--- a/TestON/tests/MultiProd/MultiProd.py
+++ b/TestON/tests/MultiProd/MultiProd.py
@@ -637,10 +637,8 @@
         main.step( "Determine the current number of switches and links" )
         topologyOutput = main.ONOScli1.topology()
         topologyResult = main.ONOSbench.getTopology( topologyOutput )
-        activeSwitches = topologyResult[ 'devices' ]
-        links = topologyResult[ 'links' ]
-        print "activeSwitches = ", type( activeSwitches )
-        print "links = ", type( links )
+        activeSwitches = topologyResult[ 'deviceCount' ]
+        links = topologyResult[ 'linkCount' ]
         main.log.info(
             "Currently there are %s switches and %s links" %
             ( str( activeSwitches ), str( links ) ) )
@@ -1535,39 +1533,54 @@
         main.Mininet1.verifyStaticGWandMAC( host='h9' )
         main.Mininet1.verifyStaticGWandMAC( host='h10' )
 
+        ingressDevice1=main.params[ 'MULTIPOINT_INTENT' ][ 'device1' ]
+        ingressDevice2=main.params[ 'MULTIPOINT_INTENT' ][ 'device2' ]
+        ingressDeviceList = []
+        ingressDeviceList.append( ingressDevice1 )
+        ingressDeviceList.append( ingressDevice2 )
+
         main.step( "Adding multipoint to singlepoint intent" )
         pIntentResult1 = main.ONOScli1.addMultipointToSinglepointIntent(
-            ingressDevice1=main.params[ 'MULTIPOINT_INTENT' ][ 'device1' ],
-            ingressDevice2=main.params[ 'MULTIPOINT_INTENT' ][ 'device2' ],
+            ingressDeviceList,
             egressDevice=main.params[ 'MULTIPOINT_INTENT' ][ 'device3' ],
             ipDst=main.params[ 'MULTIPOINT_INTENT' ][ 'ip1' ],
             setEthDst=main.params[ 'MULTIPOINT_INTENT' ][ 'mac1' ] )
 
+        ingressDevice1=main.params[ 'MULTIPOINT_INTENT' ][ 'device3' ]
+        ingressDevice2=main.params[ 'MULTIPOINT_INTENT' ][ 'device2' ]
+        ingressDeviceList = [ingressDevice1, ingressDevice2]
+
         pIntentResult2 = main.ONOScli1.addMultipointToSinglepointIntent(
-            ingressDevice1=main.params[ 'MULTIPOINT_INTENT' ][ 'device3' ],
-            ingressDevice2=main.params[ 'MULTIPOINT_INTENT' ][ 'device2' ],
+            ingressDeviceList,
             egressDevice=main.params[ 'MULTIPOINT_INTENT' ][ 'device1' ],
             ipDst=main.params[ 'MULTIPOINT_INTENT' ][ 'ip2' ],
             setEthDst=main.params[ 'MULTIPOINT_INTENT' ][ 'mac2' ] )
 
-        getIntentResult = main.ONOScli1.intents( jsonFormat=False )
-        main.log.info( "intents = " + getIntentResult )
+        pIntentResult = pIntentResult1 and pIntentResult2
+        if pIntentResult == main.FALSE:
+            main.log.info(
+                "Multi point to single point intent " +
+                "installation failed" )
+        else:
+            pIntentResult = main.TRUE 
+            getIntentResult = main.ONOScli1.intents( jsonFormat=False )
+            main.log.info( "intents = " + getIntentResult )
 
-        time.sleep( 10 )
-        getFlowsResult = main.ONOScli1.flows( jsonFormat=False )
-        main.log.info( "flows = " + getFlowsResult )
+            time.sleep( 10 )
+            getFlowsResult = main.ONOScli1.flows( jsonFormat=False )
+            main.log.info( "flows = " + getFlowsResult )
 
-        count = 1
-        i = 8
-        PingResult = main.TRUE
+            count = 1
+            i = 8
+            PingResult = main.TRUE
 
-        main.log.info( "\n\nh" + str( i ) + " is Pinging h" + str( i + 2 ) )
-        ping = main.Mininet1.pingHost(
+            main.log.info( "\n\nh" + str( i ) + " is Pinging h" + str( i + 2 ) )
+            ping = main.Mininet1.pingHost(
             src="h" + str( i ), target="h" + str( i + 2 ) )
-        if ping == main.FALSE and count < 3:
-            count += 1
-            PingResult = main.FALSE
-            main.log.report( "Ping between h" +
+            if ping == main.FALSE and count < 3:
+                count += 1
+                PingResult = main.FALSE
+                main.log.report( "Ping between h" +
                              str( i ) +
                              " and h" +
                              str( i +
@@ -1575,43 +1588,38 @@
                              " failed. Making attempt number " +
                              str( count ) +
                              " in 2 seconds" )
-            time.sleep( 2 )
-        elif ping == main.FALSE:
-            main.log.report( "All ping attempts between h" +
+                time.sleep( 2 )
+            elif ping == main.FALSE:
+                main.log.report( "All ping attempts between h" +
                              str( i ) +
                              " and h" +
                              str( i +
                                   10 ) +
                              "have failed" )
-            PingResult = main.FALSE
-        elif ping == main.TRUE:
-            main.log.info( "Ping test between h" +
+                PingResult = main.FALSE
+            elif ping == main.TRUE:
+                main.log.info( "Ping test between h" +
                            str( i ) +
                            " and h" +
                            str( i +
                                 2 ) +
                            "passed!" )
-            PingResult = main.TRUE
-        else:
-            main.log.info( "Unknown error" )
-            PingResult = main.ERROR
+                PingResult = main.TRUE
+            else:
+                main.log.info( "Unknown error" )
+                PingResult = main.ERROR
 
-        if PingResult == main.FALSE:
-            main.log.report( "Ping test failed." )
-            # main.cleanup()
-            # main.exit()
-        if PingResult == main.TRUE:
-            main.log.report( "Ping all successful" )
+            if PingResult == main.FALSE:
+                main.log.report( "Ping test failed." )
+                # main.cleanup()
+                # main.exit()
+            if PingResult == main.TRUE:
+                main.log.report( "Ping all successful" )
 
-        pIntentResult = pIntentResult1 and pIntentResult2
         if pIntentResult == main.TRUE:
             main.log.info(
                 "Multi point intent with rewrite mac " +
-                "address installation successful" )
-        else:
-            main.log.info(
-                "Multi point intent with rewrite mac" +
-                " address installation failed" )
+                "address installation and ping successful" )
 
         case33Result = pIntentResult and PingResult
         utilities.assertEquals(
diff --git a/TestON/tests/MultiProd/MultiProd.py.fixed b/TestON/tests/MultiProd/MultiProd.py.fixed
deleted file mode 100644
index e0e772a..0000000
--- a/TestON/tests/MultiProd/MultiProd.py.fixed
+++ /dev/null
@@ -1,1566 +0,0 @@
-
-# Testing the basic functionality of ONOS Next
-# For sanity and driver functionality excercises only.
-
-import time
-import json
-
-time.sleep( 1 )
-
-
-class MultiProd:
-
-    def __init__( self ):
-        self.default = ''
-
-    def CASE1( self, main ):
-        """
-        Startup sequence:
-        cell <name>
-        onos-verify-cell
-        onos-remove-raft-logs
-        git pull
-        mvn clean install
-        onos-package
-        onos-install -f
-        onos-wait-for-start
-        """
-        cell_name = main.params[ 'ENV' ][ 'cellName' ]
-        ONOS1_ip = main.params[ 'CTRL' ][ 'ip1' ]
-        ONOS2_ip = main.params[ 'CTRL' ][ 'ip2' ]
-        ONOS3_ip = main.params[ 'CTRL' ][ 'ip3' ]
-
-        main.case( "Setting up test environment" )
-        main.log.report(
-            "This testcase is testing setting up test environment" )
-        main.log.report( "__________________________________" )
-
-        main.step( "Applying cell variable to environment" )
-        cell_result1 = main.ONOSbench.set_cell( cell_name )
-        # cell_result2 = main.ONOScli1.set_cell( cell_name )
-        # cell_result3 = main.ONOScli2.set_cell( cell_name )
-        # cell_result4 = main.ONOScli3.set_cell( cell_name )
-        verify_result = main.ONOSbench.verify_cell()
-        cell_result = cell_result1
-
-        main.step( "Removing raft logs before a clen installation of ONOS" )
-        main.ONOSbench.onos_remove_raft_logs()
-
-        main.step( "Git checkout and pull master and get version" )
-        main.ONOSbench.git_checkout( "master" )
-        git_pull_result = main.ONOSbench.git_pull()
-        print "git_pull_result = ", git_pull_result
-        main.ONOSbench.get_version( report=True )
-
-        if git_pull_result == 1:
-            main.step( "Using mvn clean & install" )
-            main.ONOSbench.clean_install()
-
-        main.step( "Creating ONOS package" )
-        package_result = main.ONOSbench.onos_package()
-
-        # main.step( "Creating a cell" )
-        # cell_create_result = main.ONOSbench.create_cell_file( **************
-        # )
-
-        main.step( "Installing ONOS package" )
-        onos1_install_result = main.ONOSbench.onos_install(
-            options="-f",
-            node=ONOS1_ip )
-        onos2_install_result = main.ONOSbench.onos_install(
-            options="-f",
-            node=ONOS2_ip )
-        onos3_install_result = main.ONOSbench.onos_install(
-            options="-f",
-            node=ONOS3_ip )
-        onos_install_result = onos1_install_result and onos2_install_result \
-                                and onos3_install_result
-        if onos_install_result == main.TRUE:
-            main.log.report( "Installing ONOS package successful" )
-        else:
-            main.log.report( "Installing ONOS package failed" )
-
-        onos1_isup = main.ONOSbench.isup( ONOS1_ip )
-        onos2_isup = main.ONOSbench.isup( ONOS2_ip )
-        onos3_isup = main.ONOSbench.isup( ONOS3_ip )
-        onos_isup = onos1_isup and onos2_isup and onos3_isup
-        if onos_isup == main.TRUE:
-            main.log.report( "ONOS instances are up and ready" )
-        else:
-            main.log.report( "ONOS instances may not be up" )
-
-        main.step( "Starting ONOS service" )
-        start_result = main.TRUE
-        # start_result = main.ONOSbench.onos_start( ONOS1_ip )
-        startcli1 = main.ONOScli1.start_onos_cli( ONOS_ip=ONOS1_ip )
-        startcli2 = main.ONOScli2.start_onos_cli( ONOS_ip=ONOS2_ip )
-        startcli3 = main.ONOScli3.start_onos_cli( ONOS_ip=ONOS3_ip )
-        print startcli1
-        print startcli2
-        print startcli3
-
-        case1_result = ( package_result and cell_result and
-                         verify_result and onos_install_result
-                         and onos_isup and start_result )
-        utilities.assert_equals( expect=main.TRUE, actual=case1_result,
-                                 onpass="Test startup successful",
-                                 onfail="Test startup NOT successful" )
-
-    def CASE11( self, main ):
-        """
-        Cleanup sequence:
-        onos-service <node_ip> stop
-        onos-uninstall
-
-        TODO: Define rest of cleanup
-
-        """
-        ONOS1_ip = main.params[ 'CTRL' ][ 'ip1' ]
-        ONOS2_ip = main.params[ 'CTRL' ][ 'ip2' ]
-        ONOS3_ip = main.params[ 'CTRL' ][ 'ip3' ]
-
-        main.case( "Cleaning up test environment" )
-
-        main.step( "Testing ONOS kill function" )
-        kill_result1 = main.ONOSbench.onos_kill( ONOS1_ip )
-        kill_result2 = main.ONOSbench.onos_kill( ONOS2_ip )
-        kill_result3 = main.ONOSbench.onos_kill( ONOS3_ip )
-        kill_result = kill_result1 and kill_result2 and kill_result3
-
-        main.step( "Stopping ONOS service" )
-        stop_result1 = main.ONOSbench.onos_stop( ONOS1_ip )
-        stop_result2 = main.ONOSbench.onos_stop( ONOS2_ip )
-        stop_result3 = main.ONOSbench.onos_stop( ONOS3_ip )
-        stop_result = stop_result1 and stop_result2 and stop_result3
- 
-        main.step( "Uninstalling ONOS service" )
-        uninstall_result = main.ONOSbench.onos_uninstall()
-
-        case11_result = kill_result and stop_result and uninstall_result
-        utilities.assert_equals( expect=main.TRUE, actual=case11_result,
-                                 onpass="Cleanup successful",
-                                 onfail="Cleanup failed" )
-
-    def CASE3( self, main ):
-        """
-        Test 'onos' command and its functionality in driver
-        """
-        ONOS1_ip = main.params[ 'CTRL' ][ 'ip1' ]
-        ONOS2_ip = main.params[ 'CTRL' ][ 'ip2' ]
-        ONOS3_ip = main.params[ 'CTRL' ][ 'ip3' ]
-
-        main.case( "Testing 'onos' command" )
-
-        main.step( "Sending command 'onos -w <onos-ip> system:name'" )
-        cmdstr1 = "system:name"
-        cmd_result1 = main.ONOSbench.onos_cli( ONOS1_ip, cmdstr1 )
-        main.log.info( "onos command returned: " + cmd_result1 )
-        cmd_result2 = main.ONOSbench.onos_cli( ONOS2_ip, cmdstr1 )
-        main.log.info( "onos command returned: " + cmd_result2 )
-        cmd_result3 = main.ONOSbench.onos_cli( ONOS3_ip, cmdstr1 )
-        main.log.info( "onos command returned: " + cmd_result3 )
-
-        main.step( "Sending command 'onos -w <onos-ip> onos:topology'" )
-        cmdstr2 = "onos:topology"
-        cmd_result4 = main.ONOSbench.onos_cli( ONOS1_ip, cmdstr2 )
-        main.log.info( "onos command returned: " + cmd_result4 )
-        cmd_result5 = main.ONOSbench.onos_cli( ONOS2_ip, cmdstr2 )
-        main.log.info( "onos command returned: " + cmd_result5 )
-        cmd_result6 = main.ONOSbench.onos_cli( ONOS3_ip, cmdstr2 )
-        main.log.info( "onos command returned: " + cmd_result6 )
-
-    def CASE4( self, main ):
-        import re
-        import time
-        ONOS1_ip = main.params[ 'CTRL' ][ 'ip1' ]
-        ONOS2_ip = main.params[ 'CTRL' ][ 'ip2' ]
-        ONOS3_ip = main.params[ 'CTRL' ][ 'ip3' ]
-        ONOS1_port = main.params[ 'CTRL' ][ 'port1' ]
-        ONOS2_port = main.params[ 'CTRL' ][ 'port2' ]
-        ONOS3_port = main.params[ 'CTRL' ][ 'port3' ]
-
-        main.log.report(
-            "This testcase is testing the assignment of all the switches to \
-            all controllers and discovering the hosts in reactive mode" )
-        main.log.report( "__________________________________" )
-        main.case( "Pingall Test(No intents are added)" )
-        main.step( "Assigning switches to controllers" )
-        for i in range( 1, 29 ):  # 1 to ( num of switches +1 )
-            main.Mininet1.assign_sw_controller(
-                sw=str( i ),
-                count=3,
-                ip1=ONOS1_ip,
-                port1=ONOS1_port,
-                ip2=ONOS2_ip,
-                port2=ONOS2_port,
-                ip3=ONOS3_ip,
-                port3=ONOS3_port )
-
-        switch_mastership = main.TRUE
-        for i in range( 1, 29 ):
-            response = main.Mininet1.get_sw_controller( "s" + str( i ) )
-            print( "Response is " + str( response ) )
-            if re.search( "tcp:" + ONOS1_ip, response ):
-                switch_mastership = switch_mastership and main.TRUE
-            else:
-                switch_mastership = main.FALSE
-
-        if switch_mastership == main.TRUE:
-            main.log.report( "Controller assignment successfull" )
-        else:
-            main.log.report( "Controller assignment failed" )
-        # REACTIVE FWD test
-        main.step( "Pingall" )
-        ping_result = main.FALSE
-        time1 = time.time()
-        ping_result = main.Mininet1.pingall()
-        time2 = time.time()
-        print "Time for pingall: %2f seconds" % ( time2 - time1 )
-
-        case4_result = switch_mastership and ping_result
-        if ping_result == main.TRUE:
-            main.log.report( "Pingall Test in reactive mode to discover \
-                             the hosts successful" )
-        else:
-            main.log.report( "Pingall Test in reactive mode to discover \
-                             the hosts failed" )
-
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=case4_result,
-            onpass="Controller assignment and Pingall Test successful",
-            onfail="Controller assignment and Pingall Test NOT successful" )
-
-    def CASE5( self, main ):
-        import json
-        from subprocess import Popen, PIPE
-        # assumes that sts is already in you PYTHONPATH
-        from sts.topology.teston_topology import TestONTopology
-
-        main.log.report( "This testcase is testing if all ONOS nodes are in \
-                         topology sync with mininet and its peer ONOS nodes" )
-        main.log.report( "__________________________________" )
-        main.case(
-            "Testing Mininet topology with the topology \
-            of multi instances ONOS" )
-        main.step( "Collecting topology information from ONOS" )
-        devices1 = main.ONOScli1.devices()
-        devices2 = main.ONOScli2.devices()
-        devices3 = main.ONOScli3.devices()
-        hosts1 = main.ONOScli1.hosts()
-        hosts2 = main.ONOScli2.hosts()
-        hosts3 = main.ONOScli3.hosts()
-        ports1 = main.ONOScli1.ports()
-        ports2 = main.ONOScli2.ports()
-        ports3 = main.ONOScli3.ports()
-        links1 = main.ONOScli1.links()
-        links2 = main.ONOScli2.links()
-        links3 = main.ONOScli3.links()
-
-        main.step( "Start continuous pings" )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source1' ],
-            target=main.params[ 'PING' ][ 'target1' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source2' ],
-            target=main.params[ 'PING' ][ 'target2' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source3' ],
-            target=main.params[ 'PING' ][ 'target3' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source4' ],
-            target=main.params[ 'PING' ][ 'target4' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source5' ],
-            target=main.params[ 'PING' ][ 'target5' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source6' ],
-            target=main.params[ 'PING' ][ 'target6' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source7' ],
-            target=main.params[ 'PING' ][ 'target7' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source8' ],
-            target=main.params[ 'PING' ][ 'target8' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source9' ],
-            target=main.params[ 'PING' ][ 'target9' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source10' ],
-            target=main.params[ 'PING' ][ 'target10' ],
-            pingTime=500 )
-
-        main.step( "Create TestONTopology object" )
-        global ctrls
-        ctrls = []
-        count = 1
-        while True:
-            temp = ()
-            if ( 'ip' + str( count ) ) in main.params[ 'CTRL' ]:
-                temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
-                temp = temp + ( "ONOS" + str( count ), )
-                temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
-                temp = temp + \
-                    ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
-                ctrls.append( temp )
-                count = count + 1
-            else:
-                break
-        global MNTopo
-        Topo = TestONTopology(
-            main.Mininet1,
-            ctrls )  # can also add Intent API info for intent operations
-        MNTopo = Topo
-
-        Topology_Check = main.TRUE
-        main.step( "Compare ONOS Topology to MN Topology" )
-
-        switches_results1 = main.Mininet1.compare_switches(
-            MNTopo,
-            json.loads( devices1 ) )
-        print "switches_Result1 = ", switches_results1
-        utilities.assert_equals( expect=main.TRUE, actual=switches_results1,
-                                 onpass="ONOS1 Switches view is correct",
-                                 onfail="ONOS1 Switches view is incorrect" )
-
-        switches_results2 = main.Mininet1.compare_switches(
-            MNTopo,
-            json.loads( devices2 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=switches_results2,
-                                 onpass="ONOS2 Switches view is correct",
-                                 onfail="ONOS2 Switches view is incorrect" )
-
-        switches_results3 = main.Mininet1.compare_switches(
-            MNTopo,
-            json.loads( devices3 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=switches_results3,
-                                 onpass="ONOS3 Switches view is correct",
-                                 onfail="ONOS3 Switches view is incorrect" )
-
-        ports_results1 = main.Mininet1.compare_ports(
-                            MNTopo, json.loads( ports1 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=ports_results1,
-                onpass="ONOS1 Ports view is correct",
-                onfail="ONOS1 Ports view is incorrect" )
-
-        ports_results2 = main.Mininet1.compare_ports(
-                            MNTopo, json.loads( ports2 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=ports_results2,
-                onpass="ONOS2 Ports view is correct",
-                onfail="ONOS2 Ports view is incorrect" )
-
-        ports_results3 = main.Mininet1.compare_ports(
-                            MNTopo, json.loads( ports3 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=ports_results3,
-                onpass="ONOS3 Ports view is correct",
-                onfail="ONOS3 Ports view is incorrect" )
-        
-        links_results1 = main.Mininet1.compare_links(
-            MNTopo,
-            json.loads( links1 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=links_results1,
-                                 onpass="ONOS1 Links view is correct",
-                                 onfail="ONOS1 Links view is incorrect" )
-
-        links_results2 = main.Mininet1.compare_links(
-            MNTopo,
-            json.loads( links2 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=links_results2,
-                                 onpass="ONOS2 Links view is correct",
-                                 onfail="ONOS2 Links view is incorrect" )
-
-        links_results3 = main.Mininet1.compare_links(
-            MNTopo,
-            json.loads( links3 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=links_results3,
-                                 onpass="ONOS2 Links view is correct",
-                                 onfail="ONOS2 Links view is incorrect" )
-
-        topo_result = switches_results1 and switches_results2 and \
-        switches_results3\
-        and ports_results1 and ports_results2 and ports_results3\
-        and links_results1 and links_results2 and links_results3
-
-        '''
-            topo_result = switches_results1 and switches_results2 and \
-                        switches_results3 and links_results1 and \
-                        links_results2 and links_results3
-        '''
-
-        if topo_result == main.TRUE:
-            main.log.report(
-                "Topology Check Test with mininet and \
-                ONOS instances successful" )
-        else:
-            main.log.report(
-                "Topology Check Test with mininet and \
-                ONOS instances failed" )
-
-        utilities.assert_equals( expect=main.TRUE, actual=topo_result,
-                                 onpass="Topology Check Test successful",
-                                 onfail="Topology Check Test NOT successful" )
-
-    def CASE10( self ):
-        main.log.report(
-            "This testcase uninstalls the reactive forwarding app" )
-        main.log.report( "__________________________________" )
-        main.case( "Uninstalling reactive forwarding app" )
-        # Unistall onos-app-fwd app to disable reactive forwarding
-        appUninstall_result1 = main.ONOScli1.feature_uninstall(
-            "onos-app-fwd" )
-        appUninstall_result2 = main.ONOScli2.feature_uninstall(
-            "onos-app-fwd" )
-        appUninstall_result3 = main.ONOScli3.feature_uninstall(
-            "onos-app-fwd" )
-        main.log.info( "onos-app-fwd uninstalled" )
-
-        # After reactive forwarding is disabled,
-        # the reactive flows on switches timeout in 10-15s
-        # So sleep for 15s
-        time.sleep( 15 )
-
-        hosts = main.ONOScli1.hosts()
-        main.log.info( hosts )
-
-        case10_result = appUninstall_result1 and appUninstall_result2 and \
-                        appUninstall_result3
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=case10_result,
-            onpass="Reactive forwarding app uninstallation successful",
-            onfail="Reactive forwarding app uninstallation failed" )
-
-    def CASE6( self ):
-        main.log.report(
-            "This testcase is testing the addition of host intents and \
-            then doing pingall" )
-        main.log.report( "__________________________________" )
-        main.case( "Obtaining hostsfor adding host intents" )
-        main.step( "Get hosts" )
-        hosts = main.ONOScli1.hosts()
-        main.log.info( hosts )
-
-        main.step( "Get all devices id" )
-        devices_id_list = main.ONOScli1.get_all_devices_id()
-        main.log.info( devices_id_list )
-
-        # ONOS displays the hosts in hex format unlike mininet
-        # which does in decimal format
-        # So take care while adding intents
-
-        """
-        main.step(
-            "Add host intents for mn hosts
-            (h8-h18,h9-h19,h10-h20,h11-h21,h12-h22,h13-h23,h14-h24,
-            h15-h25,h16-h26,h17-h27)" )
-        hth_intent_result = main.ONOScli1.add_host_intent(
-                            "00:00:00:00:00:08/-1", "00:00:00:00:00:12/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent(
-                            "00:00:00:00:00:09/-1", "00:00:00:00:00:13/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent(
-                            "00:00:00:00:00:0A/-1", "00:00:00:00:00:14/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent(
-                            "00:00:00:00:00:0B/-1", "00:00:00:00:00:15/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent(
-                            "00:00:00:00:00:0C/-1", "00:00:00:00:00:16/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent(
-                            "00:00:00:00:00:0D/-1", "00:00:00:00:00:17/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent(
-                            "00:00:00:00:00:0E/-1", "00:00:00:00:00:18/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent(
-                            "00:00:00:00:00:0F/-1", "00:00:00:00:00:19/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent(
-                            "00:00:00:00:00:10/-1", "00:00:00:00:00:1A/-1" )
-        hth_intent_result = main.ONOScli1.add_host_intent(
-                            "00:00:00:00:00:11/-1", "00:00:00:00:00:1B/-1" )
-        """
-        for i in range( 8, 18 ):
-            main.log.info(
-                "Adding host intent between h" + str( i ) +
-                " and h" + str( i + 10 ) )
-            host1 = "00:00:00:00:00:" + \
-                    str( hex( i )[ 2: ] ).zfill( 2 ).upper()
-            host2 = "00:00:00:00:00:" + \
-                    str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
-            # NOTE: get host can return None
-            # TODO: handle this
-            host1_id = main.ONOScli1.get_host( host1 )[ 'id' ]
-            host2_id = main.ONOScli1.get_host( host2 )[ 'id' ]
-            tmp_result = main.ONOScli1.add_host_intent( host1_id, host2_id )
-
-        flowHandle = main.ONOScli1.flows()
-        main.log.info( "flows:" + flowHandle )
-
-        count = 1
-        i = 8
-        Ping_Result = main.TRUE
-        while i < 18:
-            main.log.info(
-                "\n\nh" + str( i ) + " is Pinging h" + str( i + 10 ) )
-            ping = main.Mininet1.pingHost(
-                src="h" + str( i ), target="h" + str( i + 10 ) )
-            if ping == main.FALSE and count < 5:
-                count += 1
-                # i = 8
-                Ping_Result = main.FALSE
-                main.log.report( "Ping between h" +
-                                 str( i ) +
-                                 " and h" +
-                                 str( i +
-                                      10 ) +
-                                 " failed. Making attempt number " +
-                                 str( count ) +
-                                 " in 2 seconds" )
-                time.sleep( 2 )
-            elif ping == main.FALSE:
-                main.log.report( "All ping attempts between h" +
-                                 str( i ) +
-                                 " and h" +
-                                 str( i +
-                                      10 ) +
-                                 "have failed" )
-                i = 19
-                Ping_Result = main.FALSE
-            elif ping == main.TRUE:
-                main.log.info( "Ping test between h" +
-                               str( i ) +
-                               " and h" +
-                               str( i +
-                                    10 ) +
-                               "passed!" )
-                i += 1
-                Ping_Result = main.TRUE
-            else:
-                main.log.info( "Unknown error" )
-                Ping_Result = main.ERROR
-        if Ping_Result == main.FALSE:
-            main.log.report(
-                "Host intents have not ben installed correctly. Cleaning up" )
-            # main.cleanup()
-            # main.exit()
-        if Ping_Result == main.TRUE:
-            main.log.report( "Host intents have been installed correctly" )
-
-        case6_result = Ping_Result
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=case6_result,
-            onpass="Host intent addition and Pingall Test successful",
-            onfail="Host intent addition and Pingall Test NOT successful" )
-
-    def CASE7( self, main ):
-
-        from sts.topology.teston_topology import TestONTopology
-        ONOS1_ip = main.params[ 'CTRL' ][ 'ip1' ]
-
-        link_sleep = int( main.params[ 'timers' ][ 'LinkDiscovery' ] )
-
-        main.log.report(
-            "This testscase is killing a link to ensure that \
-            link discovery is consistent" )
-        main.log.report( "__________________________________" )
-        main.case(
-            "Killing a link to ensure that \
-            Link Discovery is Working Properly" )
-        main.step( "Start continuous pings" )
-
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source1' ],
-            target=main.params[ 'PING' ][ 'target1' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source2' ],
-            target=main.params[ 'PING' ][ 'target2' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source3' ],
-            target=main.params[ 'PING' ][ 'target3' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source4' ],
-            target=main.params[ 'PING' ][ 'target4' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source5' ],
-            target=main.params[ 'PING' ][ 'target5' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source6' ],
-            target=main.params[ 'PING' ][ 'target6' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source7' ],
-            target=main.params[ 'PING' ][ 'target7' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source8' ],
-            target=main.params[ 'PING' ][ 'target8' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source9' ],
-            target=main.params[ 'PING' ][ 'target9' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source10' ],
-            target=main.params[ 'PING' ][ 'target10' ],
-            pingTime=500 )
-
-        main.step( "Determine the current number of switches and links" )
-        topology_output = main.ONOScli1.topology()
-        topology_result = main.ONOSbench.get_topology( topology_output )
-        activeSwitches = topology_result[ 'devices' ]
-        links = topology_result[ 'links' ]
-        main.log.info(
-            "Currently there are %s switches and %s links" %
-            ( str( activeSwitches ), str( links ) ) )
-
-        main.step( "Kill Link between s3 and s28" )
-        main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
-        time.sleep( link_sleep )
-        topology_output = main.ONOScli2.topology()
-        Link_Down = main.ONOSbench.check_status(
-            topology_output, activeSwitches, str(
-                int( links ) - 2 ) )
-        if Link_Down == main.TRUE:
-            main.log.report( "Link Down discovered properly" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=Link_Down,
-            onpass="Link Down discovered properly",
-            onfail="Link down was not discovered in " +
-            str( link_sleep ) +
-            " seconds" )
-
-        main.step( "Bring link between s3 and s28 back up" )
-        Link_Up = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
-        time.sleep( link_sleep )
-        topology_output = main.ONOScli2.topology()
-        Link_Up = main.ONOSbench.check_status(
-            topology_output,
-            activeSwitches,
-            str( links ) )
-        if Link_Up == main.TRUE:
-            main.log.report( "Link up discovered properly" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=Link_Up,
-            onpass="Link up discovered properly",
-            onfail="Link up was not discovered in " +
-            str( link_sleep ) +
-            " seconds" )
-
-        main.step( "Compare ONOS Topology to MN Topology" )
-        main.case(
-            "Testing Mininet topology with the topology of \
-            multi instances ONOS" )
-        main.step( "Collecting topology information from ONOS" )
-        devices1 = main.ONOScli1.devices()
-        devices2 = main.ONOScli2.devices()
-        devices3 = main.ONOScli3.devices()
-        hosts1 = main.ONOScli1.hosts()
-        hosts2 = main.ONOScli2.hosts()
-        hosts3 = main.ONOScli3.hosts()
-        ports1 = main.ONOScli1.ports()
-        ports2 = main.ONOScli2.ports()
-        ports3 = main.ONOScli3.ports()
-        links1 = main.ONOScli1.links()
-        links2 = main.ONOScli2.links()
-        links3 = main.ONOScli3.links()
-
-        main.step( "Start continuous pings" )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source1' ],
-            target=main.params[ 'PING' ][ 'target1' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source2' ],
-            target=main.params[ 'PING' ][ 'target2' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source3' ],
-            target=main.params[ 'PING' ][ 'target3' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source4' ],
-            target=main.params[ 'PING' ][ 'target4' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source5' ],
-            target=main.params[ 'PING' ][ 'target5' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source6' ],
-            target=main.params[ 'PING' ][ 'target6' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source7' ],
-            target=main.params[ 'PING' ][ 'target7' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source8' ],
-            target=main.params[ 'PING' ][ 'target8' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source9' ],
-            target=main.params[ 'PING' ][ 'target9' ],
-            pingTime=500 )
-        main.Mininet2.pingLong(
-            src=main.params[ 'PING' ][ 'source10' ],
-            target=main.params[ 'PING' ][ 'target10' ],
-            pingTime=500 )
-
-        main.step( "Create TestONTopology object" )
-        global ctrls
-        ctrls = []
-        count = 1
-        while True:
-            temp = ()
-            if ( 'ip' + str( count ) ) in main.params[ 'CTRL' ]:
-                temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
-                temp = temp + ( "ONOS" + str( count ), )
-                temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
-                temp = temp + \
-                    ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
-                ctrls.append( temp )
-                count = count + 1
-            else:
-                break
-        global MNTopo
-        Topo = TestONTopology(
-            main.Mininet1,
-            ctrls )  # can also add Intent API info for intent operations
-        MNTopo = Topo
-
-        Topology_Check = main.TRUE
-        main.step( "Compare ONOS Topology to MN Topology" )
-
-        switches_results1 = main.Mininet1.compare_switches(
-            MNTopo,
-            json.loads( devices1 ) )
-        print "switches_Result1 = ", switches_results1
-        utilities.assert_equals( expect=main.TRUE, actual=switches_results1,
-                                 onpass="ONOS1 Switches view is correct",
-                                 onfail="ONOS1 Switches view is incorrect" )
-
-        switches_results2 = main.Mininet1.compare_switches(
-            MNTopo,
-            json.loads( devices2 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=switches_results2,
-                                 onpass="ONOS2 Switches view is correct",
-                                 onfail="ONOS2 Switches view is incorrect" )
-
-        switches_results3 = main.Mininet1.compare_switches(
-            MNTopo,
-            json.loads( devices3 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=switches_results3,
-                                 onpass="ONOS3 Switches view is correct",
-                                 onfail="ONOS3 Switches view is incorrect" )
-
-        """
-        ports_results1 =  main.Mininet1.compare_ports(
-                            MNTopo, json.loads( ports1 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=ports_results1,
-                onpass="ONOS1 Ports view is correct",
-                onfail="ONOS1 Ports view is incorrect" )
-
-        ports_results2 =  main.Mininet1.compare_ports(
-                            MNTopo, json.loads( ports2 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=ports_results2,
-                onpass="ONOS2 Ports view is correct",
-                onfail="ONOS2 Ports view is incorrect" )
-
-        ports_results3 =  main.Mininet1.compare_ports(
-                            MNTopo, json.loads( ports3 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=ports_results3,
-                onpass="ONOS3 Ports view is correct",
-                onfail="ONOS3 Ports view is incorrect" )
-        """
-        links_results1 = main.Mininet1.compare_links(
-            MNTopo,
-            json.loads( links1 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=links_results1,
-                                 onpass="ONOS1 Links view is correct",
-                                 onfail="ONOS1 Links view is incorrect" )
-
-        links_results2 = main.Mininet1.compare_links(
-            MNTopo,
-            json.loads( links2 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=links_results2,
-                                 onpass="ONOS2 Links view is correct",
-                                 onfail="ONOS2 Links view is incorrect" )
-
-        links_results3 = main.Mininet1.compare_links(
-            MNTopo,
-            json.loads( links3 ) )
-        utilities.assert_equals( expect=main.TRUE, actual=links_results3,
-                                 onpass="ONOS2 Links view is correct",
-                                 onfail="ONOS2 Links view is incorrect" )
-
-        # topo_result = switches_results1 and switches_results2 and \
-        # switches_results3  and ports_results1 and ports_results2 and \
-        # ports_results3 and links_results1 and links_results2 and \
-        # links_results3
-
-        topo_result = switches_results1 and switches_results2 \
-                        and switches_results3 and links_results1 and \
-                        links_results2 and links_results3
-
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=topo_result and Link_Up and Link_Down,
-            onpass="Topology Check Test successful",
-            onfail="Topology Check Test NOT successful" )
-
-    def CASE8( self ):
-        """
-        Intent removal
-        """
-        main.log.report(
-            "This testcase removes host any previously added intents" )
-        main.log.report( "__________________________________" )
-        main.log.info( "Removing any previously installed intents" )
-        main.case( "Removing intents" )
-        main.step( "Obtain the intent id's" )
-        intent_result = main.ONOScli1.intents( json_format=False )
-
-        intent_linewise = intent_result.split( "\n" )
-        intentList = []
-        for line in intent_linewise:
-            if line.startswith( "id=" ):
-                intentList.append( line )
-
-        intentids = []
-        for line in intentList:
-            intentids.append( line.split( "," )[ 0 ].split( "=" )[ 1 ] )
-        for id in intentids:
-            main.log.info( "id = " + id )
-
-        main.step(
-            "Iterate through the intentids list and remove each intent" )
-        for id in intentids:
-            main.ONOScli1.remove_intent( intent_id=id )
-
-        intent_result = main.ONOScli1.intents( json_format=False )
-        main.log.info( "intent_result = " + intent_result )
-        case8_result = main.TRUE
-
-        i = 8
-        Ping_Result = main.TRUE
-        while i < 18:
-            main.log.info(
-                "\n\nh" + str( i ) + " is Pinging h" + str( i + 10 ) )
-            ping = main.Mininet1.pingHost(
-                src="h" + str( i ), target="h" + str( i + 10 ) )
-            if ping == main.TRUE:
-                i = 19
-                Ping_Result = main.TRUE
-            elif ping == main.FALSE:
-                i += 1
-                Ping_Result = main.FALSE
-            else:
-                main.log.info( "Unknown error" )
-                Ping_Result = main.ERROR
-
-        # Note: If the ping result failed, that means the intents have been
-        # withdrawn correctly.
-        if Ping_Result == main.TRUE:
-            main.log.report( "Host intents have not been withdrawn correctly" )
-            # main.cleanup()
-            # main.exit()
-        if Ping_Result == main.FALSE:
-            main.log.report( "Host intents have been withdrawn correctly" )
-
-        case8_result = case8_result and Ping_Result
-
-        if case8_result == main.FALSE:
-            main.log.report( "Intent removal successful" )
-        else:
-            main.log.report( "Intent removal failed" )
-
-        utilities.assert_equals( expect=main.FALSE, actual=case8_result,
-                                 onpass="Intent removal test failed",
-                                 onfail="Intent removal test successful" )
-
-    def CASE9( self ):
-        """
-        This test case adds point intents. Make sure you run test case 8
-        which is host intent removal before executing this test case.
-        Else the host intents flows will persist on switches and the ping
-         would work even if there is some issue with the point intent's flows
-        """
-        main.log.report(
-            "This testcase adds point intents and then does pingall" )
-        main.log.report( "__________________________________" )
-        main.log.info( "Adding point intents" )
-        main.case(
-                    "Adding bidirectional point for mn hosts \
-                    h8-h18 h9-h19 h10-h20 h11-h21 h12-h22 h13-h23 \
-                    h14-h24 h15-h25 h16-h26 h17-h27" )
-
-        main.step( "Add point-to-point intents for mininet hosts \
-                   h8 and h18 or ONOS hosts h8 and h12" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003008/1",
-            "of:0000000000006018/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006018/1",
-            "of:0000000000003008/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step( "Add point-to-point intents for mininet hosts \
-                    h9 and h19 or ONOS hosts h9 and h13" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003009/1",
-            "of:0000000000006019/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006019/1",
-            "of:0000000000003009/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step( "Add point-to-point intents for mininet hosts \
-                    h10 and h20 or ONOS hosts hA and h14" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003010/1",
-            "of:0000000000006020/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006020/1",
-            "of:0000000000003010/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step( "Add point-to-point intents for mininet hosts \
-                    h11 and h21 or ONOS hosts hB and h15" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003011/1",
-            "of:0000000000006021/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006021/1",
-            "of:0000000000003011/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step( "Add point-to-point intents for mininet hosts \
-                    h12 and h22 or ONOS hosts hC and h16" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003012/1",
-            "of:0000000000006022/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006022/1",
-            "of:0000000000003012/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step( "Add point-to-point intents for mininet hosts \
-                    h13 and h23 or ONOS hosts hD and h17" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003013/1",
-            "of:0000000000006023/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006023/1",
-            "of:0000000000003013/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step( "Add point-to-point intents for mininet hosts \
-                    h14 and h24 or ONOS hosts hE and h18" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003014/1",
-            "of:0000000000006024/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006024/1",
-            "of:0000000000003014/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step( "Add point-to-point intents for mininet hosts \
-                    h15 and h25 or ONOS hosts hF and h19" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003015/1",
-            "of:0000000000006025/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006025/1",
-            "of:0000000000003015/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step( "Add point-to-point intents for mininet hosts \
-                    h16 and h26 or ONOS hosts h10 and h1A" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003016/1",
-            "of:0000000000006026/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006026/1",
-            "of:0000000000003016/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        main.step( "Add point-to-point intents for mininet hosts \
-                    h17 and h27 or ONOS hosts h11 and h1B" )
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000003017/1",
-            "of:0000000000006027/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        ptp_intent_result = main.ONOScli1.add_point_intent(
-            "of:0000000000006027/1",
-            "of:0000000000003017/1" )
-        if ptp_intent_result == main.TRUE:
-            get_intent_result = main.ONOScli1.intents()
-            main.log.info( "Point to point intent install successful" )
-            # main.log.info( get_intent_result )
-
-        print("___________________________________________________________" )
-
-        flowHandle = main.ONOScli1.flows()
-        main.log.info( "flows :" + flowHandle )
-
-        count = 1
-        i = 8
-        Ping_Result = main.TRUE
-        while i < 18:
-            main.log.info(
-                "\n\nh" + str( i ) + " is Pinging h" + str( i + 10 ) )
-            ping = main.Mininet1.pingHost(
-                src="h" + str( i ), target="h" + str( i + 10 ) )
-            if ping == main.FALSE and count < 5:
-                count += 1
-                # i = 8
-                Ping_Result = main.FALSE
-                main.log.report( "Ping between h" +
-                                 str( i ) +
-                                 " and h" +
-                                 str( i +
-                                      10 ) +
-                                 " failed. Making attempt number " +
-                                 str( count ) +
-                                 " in 2 seconds" )
-                time.sleep( 2 )
-            elif ping == main.FALSE:
-                main.log.report( "All ping attempts between h" +
-                                 str( i ) +
-                                 " and h" +
-                                 str( i +
-                                      10 ) +
-                                 "have failed" )
-                i = 19
-                Ping_Result = main.FALSE
-            elif ping == main.TRUE:
-                main.log.info( "Ping test between h" +
-                               str( i ) +
-                               " and h" +
-                               str( i +
-                                    10 ) +
-                               "passed!" )
-                i += 1
-                Ping_Result = main.TRUE
-            else:
-                main.log.info( "Unknown error" )
-                Ping_Result = main.ERROR
-
-        if Ping_Result == main.FALSE:
-            main.log.report(
-                "Ping all test after Point intents addition failed. \
-                Cleaning up" )
-            # main.cleanup()
-            # main.exit()
-        if Ping_Result == main.TRUE:
-            main.log.report(
-                "Ping all test after Point intents addition successful" )
-
-        case8_result = Ping_Result
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=case8_result,
-            onpass="Ping all test after Point intents addition successful",
-            onfail="Ping all test after Point intents addition failed" )
-
-    def CASE31( self ):
-        """
-            This test case adds point intent related to SDN-IP
-            matching on ICMP ( ethertype=IPV4, ipProto=1 )
-        """
-        import json
-
-        main.log.report(
-            '''This test case adds point intent related to SDN-IP
-            matching on ICMP''' )
-        main.case(
-            '''Adding bidirectional point intent related to SDN-IP
-            matching on ICMP''' )
-        main.step( "Adding bidirectional point intent" )
-        # add-point-intent --ipSrc=10.0.0.8/32 --ipDst=10.0.0.18/32
-        # --ethType=IPV4 --ipProto=1  of:0000000000003008/1
-        # of:0000000000006018/1
-
-        hosts_json = json.loads( main.ONOScli1.hosts() )
-        for i in range( 8, 11 ):
-            main.log.info(
-                "Adding point intent between h" + str( i ) +
-                " and h" + str( i + 10 ) )
-            host1 = "00:00:00:00:00:" + \
-                str( hex( i )[ 2: ] ).zfill( 2 ).upper()
-            host2 = "00:00:00:00:00:" + \
-                str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
-            host1_id = main.ONOScli1.get_host( host1 )[ 'id' ]
-            host2_id = main.ONOScli1.get_host( host2 )[ 'id' ]
-            for host in hosts_json:
-                if host[ 'id' ] == host1_id:
-                    ip1 = host[ 'ips' ][ 0 ]
-                    ip1 = str( ip1 + "/32" )
-                    device1 = host[ 'location' ][ 'device' ]
-                    device1 = str( device1 + "/1" )
-                elif host[ 'id' ] == host2_id:
-                    ip2 = str( host[ 'ips' ][ 0 ] ) + "/32"
-                    device2 = host[ 'location' ][ "device" ]
-                    device2 = str( device2 + "/1" )
-
-            p_intent_result1 = main.ONOScli1.add_point_intent(
-                ingress_device=device1,
-                egress_device=device2,
-                ipSrc=ip1,
-                ipDst=ip2,
-                ethType=main.params[ 'SDNIP' ][ 'ethType' ],
-                ipProto=main.params[ 'SDNIP' ][ 'icmpProto' ] )
-
-            get_intent_result = main.ONOScli1.intents( json_format=False )
-            main.log.info( get_intent_result )
-
-            p_intent_result2 = main.ONOScli1.add_point_intent(
-                ingress_device=device2,
-                egress_device=device1,
-                ipSrc=ip2,
-                ipDst=ip1,
-                ethType=main.params[ 'SDNIP' ][ 'ethType' ],
-                ipProto=main.params[ 'SDNIP' ][ 'icmpProto' ] )
-
-            get_intent_result = main.ONOScli1.intents( json_format=False )
-            main.log.info( get_intent_result )
-            if ( p_intent_result1 and p_intent_result2 ) == main.TRUE:
-                # get_intent_result = main.ONOScli1.intents()
-                # main.log.info( get_intent_result )
-                main.log.info(
-                    '''Point intent related to SDN-IP matching on ICMP install
-                    successful''' )
-
-        time.sleep( 15 )
-        get_intent_result = main.ONOScli1.intents( json_format=False )
-        main.log.info( "intents = " + get_intent_result )
-        get_flows_result = main.ONOScli1.flows()
-        main.log.info( "flows = " + get_flows_result )
-
-        count = 1
-        i = 8
-        Ping_Result = main.TRUE
-        while i < 11:
-            main.log.info(
-                "\n\nh" + str( i ) + " is Pinging h" + str( i + 10 ) )
-            ping = main.Mininet1.pingHost(
-                src="h" + str( i ), target="h" + str( i + 10 ) )
-            if ping == main.FALSE and count < 3:
-                count += 1
-                # i = 8
-                Ping_Result = main.FALSE
-                main.log.report( "Ping between h" +
-                                 str( i ) +
-                                 " and h" +
-                                 str( i +
-                                      10 ) +
-                                 " failed. Making attempt number " +
-                                 str( count ) +
-                                 " in 2 seconds" )
-                time.sleep( 2 )
-            elif ping == main.FALSE:
-                main.log.report( "All ping attempts between h" +
-                                 str( i ) +
-                                 " and h" +
-                                 str( i +
-                                      10 ) +
-                                 "have failed" )
-                i = 19
-                Ping_Result = main.FALSE
-            elif ping == main.TRUE:
-                main.log.info( "Ping test between h" +
-                               str( i ) +
-                               " and h" +
-                               str( i +
-                                    10 ) +
-                               "passed!" )
-                i += 1
-                Ping_Result = main.TRUE
-            else:
-                main.log.info( "Unknown error" )
-                Ping_Result = main.ERROR
-        if Ping_Result == main.FALSE:
-            main.log.report(
-                "Ping test after Point intents related to SDN-IP \
-                matching on ICMP failed." )
-            # main.cleanup()
-            # main.exit()
-        if Ping_Result == main.TRUE:
-            main.log.report(
-                "Ping all test after Point intents related to SDN-IP \
-                matching on ICMP successful" )
-
-        case31_result = Ping_Result and p_intent_result1 and p_intent_result2
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=case31_result,
-            onpass="Point intent related to SDN-IP matching on ICMP and \
-                    ping test successful",
-            onfail="Point intent related to SDN-IP matching on ICMP and \
-                    ping test failed" )
-
-    def CASE32( self ):
-        '''
-            This test case adds point intent related to SDN-IP matching on TCP
-            ( ethertype=IPV4, ipProto=6, DefaultPort for iperf=5001 )
-            Note: Although BGP port is 179, we are using 5001 because iperf is
-            used for verifying and iperf's default port is 5001
-        '''
-        import json
-
-        main.log.report( '''This test case adds point intent related
-                         to SDN-IP matching on TCP''' )
-        main.case( '''Adding bidirectional point intent related to SDN-IP
-                    matching on TCP''' )
-        main.step( "Adding bidirectional point intent" )
-
-        """
-        add-point-intent --ipSrc=10.0.0.8/32 --ipDst=10.0.0.18/32
-                    --ethType=IPV4 --ipProto=6 --tcpDst=5001
-                    of:0000000000003008/1 of:0000000000006018/1
-
-        add-point-intent --ipSrc=10.0.0.18/32 --ipDst=10.0.0.8/32
-                    --ethType=IPV4 --ipProto=6 --tcpDst=5001
-                    of:0000000000006018/1 of:0000000000003008/1
-
-        add-point-intent --ipSrc=10.0.0.8/32 --ipDst=10.0.0.18/32
-                    --ethType=IPV4 --ipProto=6 --tcpSrc=5001
-                    of:0000000000003008/1 of:0000000000006018/1
-
-        add-point-intent --ipSrc=10.0.0.18/32 --ipDst=10.0.0.8/32
-                    --ethType=IPV4 --ipProto=6 --tcpSrc=5001
-                    of:0000000000006018/1 of:0000000000003008/1
-
-        """
-        hosts_json = json.loads( main.ONOScli1.hosts() )
-        for i in range( 8, 9 ):
-            main.log.info(
-                "Adding point intent between h" + str( i ) +
-                " and h" + str( i + 10 ) )
-            host1 = "00:00:00:00:00:" + \
-                    str( hex( i )[ 2: ] ).zfill( 2 ).upper()
-            host2 = "00:00:00:00:00:" + \
-                    str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
-            host1_id = main.ONOScli1.get_host( host1 )[ 'id' ]
-            host2_id = main.ONOScli1.get_host( host2 )[ 'id' ]
-            for host in hosts_json:
-                if host[ 'id' ] == host1_id:
-                    ip1 = host[ 'ips' ][ 0 ]
-                    ip1 = str( ip1 + "/32" )
-                    device1 = host[ 'location' ][ 'device' ]
-                    device1 = str( device1 + "/1" )
-                elif host[ 'id' ] == host2_id:
-                    ip2 = str( host[ 'ips' ][ 0 ] ) + "/32"
-                    device2 = host[ 'location' ][ "device" ]
-                    device2 = str( device2 + "/1" )
-
-            p_intent_result1 = main.ONOScli1.add_point_intent(
-                ingress_device=device1,
-                egress_device=device2,
-                ipSrc=ip1,
-                ipDst=ip2,
-                ethType=main.params[ 'SDNIP' ][ 'ethType' ],
-                ipProto=main.params[ 'SDNIP' ][ 'tcpProto' ],
-                tcpDst=main.params[ 'SDNIP' ][ 'dstPort' ] )
-            p_intent_result2 = main.ONOScli1.add_point_intent(
-                ingress_device=device2,
-                egress_device=device1,
-                ipSrc=ip2,
-                ipDst=ip1,
-                ethType=main.params[ 'SDNIP' ][ 'ethType' ],
-                ipProto=main.params[ 'SDNIP' ][ 'tcpProto' ],
-                tcpDst=main.params[ 'SDNIP' ][ 'dstPort' ] )
-
-            p_intent_result3 = main.ONOScli1.add_point_intent(
-                ingress_device=device1,
-                egress_device=device2,
-                ipSrc=ip1,
-                ipDst=ip2,
-                ethType=main.params[ 'SDNIP' ][ 'ethType' ],
-                ipProto=main.params[ 'SDNIP' ][ 'tcpProto' ],
-                tcpSrc=main.params[ 'SDNIP' ][ 'srcPort' ] )
-            p_intent_result4 = main.ONOScli1.add_point_intent(
-                ingress_device=device2,
-                egress_device=device1,
-                ipSrc=ip2,
-                ipDst=ip1,
-                ethType=main.params[ 'SDNIP' ][ 'ethType' ],
-                ipProto=main.params[ 'SDNIP' ][ 'tcpProto' ],
-                tcpSrc=main.params[ 'SDNIP' ][ 'srcPort' ] )
-
-            p_intent_result = p_intent_result1 and p_intent_result2 and \
-                                p_intent_result3 and p_intent_result4
-            if p_intent_result == main.TRUE:
-                get_intent_result = main.ONOScli1.intents( json_format=False )
-                main.log.info( get_intent_result )
-                main.log.info( '''Point intent related to SDN-IP matching
-                                on TCP install successful''' )
-
-        iperf_result = main.Mininet1.iperf( 'h8', 'h18' )
-        if iperf_result == main.TRUE:
-            main.log.report( "iperf test successful" )
-        else:
-            main.log.report( "iperf test failed" )
-
-        case32_result = p_intent_result and iperf_result
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=case32_result,
-            onpass="Ping all test after Point intents addition related to \
-                    SDN-IP on TCP match successful",
-            onfail="Ping all test after Point intents addition related to \
-                    SDN-IP on TCP match failed" )
-
-    def CASE33( self ):
-        """
-            This test case adds multipoint to singlepoint  intent related
-            to SDN-IP matching on destination ip and the action is to
-            rewrite the mac address.
-            Here the mac address to be rewritten is the mac address
-            of the egress device
-        """
-        import json
-        import time
-
-        main.log.report( "This test case adds multipoint to singlepoint intent\
-                         related to SDN-IP matching on destination ip and\
-                         rewrite mac address action" )
-        main.case( "Adding multipoint to singlepoint intent related to SDN-IP\
-                    matching on destination ip" )
-        main.step( "Adding bidirectional multipoint to singlepoint intent" )
-        """
-        add-multi-to-single-intent --ipDst=10.0.3.0/24
-            --setEthDst=00:00:00:00:00:12
-            of:0000000000003008/1 0000000000003009/1 of:0000000000006018/1
-
-        add-multi-to-single-intent --ipDst=10.0.1.0/24
-            --setEthDst=00:00:00:00:00:08
-            of:0000000000006018/1 0000000000003009/1 of:0000000000003008/1
-        """
-        main.case( "Installing multipoint to single point intent with\
-                   rewrite mac address" )
-        main.step( "Uninstalling proxy arp app" )
-        # Unistall onos-app-proxyarp app to disable reactive forwarding
-        appUninstall_result1 = main.ONOScli1.feature_uninstall(
-            "onos-app-proxyarp" )
-        appUninstall_result2 = main.ONOScli2.feature_uninstall(
-            "onos-app-proxyarp" )
-        appUninstall_result3 = main.ONOScli3.feature_uninstall(
-            "onos-app-proxyarp" )
-        main.log.info( "onos-app-proxyarp uninstalled" )
-
-        main.step( "Changing ipaddress of hosts h8,h9 and h18" )
-        main.Mininet1.changeIP(
-            host='h8',
-            intf='h8-eth0',
-            newIP='10.0.1.1',
-            newNetmask='255.255.255.0' )
-        main.Mininet1.changeIP(
-            host='h9',
-            intf='h9-eth0',
-            newIP='10.0.2.1',
-            newNetmask='255.255.255.0' )
-        main.Mininet1.changeIP(
-            host='h10',
-            intf='h10-eth0',
-            newIP='10.0.3.1',
-            newNetmask='255.255.255.0' )
-
-        main.step( "Changing default gateway of hosts h8,h9 and h18" )
-        main.Mininet1.changeDefaultGateway( host='h8', newGW='10.0.1.254' )
-        main.Mininet1.changeDefaultGateway( host='h9', newGW='10.0.2.254' )
-        main.Mininet1.changeDefaultGateway( host='h10', newGW='10.0.3.254' )
-
-        main.step( "Assigning random mac address to the default gateways\
-                    since proxyarp app is uninstalled" )
-        main.Mininet1.addStaticMACAddress(
-            host='h8',
-            GW='10.0.1.254',
-            macaddr='00:00:00:00:11:11' )
-        main.Mininet1.addStaticMACAddress(
-            host='h9',
-            GW='10.0.2.254',
-            macaddr='00:00:00:00:22:22' )
-        main.Mininet1.addStaticMACAddress(
-            host='h10',
-            GW='10.0.3.254',
-            macaddr='00:00:00:00:33:33' )
-
-        main.step( "Verify static gateway and MAC address assignment" )
-        main.Mininet1.verifyStaticGWandMAC( host='h8' )
-        main.Mininet1.verifyStaticGWandMAC( host='h9' )
-        main.Mininet1.verifyStaticGWandMAC( host='h10' )
-
-        main.step( "Adding multipoint to singlepoint intent" )
-        p_intent_result1 = main.ONOScli1.add_multipoint_to_singlepoint_intent(
-            ingress_device1=main.params[ 'MULTIPOINT_INTENT' ][ 'device1' ],
-            ingress_device2=main.params[ 'MULTIPOINT_INTENT' ][ 'device2' ],
-            egress_device=main.params[ 'MULTIPOINT_INTENT' ][ 'device3' ],
-            ipDst=main.params[ 'MULTIPOINT_INTENT' ][ 'ip1' ],
-            setEthDst=main.params[ 'MULTIPOINT_INTENT' ][ 'mac1' ] )
-
-        p_intent_result2 = main.ONOScli1.add_multipoint_to_singlepoint_intent(
-            ingress_device1=main.params[ 'MULTIPOINT_INTENT' ][ 'device3' ],
-            ingress_device2=main.params[ 'MULTIPOINT_INTENT' ][ 'device2' ],
-            egress_device=main.params[ 'MULTIPOINT_INTENT' ][ 'device1' ],
-            ipDst=main.params[ 'MULTIPOINT_INTENT' ][ 'ip2' ],
-            setEthDst=main.params[ 'MULTIPOINT_INTENT' ][ 'mac2' ] )
-
-        get_intent_result = main.ONOScli1.intents( json_format=False )
-        main.log.info( "intents = " + get_intent_result )
-
-        time.sleep( 10 )
-        get_flows_result = main.ONOScli1.flows( json_format=False )
-        main.log.info( "flows = " + get_flows_result )
-
-        count = 1
-        i = 8
-        Ping_Result = main.TRUE
-
-        main.log.info( "\n\nh" + str( i ) + " is Pinging h" + str( i + 2 ) )
-        ping = main.Mininet1.pingHost(
-            src="h" + str( i ), target="h" + str( i + 2 ) )
-        if ping == main.FALSE and count < 3:
-            count += 1
-            Ping_Result = main.FALSE
-            main.log.report( "Ping between h" +
-                             str( i ) +
-                             " and h" +
-                             str( i +
-                                  2 ) +
-                             " failed. Making attempt number " +
-                             str( count ) +
-                             " in 2 seconds" )
-            time.sleep( 2 )
-        elif ping == main.FALSE:
-            main.log.report( "All ping attempts between h" +
-                             str( i ) +
-                             " and h" +
-                             str( i +
-                                  10 ) +
-                             "have failed" )
-            Ping_Result = main.FALSE
-        elif ping == main.TRUE:
-            main.log.info( "Ping test between h" +
-                           str( i ) +
-                           " and h" +
-                           str( i +
-                                2 ) +
-                           "passed!" )
-            Ping_Result = main.TRUE
-        else:
-            main.log.info( "Unknown error" )
-            Ping_Result = main.ERROR
-
-        if Ping_Result == main.FALSE:
-            main.log.report( "Ping test failed." )
-            # main.cleanup()
-            # main.exit()
-        if Ping_Result == main.TRUE:
-            main.log.report( "Ping all successful" )
-
-        p_intent_result = p_intent_result1 and p_intent_result2
-        if p_intent_result == main.TRUE:
-            main.log.info( "Multi point intent with rewrite mac address\
-                            installation successful" )
-        else:
-            main.log.info( "Multi point intent with rewrite mac address\
-                            installation failed" )
-
-        case33_result = p_intent_result and Ping_Result
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=case33_result,
-            onpass="Ping all test after multipoint to single point intent \
-                    addition with rewrite mac address successful",
-            onfail="Ping all test after multipoint to single point intent \
-                    addition with rewrite mac address failed" )
-
diff --git a/TestON/tests/IntentsLoad/__init__.py b/TestON/tests/MultiProd/__init__.py
similarity index 100%
copy from TestON/tests/IntentsLoad/__init__.py
copy to TestON/tests/MultiProd/__init__.py
diff --git a/TestON/tests/MultiProd13/MultiProd13.py b/TestON/tests/MultiProd13/MultiProd13.py
index 52519d8..6c0b8d7 100644
--- a/TestON/tests/MultiProd13/MultiProd13.py
+++ b/TestON/tests/MultiProd13/MultiProd13.py
@@ -11,7 +11,7 @@
 
 time.sleep( 1 )
 
-class MultiProd:
+class MultiProd13:
 
     def __init__( self ):
         self.default = ''
@@ -637,10 +637,8 @@
         main.step( "Determine the current number of switches and links" )
         topologyOutput = main.ONOScli1.topology()
         topologyResult = main.ONOSbench.getTopology( topologyOutput )
-        activeSwitches = topologyResult[ 'devices' ]
-        links = topologyResult[ 'links' ]
-        print "activeSwitches = ", type( activeSwitches )
-        print "links = ", type( links )
+        activeSwitches = topologyResult[ 'deviceCount' ]
+        links = topologyResult[ 'linkCount' ]
         main.log.info(
             "Currently there are %s switches and %s links" %
             ( str( activeSwitches ), str( links ) ) )
@@ -1535,39 +1533,54 @@
         main.Mininet1.verifyStaticGWandMAC( host='h9' )
         main.Mininet1.verifyStaticGWandMAC( host='h10' )
 
+        ingressDevice1=main.params[ 'MULTIPOINT_INTENT' ][ 'device1' ]
+        ingressDevice2=main.params[ 'MULTIPOINT_INTENT' ][ 'device2' ]
+        ingressDeviceList = []
+        ingressDeviceList.append( ingressDevice1 )
+        ingressDeviceList.append( ingressDevice2 )
+
         main.step( "Adding multipoint to singlepoint intent" )
         pIntentResult1 = main.ONOScli1.addMultipointToSinglepointIntent(
-            ingressDevice1=main.params[ 'MULTIPOINT_INTENT' ][ 'device1' ],
-            ingressDevice2=main.params[ 'MULTIPOINT_INTENT' ][ 'device2' ],
+            ingressDeviceList,
             egressDevice=main.params[ 'MULTIPOINT_INTENT' ][ 'device3' ],
             ipDst=main.params[ 'MULTIPOINT_INTENT' ][ 'ip1' ],
             setEthDst=main.params[ 'MULTIPOINT_INTENT' ][ 'mac1' ] )
 
+        ingressDevice1=main.params[ 'MULTIPOINT_INTENT' ][ 'device3' ]
+        ingressDevice2=main.params[ 'MULTIPOINT_INTENT' ][ 'device2' ]
+        ingressDeviceList = [ingressDevice1, ingressDevice2]
+
         pIntentResult2 = main.ONOScli1.addMultipointToSinglepointIntent(
-            ingressDevice1=main.params[ 'MULTIPOINT_INTENT' ][ 'device3' ],
-            ingressDevice2=main.params[ 'MULTIPOINT_INTENT' ][ 'device2' ],
+            ingressDeviceList,
             egressDevice=main.params[ 'MULTIPOINT_INTENT' ][ 'device1' ],
             ipDst=main.params[ 'MULTIPOINT_INTENT' ][ 'ip2' ],
             setEthDst=main.params[ 'MULTIPOINT_INTENT' ][ 'mac2' ] )
 
-        getIntentResult = main.ONOScli1.intents( jsonFormat=False )
-        main.log.info( "intents = " + getIntentResult )
+        pIntentResult = pIntentResult1 and pIntentResult2
+        if pIntentResult == main.FALSE:
+            main.log.info(
+                "Multi point to single point intent " +
+                "installation failed" )
+        else:
+            pIntentResult = main.TRUE 
+            getIntentResult = main.ONOScli1.intents( jsonFormat=False )
+            main.log.info( "intents = " + getIntentResult )
 
-        time.sleep( 10 )
-        getFlowsResult = main.ONOScli1.flows( jsonFormat=False )
-        main.log.info( "flows = " + getFlowsResult )
+            time.sleep( 10 )
+            getFlowsResult = main.ONOScli1.flows( jsonFormat=False )
+            main.log.info( "flows = " + getFlowsResult )
 
-        count = 1
-        i = 8
-        PingResult = main.TRUE
+            count = 1
+            i = 8
+            PingResult = main.TRUE
 
-        main.log.info( "\n\nh" + str( i ) + " is Pinging h" + str( i + 2 ) )
-        ping = main.Mininet1.pingHost(
+            main.log.info( "\n\nh" + str( i ) + " is Pinging h" + str( i + 2 ) )
+            ping = main.Mininet1.pingHost(
             src="h" + str( i ), target="h" + str( i + 2 ) )
-        if ping == main.FALSE and count < 3:
-            count += 1
-            PingResult = main.FALSE
-            main.log.report( "Ping between h" +
+            if ping == main.FALSE and count < 3:
+                count += 1
+                PingResult = main.FALSE
+                main.log.report( "Ping between h" +
                              str( i ) +
                              " and h" +
                              str( i +
@@ -1575,43 +1588,38 @@
                              " failed. Making attempt number " +
                              str( count ) +
                              " in 2 seconds" )
-            time.sleep( 2 )
-        elif ping == main.FALSE:
-            main.log.report( "All ping attempts between h" +
+                time.sleep( 2 )
+            elif ping == main.FALSE:
+                main.log.report( "All ping attempts between h" +
                              str( i ) +
                              " and h" +
                              str( i +
                                   10 ) +
                              "have failed" )
-            PingResult = main.FALSE
-        elif ping == main.TRUE:
-            main.log.info( "Ping test between h" +
+                PingResult = main.FALSE
+            elif ping == main.TRUE:
+                main.log.info( "Ping test between h" +
                            str( i ) +
                            " and h" +
                            str( i +
                                 2 ) +
                            "passed!" )
-            PingResult = main.TRUE
-        else:
-            main.log.info( "Unknown error" )
-            PingResult = main.ERROR
+                PingResult = main.TRUE
+            else:
+                main.log.info( "Unknown error" )
+                PingResult = main.ERROR
 
-        if PingResult == main.FALSE:
-            main.log.report( "Ping test failed." )
-            # main.cleanup()
-            # main.exit()
-        if PingResult == main.TRUE:
-            main.log.report( "Ping all successful" )
+            if PingResult == main.FALSE:
+                main.log.report( "Ping test failed." )
+                # main.cleanup()
+                # main.exit()
+            if PingResult == main.TRUE:
+                main.log.report( "Ping all successful" )
 
-        pIntentResult = pIntentResult1 and pIntentResult2
         if pIntentResult == main.TRUE:
             main.log.info(
                 "Multi point intent with rewrite mac " +
-                "address installation successful" )
-        else:
-            main.log.info(
-                "Multi point intent with rewrite mac" +
-                " address installation failed" )
+                "address installation and ping successful" )
 
         case33Result = pIntentResult and PingResult
         utilities.assertEquals(
diff --git a/TestON/tests/IntentsLoad/__init__.py b/TestON/tests/MultiProd13/__init__.py
similarity index 100%
copy from TestON/tests/IntentsLoad/__init__.py
copy to TestON/tests/MultiProd13/__init__.py
diff --git a/TestON/tests/OnosCHO/OnosCHO.params b/TestON/tests/OnosCHO/OnosCHO.params
index af23c70..02a016c 100644
--- a/TestON/tests/OnosCHO/OnosCHO.params
+++ b/TestON/tests/OnosCHO/OnosCHO.params
@@ -11,10 +11,11 @@
     # 9. Install 114 point intents and verify ping all
     # 10. Remove all intents on ONOS
     # 1,2,3,[4,5,6,5,70,80,5,10,5,9,5,71,81,5,10,5]*100
+    # 1,2,3,4,5,6,10,12,3,4,5,6,10,13,3,4,5,6,10
 
-    <testcases>1,2,3,4,5,12,3,4,5,13,3,4,5</testcases>
+    <testcases>1,[2,3,4,5,6,70,80,10,12,3,4,5,14,10,13,3,4,5,15,10]*3</testcases>
     <ENV>
-        <cellName>choTest5</cellName>
+        <cellName>choTest5New</cellName>
     </ENV>
     <GIT>
         #autoPull 'on' or 'off'
diff --git a/TestON/tests/OnosCHO/OnosCHO.py b/TestON/tests/OnosCHO/OnosCHO.py
index eb71518..93dc11b 100644
--- a/TestON/tests/OnosCHO/OnosCHO.py
+++ b/TestON/tests/OnosCHO/OnosCHO.py
@@ -25,6 +25,9 @@
         """
         import time
 
+        global intentState
+        main.threadID = 0
+        main.pingTimeout = 300
         main.numCtrls = main.params[ 'CTRL' ][ 'numCtrl' ]
         main.ONOS1_ip = main.params[ 'CTRL' ][ 'ip1' ]
         main.ONOS2_ip = main.params[ 'CTRL' ][ 'ip2' ]
@@ -39,7 +42,13 @@
         cell_name = main.params[ 'ENV' ][ 'cellName' ]
         git_pull = main.params[ 'GIT' ][ 'autoPull' ]
         git_branch = main.params[ 'GIT' ][ 'branch' ]
-
+        
+        main.CLIs = []
+        main.nodes = []
+        for i in range( 1, int(main.numCtrls) + 1 ):
+            main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
+            main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
+        
         main.case( "Set up test environment" )
         main.log.report( "Set up test environment" )
         main.log.report( "_______________________" )
@@ -86,7 +95,7 @@
         uninstallResult = main.TRUE
         for i in range( 1, int( main.numCtrls ) + 1 ):
             ONOS_ip = main.params[ 'CTRL' ][ 'ip' + str( i ) ]
-            main.log.info( "Unintsalling package on ONOS Node IP: " + ONOS_ip )
+            main.log.info( "Uninstalling package on ONOS Node IP: " + ONOS_ip )
             u_result = main.ONOSbench.onosUninstall( ONOS_ip )
             utilities.assert_equals( expect=main.TRUE, actual=u_result,
                                      onpass="Test step PASS",
@@ -123,24 +132,38 @@
         karafTimeout = "3600000"
         # need to wait here for sometime. This will be removed once ONOS is
         # stable enough
-        time.sleep( 20 )
-        for i in range( 1, int( main.numCtrls ) + 1 ):
-            ONOS_ip = main.params[ 'CTRL' ][ 'ip' + str( i ) ]
-            ONOScli = 'ONOScli' + str( i )
-            main.log.info( "ONOS Node " + ONOS_ip + " cli start:" )
-            exec "startcli=main." + ONOScli + \
-                ".startOnosCli(ONOS_ip, karafTimeout=karafTimeout)"
-            utilities.assert_equals( expect=main.TRUE, actual=startcli,
-                                     onpass="Test step PASS",
-                                     onfail="Test step FAIL" )
-            cliResult = ( cliResult and startcli )
-
-        case1Result = ( cp_result and cell_result
-                        and packageResult and installResult and statusResult and cliResult )
+        time.sleep( 25 )
+        main.log.step(" Start ONOS cli using thread ")
+        startCliResult  = main.TRUE
+        pool = []
+        time1 = time.time()
+        for i in range( int( main.numCtrls) ):
+            t = main.Thread( target=main.CLIs[i].startOnosCli,
+                             threadID=main.threadID,
+                             name="startOnosCli",
+                             args=[ main.nodes[i].ip_address ] )
+            pool.append(t)
+            t.start()
+            main.threadID = main.threadID + 1
+        for t in pool:
+            t.join()
+            startCliResult = startCliResult and t.result
+        time2 = time.time()
+        
+        if not startCliResult:
+                main.log.info("ONOS CLI did not start up properly")
+                main.cleanup()
+                main.exit()
+        else:
+            main.log.info("Successful CLI startup")
+            startCliResult = main.TRUE
+        case1Result = installResult and uninstallResult and statusResult and startCliResult
+        
+        main.log.info("Time for connecting to CLI: %2f seconds" %(time2-time1))
         utilities.assert_equals( expect=main.TRUE, actual=case1Result,
                                  onpass="Set up test environment PASS",
                                  onfail="Set up test environment FAIL" )
-
+        time.sleep(30)
     def CASE2( self, main ):
         """
         This test loads a Topology (ATT) on Mininet and balances all switches.
@@ -151,7 +174,7 @@
         main.numMNswitches = int ( main.params[ 'TOPO1' ][ 'numSwitches' ] )
         main.numMNlinks = int ( main.params[ 'TOPO1' ][ 'numLinks' ] )
         main.numMNhosts = int ( main.params[ 'TOPO1' ][ 'numHosts' ] )
-
+        main.pingTimeout = 60
         main.log.report(
             "Assign and Balance all Mininet switches across controllers" )
         main.log.report(
@@ -217,20 +240,21 @@
         main.deviceLinks = []
         main.deviceActiveLinksCount = []
         main.devicePortsEnabledCount = []
-
+        
         main.log.report(
             "Collect and Store topology details from ONOS before running any Tests" )
         main.log.report(
             "____________________________________________________________________" )
         main.case( "Collect and Store Topology Deatils from ONOS" )
-
         main.step( "Collect and store current number of switches and links" )
         topology_output = main.ONOScli1.topology()
         topology_result = main.ONOSbench.getTopology( topology_output )
-        numOnosDevices = topology_result[ 'devices' ]
-        numOnosLinks = topology_result[ 'links' ]
+        numOnosDevices = topology_result[ 'deviceCount' ]
+        numOnosLinks = topology_result[ 'linkCount' ]
+        print numOnosDevices
+        print numOnosLinks
 
-        if ( ( main.numMNswitches == int(numOnosDevices) ) and ( main.numMNlinks == int(numOnosLinks) ) ):
+        if ( ( main.numMNswitches == int(numOnosDevices) ) and ( main.numMNlinks >= int(numOnosLinks) ) ):
             main.step( "Store Device DPIDs" )
             for i in range( 1, (main.numMNswitches+1) ):
                 main.deviceDPIDs.append( "of:00000000000000" + format( i, '02x' ) )
@@ -255,22 +279,50 @@
             print "Length of Links Store", len( main.deviceLinks )
 
             main.step( "Collect and store each Device ports enabled Count" )
-            for i in range( 1, ( main.numMNswitches + 1) ):
-                portResult = main.ONOScli1.getDevicePortsEnabledCount(
-                    "of:00000000000000" + format( i,'02x' ) )
-                portTemp = re.split( r'\t+', portResult )
-                portCount = portTemp[ 1 ].replace( "\r\r\n\x1b[32m", "" )
-                main.devicePortsEnabledCount.append( portCount )
+            time1 = time.time()
+            for i in xrange(1,(main.numMNswitches + 1), int( main.numCtrls ) ):
+                pool = []
+                for cli in main.CLIs:
+                    dpid = "of:00000000000000" + format( i,'02x' )
+                    t = main.Thread(target = cli.getDevicePortsEnabledCount,threadID = main.threadID, name = "getDevicePortsEnabledCount",args = [dpid])
+                    t.start()
+                    pool.append(t)
+                    i = i + 1
+                    main.threadID = main.threadID + 1
+                for thread in pool:
+                    thread.join()
+                    portResult = thread.result
+                    portTemp = re.split( r'\t+', portResult )
+                    portCount = portTemp[ 1 ].replace( "\r\r\n\x1b[32m", "" )
+                    main.devicePortsEnabledCount.append( portCount )
             print "Device Enabled Port Counts Stored: \n", str( main.devicePortsEnabledCount )
+            time2 = time.time()
+            main.log.info("Time for counting enabled ports of the switches: %2f seconds" %(time2-time1))
 
             main.step( "Collect and store each Device active links Count" )
-            for i in range( 1, ( main.numMNswitches + 1) ):
-                linkCountResult = main.ONOScli1.getDeviceLinksActiveCount(
-                    "of:00000000000000" + format( i,'02x' ) )
-                linkCountTemp = re.split( r'\t+', linkCountResult )
-                linkCount = linkCountTemp[ 1 ].replace( "\r\r\n\x1b[32m", "" )
-                main.deviceActiveLinksCount.append( linkCount )
-            print "Device Active Links Count Stored: \n", str( main.deviceActiveLinksCount )
+            time1 = time.time()
+            
+            for i in xrange( 1,( main.numMNswitches + 1 ), int( main.numCtrls) ):
+                pool = []
+                for cli in main.CLIs:
+                    dpid = "of:00000000000000" + format( i,'02x' )
+                    t = main.Thread( target = cli.getDeviceLinksActiveCount,
+                                     threadID = main.threadID,
+                                     name = "getDevicePortsEnabledCount",
+                                     args = [dpid])
+                    t.start()
+                    pool.append(t)
+                    i = i + 1
+                    main.threadID = main.threadID + 1
+                for thread in pool:
+                    thread.join()
+                    linkCountResult = thread.result
+                    linkCountTemp = re.split( r'\t+', linkCountResult )
+                    linkCount = linkCountTemp[ 1 ].replace( "\r\r\n\x1b[32m", "" )
+                    main.deviceActiveLinksCount.append( linkCount )
+                print "Device Active Links Count Stored: \n", str( main.deviceActiveLinksCount )
+            time2 = time.time()
+            main.log.info("Time for counting all enabled links of the switches: %2f seconds" %(time2-time1))
 
         else:
             main.log.info("Devices (expected): %s, Links (expected): %s" % 
@@ -278,9 +330,9 @@
             main.log.info("Devices (actual): %s, Links (actual): %s" %
                     ( numOnosDevices , numOnosLinks ) )
             main.log.info("Topology does not match, exiting CHO test...")
-            time.sleep(300)
-            #main.cleanup()
-            #main.exit()
+            #time.sleep(300)
+            main.cleanup()
+            main.exit()
 
         # just returning TRUE for now as this one just collects data
         case3Result = main.TRUE
@@ -295,27 +347,44 @@
         import re
         import copy
         import time
-
         main.log.report( "Enable Reactive forwarding and Verify ping all" )
         main.log.report( "______________________________________________" )
         main.case( "Enable Reactive forwarding and Verify ping all" )
         main.step( "Enable Reactive forwarding" )
         installResult = main.TRUE
-        for i in range( 1, int( main.numCtrls ) + 1 ):
-            onosFeature = 'onos-app-fwd'
-            ONOS_ip = main.params[ 'CTRL' ][ 'ip' + str( i ) ]
-            ONOScli = 'ONOScli' + str( i )
-            main.log.info( "Enabling Reactive mode on ONOS Node " + ONOS_ip )
-            exec "inResult=main." + ONOScli + ".featureInstall(onosFeature)"
-            time.sleep( 3 )
-            installResult = inResult and installResult
-
+        feature = "onos-app-fwd"
+        
+        pool = []
+        time1 = time.time()
+        for cli in main.CLIs:
+            t = main.Thread( target=cli.featureInstall,
+                    threadID=main.threadID,
+                    name="featureInstall",
+                    args=['onos-app-fwd'])
+            pool.append(t)
+            t.start()
+            main.threadID = main.threadID + 1
+            
+        installResult = main.TRUE
+        for t in pool:
+            t.join()
+            installResult = installResult and t.result
+        time2 = time.time()
+        
+        if not installResult:
+                main.log.info("Did not install onos-app-fwd feature properly")
+                main.cleanup()
+                main.exit()
+        else:
+            main.log.info("Successful feature:install onos-app-fwd")
+        main.log.info("Time for feature:install onos-app-fwd: %2f seconds" %(time2-time1))
+        
         time.sleep( 5 )
 
         main.step( "Verify Pingall" )
         ping_result = main.FALSE
         time1 = time.time()
-        ping_result = main.Mininet1.pingall()
+        ping_result = main.Mininet1.pingall(timeout=main.pingTimeout)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -330,19 +399,33 @@
 
         main.step( "Disable Reactive forwarding" )
         uninstallResult = main.TRUE
-        for i in range( 1, int( main.numCtrls ) + 1 ):
-            onosFeature = 'onos-app-fwd'
-            ONOS_ip = main.params[ 'CTRL' ][ 'ip' + str( i ) ]
-            ONOScli = 'ONOScli' + str( i )
-            main.log.info( "Disabling Reactive mode on ONOS Node " + ONOS_ip )
-            exec "unResult=main." + ONOScli + ".featureUninstall(onosFeature)"
-            uninstallResult = unResult and uninstallResult
+        pool = []
+        time1 = time.time()
+        for cli in main.CLIs:
+            t = main.Thread( target=cli.featureUninstall,
+                             threadID=main.threadID,
+                             name="featureUninstall",
+                             args=['onos-app-fwd'])
+            pool.append(t)
+            t.start()
+            main.threadID = main.threadID + 1
+        for t in pool:
+            t.join()
+            uninstallResult = uninstallResult and t.result
+        time2 = time.time()
+        
+        if not uninstallResult:
+                main.log.info("Did not uninstall onos-app-fwd feature properly")
+                main.cleanup()
+                main.exit()
+        else:
+            main.log.info("Successful feature:uninstall onos-app-fwd")
+        main.log.info("Time for feature:uninstall onos-app-fwd: %2f seconds" %(time2-time1))
 
         # Waiting for reative flows to be cleared.
-        time.sleep( 10 )
-
-        case3Result = installResult and ping_result and uninstallResult
-        utilities.assert_equals( expect=main.TRUE, actual=case3Result,
+        time.sleep( 5 )
+        case4Result =  installResult and uninstallResult and ping_result
+        utilities.assert_equals( expect=main.TRUE, actual=case4Result,
                                  onpass="Reactive Mode Pingall test PASS",
                                  onfail="Reactive Mode Pingall test FAIL" )
 
@@ -351,6 +434,7 @@
         Compare current ONOS topology with reference data
         """
         import re
+        
         devicesDPIDTemp = []
         hostMACsTemp = []
         deviceLinksTemp = []
@@ -363,22 +447,35 @@
         main.case( "Compare ONOS topology with reference data" )
 
         main.step( "Compare current Device ports enabled with reference" )
-        for i in range( 1, 26 ):
-            portResult = main.ONOScli1.getDevicePortsEnabledCount(
-                "of:00000000000000" +
-                format(
-                    i,
-                    '02x' ) )
-            portTemp = re.split( r'\t+', portResult )
-            portCount = portTemp[ 1 ].replace( "\r\r\n\x1b[32m", "" )
-            devicePortsEnabledCountTemp.append( portCount )
-            time.sleep( 2 )
+        time1 = time.time()
+        for i in xrange( 1,(main.numMNswitches + 1), int( main.numCtrls ) ):
+            pool = []
+            for cli in main.CLIs:
+                dpid = "of:00000000000000" + format( i,'02x' )
+                t = main.Thread(target = cli.getDevicePortsEnabledCount,
+                        threadID = main.threadID,
+                        name = "getDevicePortsEnabledCount",
+                        args = [dpid])
+                t.start()
+                pool.append(t)
+                i = i + 1
+                main.threadID = main.threadID + 1
+            for thread in pool:
+                thread.join()
+                portResult = thread.result
+                portTemp = re.split( r'\t+', portResult )
+                portCount = portTemp[ 1 ].replace( "\r\r\n\x1b[32m", "" )
+                devicePortsEnabledCountTemp.append( portCount )
+        print "Device Enabled Port Counts Stored: \n", str( main.devicePortsEnabledCount )
+        time2 = time.time()
+        main.log.info("Time for counting enabled ports of the switches: %2f seconds" %(time2-time1))
         main.log.info (
             "Device Enabled ports EXPECTED: %s" % 
 	     str( main.devicePortsEnabledCount ) )
         main.log.info (
             "Device Enabled ports ACTUAL: %s" % 
             str( devicePortsEnabledCountTemp ) )
+        
         if ( cmp( main.devicePortsEnabledCount,
                   devicePortsEnabledCountTemp ) == 0 ):
             stepResult1 = main.TRUE
@@ -386,16 +483,28 @@
             stepResult1 = main.FALSE
 
         main.step( "Compare Device active links with reference" )
-        for i in range( 1, 26 ):
-            linkResult = main.ONOScli1.getDeviceLinksActiveCount(
-                "of:00000000000000" +
-                format(
-                    i,
-                    '02x' ) )
-            linkTemp = re.split( r'\t+', linkResult )
-            linkCount = linkTemp[ 1 ].replace( "\r\r\n\x1b[32m", "" )
-            deviceActiveLinksCountTemp.append( linkCount )
-            time.sleep( 3 )
+        time1 = time.time()
+        for i in xrange( 1, ( main.numMNswitches + 1) , int( main.numCtrls ) ):
+            pool = []
+            for cli in main.CLIs:
+                dpid = "of:00000000000000" + format( i,'02x' )
+                t = main.Thread(target = cli.getDeviceLinksActiveCount,
+                        threadID = main.threadID,
+                        name = "getDevicePortsEnabledCount",
+                        args = [dpid])
+                t.start()
+                pool.append(t)
+                i = i + 1
+                main.threadID = main.threadID + 1
+            for thread in pool:
+                thread.join()
+                linkCountResult = thread.result
+                linkCountTemp = re.split( r'\t+', linkCountResult )
+                linkCount = linkCountTemp[ 1 ].replace( "\r\r\n\x1b[32m", "" )
+                deviceActiveLinksCountTemp.append( linkCount )
+            print "Device Active Links Count Stored: \n", str( main.deviceActiveLinksCount )
+        time2 = time.time()
+        main.log.info("Time for counting all enabled links of the switches: %2f seconds" %(time2-time1))
         main.log.info (
             "Device Active links EXPECTED: %s" %
               str( main.deviceActiveLinksCount ) )
@@ -422,21 +531,43 @@
         main.log.report( "Add 300 host intents and verify pingall" )
         main.log.report( "_______________________________________" )
         import itertools
-
+        import time
         main.case( "Install 300 host intents" )
         main.step( "Add host Intents" )
         intentResult = main.TRUE
-        hostCombos = list( itertools.combinations( main.hostMACs, 2 ) )
-        for i in range( len( hostCombos ) ):
-            iResult = main.ONOScli1.addHostIntent(
-                hostCombos[ i ][ 0 ],
-                hostCombos[ i ][ 1 ] )
-            intentResult = ( intentResult and iResult )
-
+        hostCombos = list( itertools.combinations( main.hostMACs, 2 ) ) 
+        
+        intentIdList = []
+        time1 = time.time()
+        for i in xrange( 0, len( hostCombos ), int(main.numCtrls) ):
+            pool = []
+            for cli in main.CLIs:
+                if i >= len( hostCombos ):
+                    break
+                t = main.Thread( target=cli.addHostIntent,
+                        threadID=main.threadID,
+                        name="addHostIntent",
+                        args=[hostCombos[i][0],hostCombos[i][1]])
+                pool.append(t)
+                time.sleep(1)
+                t.start()
+                i = i + 1
+                main.threadID = main.threadID + 1
+            for thread in pool:
+                thread.join()
+                intentIdList.append(thread.result)
+        time2 = time.time()
+        main.log.info("Time for adding host intents: %2f seconds" %(time2-time1))
+        intentResult = main.TRUE
+        intentsJson = main.ONOScli2.intents()
+        getIntentStateResult = main.ONOScli1.getIntentState(intentsId = intentIdList,
+                intentsJson = intentsJson)
+        print getIntentStateResult
+        time.sleep(30)
         main.step( "Verify Ping across all hosts" )
         pingResult = main.FALSE
         time1 = time.time()
-        pingResult = main.Mininet1.pingall()
+        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -447,11 +578,11 @@
                                  onpass="PING ALL PASS",
                                  onfail="PING ALL FAIL" )
 
-        case4Result = ( intentResult and pingResult )
-        #case4Result = pingResult
+        case6Result = ( intentResult and pingResult )
+        
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=case4Result,
+            actual=case6Result,
             onpass="Install 300 Host Intents and Ping All test PASS",
             onfail="Install 300 Host Intents and Ping All test FAIL" )
 
@@ -518,7 +649,7 @@
         main.step( "Verify Ping across all hosts" )
         pingResultLinkDown = main.FALSE
         time1 = time.time()
-        pingResultLinkDown = main.Mininet1.pingall()
+        pingResultLinkDown = main.Mininet1.pingall(timeout=main.pingTimeout)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
@@ -555,15 +686,15 @@
         for i in range( int( switchLinksToToggle ) ):
             main.Mininet1.link(
                 END1=link1End1,
-                END2=randomLink1[ i ],
+                END2=main.randomLink1[ i ],
                 OPTION="up" )
             main.Mininet1.link(
                 END1=link2End1,
-                END2=randomLink2[ i ],
+                END2=main.randomLink2[ i ],
                 OPTION="up" )
             main.Mininet1.link(
                 END1=link3End1,
-                END2=randomLink3[ i ],
+                END2=main.randomLink3[ i ],
                 OPTION="up" )
         time.sleep( link_sleep )
 
@@ -812,7 +943,210 @@
             onpass="Ping all test after Point intents addition successful",
             onfail="Ping all test after Point intents addition failed" )
 
+    def CASE90( self ):
+        """
+        Install single-multi point intents and verify Ping all works
+        for att topology
+        """
+        import copy
+        main.log.report( "Install single-multi point intents and verify Ping all" )
+        main.log.report( "___________________________________________" )
+        main.case( "Install single-multi point intents and Ping all" )
+        deviceLinksCopy = copy.copy( main.deviceLinks )
+        main.step( "Install single-multi point intents" )
+        for i in range( len( deviceLinksCopy ) ):
+            pointLink = str(
+                deviceLinksCopy[ i ] ).replace(
+                "src=",
+                "" ).replace(
+                "dst=",
+                "" ).split( ',' )
+            point1 = pointLink[ 0 ].split( '/' )
+            point2 = pointLink[ 1 ].split( '/' )
+            installResult = main.ONOScli1.addPointIntent(
+                point1[ 0 ], point2[ 0 ], int(
+                    point1[ 1 ] ), int(
+                    point2[ 1 ] ) )
+            if installResult == main.TRUE:
+                print "Installed Point intent between :", point1[ 0 ], int( point1[ 1 ] ), point2[ 0 ], int( point2[ 1 ] )
+
+        main.step( "Obtain the intent id's" )
+        intentsList = main.ONOScli1.getAllIntentIds()
+        ansi_escape = re.compile( r'\x1b[^m]*m' )
+        intentsList = ansi_escape.sub( '', intentsList )
+        intentsList = intentsList.replace(
+            " onos:intents | grep id=",
+            "" ).replace(
+            "id=",
+            "" ).replace(
+            "\r\r",
+             "" )
+        intentsList = intentsList.splitlines()
+        intentsList = intentsList[ 1: ]
+        intentIdList = []
+        for i in range( len( intentsList ) ):
+            intentsTemp = intentsList[ i ].split( ',' )
+            intentIdList.append( intentsTemp[ 0 ] )
+        print "Intent IDs: ", intentIdList
+        print "Total Intents installed: ", len( intentIdList )
+
+        main.step( "Verify Ping across all hosts" )
+        pingResult = main.FALSE
+        time1 = time.time()
+        pingResult = main.Mininet1.pingall()
+        time2 = time.time()
+        timeDiff = round( ( time2 - time1 ), 2 )
+        main.log.report(
+            "Time taken for Ping All: " +
+            str( timeDiff ) +
+            " seconds" )
+        utilities.assert_equals( expect=main.TRUE, actual=pingResult,
+                                 onpass="PING ALL PASS",
+                                 onfail="PING ALL FAIL" )
+
+        case8_result = installResult and pingResult
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=case8_result,
+            onpass="Ping all test after Point intents addition successful",
+            onfail="Ping all test after Point intents addition failed" )
+
+    def CASE91( self ):
+        """
+        Install single-multi point intents and verify Ping all works
+        """
+        import copy
+        main.log.report( "Install single-multi point intents and verify Ping all" )
+        main.log.report( "___________________________________________" )
+        main.case( "Install single-multi point intents and Ping all" )
+        deviceLinksCopy = copy.copy( main.deviceLinks )
+        main.step( "Install single-multi point intents" )
+        for i in range( len( deviceLinksCopy ) ):
+            pointLink = str(
+                deviceLinksCopy[ i ] ).replace(
+                "src=",
+                "" ).replace(
+                "dst=",
+                "" ).split( ',' )
+            point1 = pointLink[ 0 ].split( '/' )
+            point2 = pointLink[ 1 ].split( '/' )
+            installResult = main.ONOScli1.addPointIntent(
+                point1[ 0 ], point2[ 0 ], int(
+                    point1[ 1 ] ), int(
+                    point2[ 1 ] ) )
+            if installResult == main.TRUE:
+                print "Installed Point intent between :", point1[ 0 ], int( point1[ 1 ] ), point2[ 0 ], int( point2[ 1 ] )
+
+        main.step( "Obtain the intent id's" )
+        intentsList = main.ONOScli1.getAllIntentIds()
+        ansi_escape = re.compile( r'\x1b[^m]*m' )
+        intentsList = ansi_escape.sub( '', intentsList )
+        intentsList = intentsList.replace(
+            " onos:intents | grep id=",
+            "" ).replace(
+            "id=",
+            "" ).replace(
+            "\r\r",
+             "" )
+        intentsList = intentsList.splitlines()
+        intentsList = intentsList[ 1: ]
+        intentIdList = []
+        for i in range( len( intentsList ) ):
+            intentsTemp = intentsList[ i ].split( ',' )
+            intentIdList.append( intentsTemp[ 0 ] )
+        print "Intent IDs: ", intentIdList
+        print "Total Intents installed: ", len( intentIdList )
+
+        main.step( "Verify Ping across all hosts" )
+        pingResult = main.FALSE
+        time1 = time.time()
+        pingResult = main.Mininet1.pingall()
+        time2 = time.time()
+        timeDiff = round( ( time2 - time1 ), 2 )
+        main.log.report(
+            "Time taken for Ping All: " +
+            str( timeDiff ) +
+            " seconds" )
+        utilities.assert_equals( expect=main.TRUE, actual=pingResult,
+                                 onpass="PING ALL PASS",
+                                 onfail="PING ALL FAIL" )
+
+        case8_result = installResult and pingResult
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=case8_result,
+            onpass="Ping all test after Point intents addition successful",
+            onfail="Ping all test after Point intents addition failed" )
+
+    def CASE92( self ):
+        """
+        Install 114 point intents and verify Ping all works
+        """
+        import copy
+        main.log.report( "Install 114 point intents and verify Ping all" )
+        main.log.report( "___________________________________________" )
+        main.case( "Install 114 point intents and Ping all" )
+        deviceLinksCopy = copy.copy( main.deviceLinks )
+        main.step( "Install 114 point intents" )
+        for i in range( len( deviceLinksCopy ) ):
+            pointLink = str(
+                deviceLinksCopy[ i ] ).replace(
+                "src=",
+                "" ).replace(
+                "dst=",
+                "" ).split( ',' )
+            point1 = pointLink[ 0 ].split( '/' )
+            point2 = pointLink[ 1 ].split( '/' )
+            installResult = main.ONOScli1.addPointIntent(
+                point1[ 0 ], point2[ 0 ], int(
+                    point1[ 1 ] ), int(
+                    point2[ 1 ] ) )
+            if installResult == main.TRUE:
+                print "Installed Point intent between :", point1[ 0 ], int( point1[ 1 ] ), point2[ 0 ], int( point2[ 1 ] )
+
+        main.step( "Obtain the intent id's" )
+        intentsList = main.ONOScli1.getAllIntentIds()
+        ansi_escape = re.compile( r'\x1b[^m]*m' )
+        intentsList = ansi_escape.sub( '', intentsList )
+        intentsList = intentsList.replace(
+            " onos:intents | grep id=",
+            "" ).replace(
+            "id=",
+            "" ).replace(
+            "\r\r",
+             "" )
+        intentsList = intentsList.splitlines()
+        intentsList = intentsList[ 1: ]
+        intentIdList = []
+        for i in range( len( intentsList ) ):
+            intentsTemp = intentsList[ i ].split( ',' )
+            intentIdList.append( intentsTemp[ 0 ] )
+        print "Intent IDs: ", intentIdList
+        print "Total Intents installed: ", len( intentIdList )
+
+        main.step( "Verify Ping across all hosts" )
+        pingResult = main.FALSE
+        time1 = time.time()
+        pingResult = main.Mininet1.pingall()
+        time2 = time.time()
+        timeDiff = round( ( time2 - time1 ), 2 )
+        main.log.report(
+            "Time taken for Ping All: " +
+            str( timeDiff ) +
+            " seconds" )
+        utilities.assert_equals( expect=main.TRUE, actual=pingResult,
+                                 onpass="PING ALL PASS",
+                                 onfail="PING ALL FAIL" )
+
+        case8_result = installResult and pingResult
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=case8_result,
+            onpass="Ping all test after Point intents addition successful",
+            onfail="Ping all test after Point intents addition failed" )
+
     def CASE10( self ):
+        import time
         """
          Remove all Intents
         """
@@ -835,42 +1169,48 @@
         intentsList = intentsList[ 1: ]
         intentIdList = []
         step1Result = main.TRUE
+        moreIntents = main.TRUE
+        removeIntentCount = 0
+        print "Current number of intents" , len(intentsList)
         if ( len( intentsList ) > 1 ):
-            for i in range( len( intentsList ) ):
-                intentsTemp = intentsList[ i ].split( ',' )
-                intentIdList.append( intentsTemp[ 0 ] )
-            print "Intent IDs: ", intentIdList
-            for id in range( len( intentIdList ) ):
-                print "Removing intent id (round 1) :", intentIdList[ id ]
-                main.ONOScli1.removeIntent( intentId=intentIdList[ id ] )
-                #time.sleep( 1 )
+            results = main.TRUE
+            main.log.info("Removing intent...")
+            while moreIntents:
+                removeIntentCount = removeIntentCount + 1
+                intentsList1 = main.ONOScli1.getAllIntentIds()
+                if len( intentsList1 ) == 0:
+                    break
+                ansi_escape = re.compile( r'\x1b[^m]*m' )
+                intentsList1 = ansi_escape.sub( '', intentsList1 )
+                intentsList1 = intentsList1.replace(
+                    " onos:intents | grep id=",
+                    "" ).replace(
+                    " state=",
+                    "" ).replace(
+                    "\r\r",
+                    "" )
+                intentsList1 = intentsList1.splitlines()
+                intentsList1 = intentsList1[ 1: ]
+                print "Round %d intents to remove: " %(removeIntentCount)
+                print intentsList1
+                intentIdList1 = []
+                if ( len( intentsList1 ) > 1 ):
+                    moreIntents = main.TRUE
+                    for i in range( len( intentsList1 ) ):
+                        intentsTemp1 = intentsList1[ i ].split( ',' )
+                        intentIdList1.append( intentsTemp1[ 0 ].split('=')[1] )
+                    print "Leftover Intent IDs: ", intentIdList1
+                    print len(intentIdList1)
+                    for intent in intentIdList1:
+                        main.CLIs[0].removeIntent(intent,'org.onosproject.cli',True,False)
+                else:
+                    time.sleep(15)
+                    if len(main.ONOScli1.intents()):
+                        continue
+                    break
+                if removeIntentCount == 5:
+                    break
 
-            main.log.info(
-                "Verify all intents are removed and if any leftovers try remove one more time" )
-            intentsList1 = main.ONOScli1.getAllIntentIds()
-            ansi_escape = re.compile( r'\x1b[^m]*m' )
-            intentsList1 = ansi_escape.sub( '', intentsList1 )
-            intentsList1 = intentsList1.replace(
-                " onos:intents | grep id=",
-                "" ).replace(
-                " state=",
-                "" ).replace(
-                "\r\r",
-                "" )
-            intentsList1 = intentsList1.splitlines()
-            intentsList1 = intentsList1[ 1: ]
-            print "Round 2 (leftover) intents to remove: ", intentsList1
-            intentIdList1 = []
-            if ( len( intentsList1 ) > 1 ):
-                for i in range( len( intentsList1 ) ):
-                    intentsTemp1 = intentsList[ i ].split( ',' )
-                    intentIdList1.append( intentsTemp1[ 0 ] )
-                print "Leftover Intent IDs: ", intentIdList1
-                for id in range( len( intentIdList1 ) ):
-                    print "Removing intent id (round 2):", intentIdList1[ id ]
-                    main.ONOScli1.removeIntent(
-                        intentId=intentIdList1[ id ] )
-                    #time.sleep( 2 )
             else:
                 print "There are no more intents that need to be removed"
                 step1Result = main.TRUE
@@ -878,8 +1218,10 @@
             print "No Intent IDs found in Intents list: ", intentsList
             step1Result = main.FALSE
 
-        caseResult7 = step1Result
-        utilities.assert_equals( expect=main.TRUE, actual=caseResult7,
+        print main.ONOScli1.intents()
+        # time.sleep(300)
+        caseResult10 = step1Result
+        utilities.assert_equals( expect=main.TRUE, actual=caseResult10,
                                  onpass="Intent removal test successful",
                                  onfail="Intent removal test failed" )
 
@@ -891,47 +1233,82 @@
         import copy
         import time
 
+        Thread = imp.load_source('Thread','/home/admin/ONLabTest/TestON/tests/OnosCHO/Thread.py')
+        threadID = 0
+
         main.log.report( "Enable Intent based Reactive forwarding and Verify ping all" )
         main.log.report( "_____________________________________________________" )
         main.case( "Enable Intent based Reactive forwarding and Verify ping all" )
         main.step( "Enable intent based Reactive forwarding" )
-        installResult = main.TRUE
-        for i in range( 1, int( main.numCtrls ) + 1 ):
-            onosFeature = 'onos-app-ifwd'
-            ONOS_ip = main.params[ 'CTRL' ][ 'ip' + str( i ) ]
-            ONOScli = 'ONOScli' + str( i )
-            main.log.info( "Enabling Intent based Reactive forwarding on ONOS Node " + ONOS_ip )
-            exec "inResult=main." + ONOScli + ".featureInstall(onosFeature)"
-            time.sleep( 3 )
-            installResult = inResult and installResult
-
-        time.sleep( 5 )
-
+        installResult = main.FALSE
+        feature = "onos-app-ifwd"
+        
+        pool = []
+        time1 = time.time()
+        for cli,feature in main.CLIs:
+            t = main.Thread(target=cli,threadID=threadID,
+                    name="featureInstall",args=[feature])
+            pool.append(t)
+            t.start()
+            threadID = threadID + 1
+            
+        results = []
+        for thread in pool:
+            thread.join()
+            results.append(thread.result)
+        time2 = time.time()
+        
+        if( all(result == main.TRUE for result in results) == False):
+                main.log.info("Did not install onos-app-ifwd feature properly")
+                main.cleanup()
+                main.exit()
+        else:
+            main.log.info("Successful feature:install onos-app-ifwd")
+            installResult = main.TRUE
+        main.log.info("Time for feature:install onos-app-ifwd: %2f seconds" %(time2-time1))
+        
         main.step( "Verify Pingall" )
         ping_result = main.FALSE
         time1 = time.time()
-        ping_result = main.Mininet1.pingall()
+        ping_result = main.Mininet1.pingall(timeout=600)
         time2 = time.time()
         timeDiff = round( ( time2 - time1 ), 2 )
         main.log.report(
             "Time taken for Ping All: " +
             str( timeDiff ) +
             " seconds" )
-
+        
         if ping_result == main.TRUE:
             main.log.report( "Pingall Test in Reactive mode successful" )
         else:
             main.log.report( "Pingall Test in Reactive mode failed" )
 
         main.step( "Disable Intent based Reactive forwarding" )
-        uninstallResult = main.TRUE
-        for i in range( 1, int( main.numCtrls ) + 1 ):
-            onosFeature = 'onos-app-ifwd'
-            ONOS_ip = main.params[ 'CTRL' ][ 'ip' + str( i ) ]
-            ONOScli = 'ONOScli' + str( i )
-            main.log.info( "Disabling Intent based Reactive forwarding on ONOS Node " + ONOS_ip )
-            exec "unResult=main." + ONOScli + ".featureUninstall(onosFeature)"
-            uninstallResult = unResult and uninstallResult
+        uninstallResult = main.FALSE
+        
+        pool = []
+        time1 = time.time()
+        for cli,feature in main.CLIs:
+            t = main.Thread(target=cli,threadID=threadID,
+                    name="featureUninstall",args=[feature])
+            pool.append(t)
+            t.start()
+            threadID = threadID + 1
+            
+        results = []
+        for thread in pool:
+            thread.join()
+            results.append(thread.result)
+        time2 = time.time()
+        
+        if( all(result == main.TRUE for result in results) == False):
+                main.log.info("Did not uninstall onos-app-ifwd feature properly")
+                main.cleanup()
+                main.exit()
+        else:
+            main.log.info("Successful feature:uninstall onos-app-ifwd")
+            uninstallResult = main.TRUE
+        main.log.info("Time for feature:uninstall onos-app-ifwd: %2f seconds" %(time2-time1))
 
         # Waiting for reative flows to be cleared.
         time.sleep( 10 )
@@ -949,11 +1326,14 @@
         import time
         import copy
 
+        Thread = imp.load_source('Thread','/home/admin/ONLabTest/TestON/tests/OnosCHO/Thread.py')
         newTopo = main.params['TOPO2']['topo']
         main.numMNswitches = int ( main.params[ 'TOPO2' ][ 'numSwitches' ] )
         main.numMNlinks = int ( main.params[ 'TOPO2' ][ 'numLinks' ] )
         main.numMNhosts = int ( main.params[ 'TOPO2' ][ 'numHosts' ] )
-
+        main.pingTimeout = 60
+        
+        time.sleep(60)
         main.log.report(
             "Load Chordal topology and Balance all Mininet switches across controllers" )
         main.log.report(
@@ -1027,16 +1407,30 @@
         #karafTimeout = "3600000" # This is not needed here as it is already set before.
         # need to wait here sometime for ONOS to bootup.
         time.sleep( 30 )
-        for i in range( 1, int( main.numCtrls ) + 1 ):
-            ONOS_ip = main.params[ 'CTRL' ][ 'ip' + str( i ) ]
-            ONOScli = 'ONOScli' + str( i )
-            main.log.info( "ONOS Node " + ONOS_ip + " cli start:" )
-            exec "startcli=main." + ONOScli + \
-                ".startOnosCli(ONOS_ip)"
-            utilities.assert_equals( expect=main.TRUE, actual=startcli,
-                                     onpass="Test step PASS",
-                                     onfail="Test step FAIL" )
-            cliResult = ( cliResult and startcli )
+
+        main.log.step(" Start ONOS cli using thread ")
+        pool = []
+        time1 = time.time()
+        for i in range( int( main.numCtrls ) ):
+            t = main.Thread(target=cli.startOnosCli,
+                    threadID=main.threadID,
+                    name="startOnosCli",
+                    args=[nodes[i].ip_address])
+            pool.append(t)
+            t.start()
+            main.threadID = main.threadID + 1
+        for t in pool:
+            t.join()
+            cliResult = cliResult and t.result
+        time2 = time.time()
+        
+        if not cliResult:
+                main.log.info("ONOS CLI did not start up properly")
+                main.cleanup()
+                main.exit()
+        else:
+            main.log.info("Successful CLI startup")
+        main.log.info("Time for connecting to CLI: %2f seconds" %(time2-time1))
 
         main.step( "Balance devices across controllers" )
         for i in range( int( main.numCtrls ) ):
@@ -1063,7 +1457,9 @@
         main.numMNswitches = int ( main.params[ 'TOPO3' ][ 'numSwitches' ] )
         main.numMNlinks = int ( main.params[ 'TOPO3' ][ 'numLinks' ] )
         main.numMNhosts = int ( main.params[ 'TOPO3' ][ 'numHosts' ] )
-
+        main.pingTimeout = 600
+        
+        time.sleep(60)
         main.log.report(
             "Load Spine and Leaf topology and Balance all Mininet switches across controllers" )
         main.log.report(
@@ -1137,16 +1533,35 @@
         #karafTimeout = "3600000" # This is not needed here as it is already set before.
         # need to wait here sometime for ONOS to bootup.
         time.sleep( 30 )
-        for i in range( 1, int( main.numCtrls ) + 1 ):
-            ONOS_ip = main.params[ 'CTRL' ][ 'ip' + str( i ) ]
-            ONOScli = 'ONOScli' + str( i )
-            main.log.info( "ONOS Node " + ONOS_ip + " cli start:" )
-            exec "startcli=main." + ONOScli + \
-                ".startOnosCli(ONOS_ip)"
-            utilities.assert_equals( expect=main.TRUE, actual=startcli,
-                                     onpass="Test step PASS",
-                                     onfail="Test step FAIL" )
-            cliResult = ( cliResult and startcli )
+        
+        main.log.step(" Start ONOS cli using thread ")
+        pool = []
+        for i in range( int( main.numCtrls ) ):
+            t = main.Thread(target=cli.startOnosCli,
+                    threadID=main.threadID,
+                    name="startOnosCli",
+                    args=[nodes[i].ip_address])
+            pool.append(t)
+            t.start()
+            main.threadID = main.threadID + 1
+        for t in pool:
+            t.join()
+            cliResult = cliResult and t.result
+        time2 = time.time()
+        
+        if not cliResult:
+                main.log.info("ONOS CLI did not start up properly")
+                main.cleanup()
+                main.exit()
+        else:
+            main.log.info("Successful CLI startup")
+        main.log.info("Time for connecting to CLI: %2f seconds" %(time2-time1))
+
+        main.step( "Balance devices across controllers" )
+        for i in range( int( main.numCtrls ) ):
+            balanceResult = main.ONOScli1.balanceMasters()
+            # giving some breathing time for ONOS to complete re-balance
+            time.sleep( 3 )
 
         main.step( "Balance devices across controllers" )
         for i in range( int( main.numCtrls ) ):
@@ -1160,3 +1575,128 @@
             actual=case13Result,
             onpass="Starting new Spine topology test PASS",
             onfail="Starting new Spine topology test FAIL" )
+
+    def CASE14( self ):
+        """
+        Install 300 host intents and verify ping all for Chordal Topology
+        """
+        main.log.report( "Add 300 host intents and verify pingall" )
+        main.log.report( "_______________________________________" )
+        import itertools
+        
+        main.case( "Install 300 host intents" )
+        main.step( "Add host Intents" )
+        intentResult = main.TRUE
+        hostCombos = list( itertools.combinations( main.hostMACs, 2 ) ) 
+        
+        intentIdList = []
+        time1 = time.time()
+        
+        for i in xrange( 0, len( hostCombos ), int(main.numCtrls) ):
+            pool = []
+            for cli in main.CLIs:
+                if i >= len( hostCombos ):
+                    break
+                t = main.Thread( target=cli.addHostIntent,
+                        threadID=main.threadID,
+                        name="addHostIntent",
+                        args=[hostCombos[i][0],hostCombos[i][1]])
+                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 host intents: %2f seconds" %(time2-time1))
+        intentResult = main.TRUE
+        intentsJson = main.ONOScli2.intents()
+        getIntentStateResult = main.ONOScli1.getIntentState(intentsId = intentIdList,
+                intentsJson = intentsJson)
+        print getIntentStateResult
+
+        main.step( "Verify Ping across all hosts" )
+        pingResult = main.FALSE
+        time1 = time.time()
+        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+        time2 = time.time()
+        timeDiff = round( ( time2 - time1 ), 2 )
+        main.log.report(
+            "Time taken for Ping All: " +
+            str( timeDiff ) +
+            " seconds" )
+        utilities.assert_equals( expect=main.TRUE, actual=pingResult,
+                                 onpass="PING ALL PASS",
+                                 onfail="PING ALL FAIL" )
+
+        case14Result = ( intentResult and pingResult )
+        
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=case14Result,
+            onpass="Install 300 Host Intents and Ping All test PASS",
+            onfail="Install 300 Host Intents and Ping All test FAIL" )
+
+    def CASE15( self ):
+        """
+        Install 300 host intents and verify ping all for Spine Topology
+        """
+        main.log.report( "Add 300 host intents and verify pingall" )
+        main.log.report( "_______________________________________" )
+        import itertools
+        
+        main.case( "Install 300 host intents" )
+        main.step( "Add host Intents" )
+        intentResult = main.TRUE
+        hostCombos = list( itertools.combinations( main.hostMACs, 2 ) ) 
+        
+        intentIdList = []
+        time1 = time.time()
+        for i in xrange( 0, len( hostCombos ), int(main.numCtrls) ):
+            pool = []
+            for cli in main.CLIs:
+                if i >= len( hostCombos ):
+                    break
+                t = main.Thread( target=cli.addHostIntent,
+                        threadID=main.threadID,
+                        name="addHostIntent",
+                        args=[hostCombos[i][0],hostCombos[i][1]])
+                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 host intents: %2f seconds" %(time2-time1))
+        intentResult = main.TRUE
+        intentsJson = main.ONOScli2.intents()
+        getIntentStateResult = main.ONOScli1.getIntentState(intentsId = intentIdList,
+                intentsJson = intentsJson)
+        print getIntentStateResult
+
+        main.step( "Verify Ping across all hosts" )
+        pingResult = main.FALSE
+        time1 = time.time()
+        pingResult = main.Mininet1.pingall(timeout=main.pingTimeout)
+        time2 = time.time()
+        timeDiff = round( ( time2 - time1 ), 2 )
+        main.log.report(
+            "Time taken for Ping All: " +
+            str( timeDiff ) +
+            " seconds" )
+        utilities.assert_equals( expect=main.TRUE, actual=pingResult,
+                                 onpass="PING ALL PASS",
+                                 onfail="PING ALL FAIL" )
+
+        case15Result = ( intentResult and pingResult )
+        
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=case15Result,
+            onpass="Install 300 Host Intents and Ping All test PASS",
+            onfail="Install 300 Host Intents and Ping All test FAIL" )
+
+
diff --git a/TestON/tests/OnosCHO/OnosCHO.topo b/TestON/tests/OnosCHO/OnosCHO.topo
index b36c789..040e3c5 100644
--- a/TestON/tests/OnosCHO/OnosCHO.topo
+++ b/TestON/tests/OnosCHO/OnosCHO.topo
@@ -56,7 +56,7 @@
         </ONOScli5>
 	
         <ONOS1>
-            <host>10.128.40.40</host>
+            <host>10.128.40.41</host>
             <user>admin</user>
             <password>onos_test</password>
             <type>OnosCliDriver</type>
@@ -65,7 +65,7 @@
         </ONOS1>
 
 	<ONOS2>
-            <host>10.128.40.40</host>
+            <host>10.128.40.42</host>
             <user>admin</user>
             <password>onos_test</password>
             <type>OnosCliDriver</type>
@@ -74,7 +74,7 @@
         </ONOS2>
 	
 	<ONOS3>
-            <host>10.128.40.40</host>
+            <host>10.128.40.43</host>
             <user>admin</user>
             <password>onos_test</password>
             <type>OnosCliDriver</type>
@@ -83,7 +83,7 @@
         </ONOS3>
 
         <ONOS4>
-            <host>10.128.40.40</host>
+            <host>10.128.40.44</host>
             <user>admin</user>
             <password>onos_test</password>
             <type>OnosCliDriver</type>
@@ -92,7 +92,7 @@
         </ONOS4>
 
 	<ONOS5>
-            <host>10.128.40.40</host>
+            <host>10.128.40.45</host>
             <user>admin</user>
             <password>onos_test</password>
             <type>OnosCliDriver</type>
diff --git a/TestON/tests/PingallExample/PingallExample.params b/TestON/tests/PingallExample/PingallExample.params
index 8d0d10b..12bebcd 100644
--- a/TestON/tests/PingallExample/PingallExample.params
+++ b/TestON/tests/PingallExample/PingallExample.params
@@ -3,7 +3,7 @@
     <ENV>
         <cellName>kelvin</cellName>
     </ENV>
-    <Git>True</Git>
+    <Git>xe</Git>
 
     <CTRL>
         <ip1>10.128.10.21</ip1>
diff --git a/TestON/tests/PingallExample/PingallExample.py b/TestON/tests/PingallExample/PingallExample.py
index 653397e..dab380f 100644
--- a/TestON/tests/PingallExample/PingallExample.py
+++ b/TestON/tests/PingallExample/PingallExample.py
@@ -127,7 +127,7 @@
             response = main.Mininet1.getSwController( "s" + str( i ) )
             try:
                 main.log.info( str( response ) )
-            except:
+            except Exception:
                 main.log.info( repr( response ) )
             if re.search( "tcp:" + ONOS1Ip, response ):
                 mastershipCheck = mastershipCheck and main.TRUE
diff --git a/TestON/tests/ProdFunc/ProdFunc.params b/TestON/tests/ProdFunc/ProdFunc.params
index 1189301..a9b212f 100755
--- a/TestON/tests/ProdFunc/ProdFunc.params
+++ b/TestON/tests/ProdFunc/ProdFunc.params
@@ -1,6 +1,6 @@
 <PARAMS>
     
-    <testcases>1,4,10,5,6,7,8,9,2,8,20,21,22,10,23,24</testcases>
+    <testcases>1,4,10,5,6,7,8,9,8,11,8,2,20,21,22,10,23,24</testcases>
     #Environment variables
     <ENV>
         <cellName>driver_test</cellName>
diff --git a/TestON/tests/ProdFunc/ProdFunc.py b/TestON/tests/ProdFunc/ProdFunc.py
old mode 100755
new mode 100644
index 645ae22..fdba3ad
--- a/TestON/tests/ProdFunc/ProdFunc.py
+++ b/TestON/tests/ProdFunc/ProdFunc.py
@@ -133,7 +133,7 @@
                                  onpass="Switch down discovery successful",
                                  onfail="Switch down discovery failed" )
 
-    def CASE11( self, main ):
+    def CASE101( self, main ):
         """
         Cleanup sequence:
         onos-service <nodeIp> stop
@@ -528,7 +528,7 @@
         import time
         main.log.report( "This testcase is testing the assignment of" +
                          " all the switches to all the controllers and" +
-                         " discovering the hists in reactive mode" )
+                         " discovering the hosts in reactive mode" )
         main.log.report( "__________________________________" )
         main.case( "Pingall Test" )
         main.step( "Assigning switches to controllers" )
@@ -688,7 +688,113 @@
             onpass="Reactive forwarding app uninstallation successful",
             onfail="Reactive forwarding app uninstallation failed" )
 
+
+    def CASE11( self ):
+        # NOTE: This testcase require reactive forwarding mode enabled
+        # NOTE: in the beginning and then uninstall it before adding 
+        # NOTE: point intents. Again the app is installed so that 
+        # NOTE: testcase 10 can be ran successively
+        import time
+        main.log.report(
+            "This testcase moves a host from one switch to another to add" +
+            "point intents between them and then perform ping" )
+        main.log.report( "__________________________________" )
+        main.log.info( "Moving host from one switch to another" )
+        main.case( "Moving host from a device and attach it to another device" )
+        main.step( "Moving host h9 from device s9 and attach it to s8" )
+        main.Mininet1.moveHost(host = 'h9', oldSw = 's9', newSw = 's8')
+
+        time.sleep(15) #Time delay to have all the flows ready
+        main.step( "Pingall" )
+        pingResult = main.FALSE
+        time1 = time.time()
+        pingResult = main.Mininet1.pingall()
+        time2 = time.time()
+        print "Time for pingall: %2f seconds" % ( time2 - time1 )
+
+        hosts = main.ONOS2.hosts( jsonFormat = False )
+        main.log.info( hosts )
+        
+        main.case( "Uninstalling reactive forwarding app" )
+        # Unistall onos-app-fwd app to disable reactive forwarding
+        appUninstallResult = main.ONOS2.featureUninstall( "onos-app-fwd" )
+        main.log.info( "onos-app-fwd uninstalled" )
+
+        main.step( "Add point intents between hosts on the same device")
+        ptpIntentResult = main.ONOS2.addPointIntent(
+            "of:0000000000003008/1",
+            "of:0000000000003008/3" )
+        if ptpIntentResult == main.TRUE:
+            getIntentResult = main.ONOS2.intents()
+            main.log.info( "Point to point intent install successful" )
+            # main.log.info( getIntentResult )
+
+        ptpIntentResult = main.ONOS2.addPointIntent(
+            "of:0000000000003008/3",
+            "of:0000000000003008/1" )
+        if ptpIntentResult == main.TRUE:
+            getIntentResult = main.ONOS2.intents()
+            main.log.info( "Point to point intent install successful" )
+            # main.log.info( getIntentResult )
+
+        main.case( "Ping hosts on the same devices" )
+        ping = main.Mininet1.pingHost( src = 'h8', target = 'h9' )
+
+        '''
+        main.case( "Installing reactive forwarding app" )
+        # Install onos-app-fwd app to enable reactive forwarding
+        appUninstallResult = main.ONOS2.featureInstall( "onos-app-fwd" )
+        main.log.info( "onos-app-fwd installed" )
+        '''
+
+        if ping == main.FALSE:
+            main.log.report(
+                "Point intents for hosts on same devices haven't" +
+                " been installed correctly. Cleaning up" )
+        if ping == main.TRUE:
+            main.log.report(
+                "Point intents for hosts on same devices" +
+                "installed correctly. Cleaning up" )
+
+        case11Result = ping and pingResult
+        utilities.assert_equals(
+            expect = main.TRUE,
+            actual = case11Result,
+            onpass = "Point intents for hosts on same devices" +
+                    "Ping Test successful",
+            onfail = "Point intents for hosts on same devices" +
+                    "Ping Test NOT successful" )
+
+
+    def CASE12( self ):
+        """
+        Verify the default flows on each switch
+        """
+        main.log.report( "This testcase is verifying num of default" +
+                         " flows on each switch" )
+        main.log.report( "__________________________________" )
+        main.case( "Verify num of default flows on each switch" )
+        main.step( "Obtaining the device id's and flowrule count on them" )
+
+        case12Result = main.TRUE
+        idList = main.ONOS2.getAllDevicesId()
+        for id in idList:
+            count = main.ONOS2.FlowAddedCount( id )
+            main.log.info("count = " +count)
+            if int(count) != 3:
+                case12Result = main.FALSE
+                break
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=case12Result,
+            onpass = "Expected default num of flows exist",
+            onfail = "Expected default num of flows do not exist")
+    
+    
+        
+
     def CASE6( self ):
+        import time
         main.log.report( "This testcase is testing the addition of" +
                          " host intents and then does pingall" )
         main.log.report( "__________________________________" )
@@ -740,15 +846,15 @@
             # NOTE: get host can return None
             # TODO: handle this
             host1Id = main.ONOS2.getHost( host1 )[ 'id' ]
+      
             host2Id = main.ONOS2.getHost( host2 )[ 'id' ]
             main.ONOS2.addHostIntent( host1Id, host2Id )
-            hIntents = main.ONOS2.intents( jsonFormat=False )
-            main.log.info( "intents:" + hIntents )
 
         time.sleep( 10 )
         hIntents = main.ONOS2.intents( jsonFormat=False )
         main.log.info( "intents:" + hIntents )
-        main.ONOS2.flows()
+        flows = main.ONOS2.flows()
+        main.log.info( "flows:" + flows )     
 
         count = 1
         i = 8
@@ -1077,14 +1183,11 @@
         intentResult = main.ONOS2.intents( jsonFormat=False )
         main.log.info( "intent_result = " + intentResult )
         intentLinewise = intentResult.split( "\n" )
-        intentList = []
-        for line in intentLinewise:
-            if line.startswith( "id=" ):
-                intentList.append( line )
 
-        intentids = []
-        for line in intentList:
-            intentids.append( line.split( "," )[ 0 ].split( "=" )[ 1 ] )
+        intentList = [line for line in intentLinewise \
+            if line.startswith( "id=")]
+        intentids = [line.split( "," )[ 0 ].split( "=" )[ 1 ] for line in \
+            intentList]
         for id in intentids:
             print "id = ", id
 
@@ -1095,8 +1198,20 @@
 
         intentResult = main.ONOS2.intents( jsonFormat=False )
         main.log.info( "intent_result = " + intentResult )
-
-        case8Result = main.TRUE
+        
+        intentList = [line for line in intentResult.split( "\n" ) \
+            if line.startswith( "id=")]
+        intentState = [line.split( "," )[ 1 ].split( "=" )[ 1 ] for line in \
+            intentList]
+        for state in intentState:
+            print state
+        
+        case8Result = main.TRUE        
+        for state in intentState:
+            if state != 'WITHDRAWN':
+                case8Result = main.FALSE
+                break
+                
         if case8Result == main.TRUE:
             main.log.report( "Intent removal successful" )
         else:
@@ -1328,7 +1443,7 @@
         if ptpIntentResult == main.TRUE:
             getIntentResult = main.ONOS2.intents()
             main.log.info( "Point to point intent install successful" )
-            main.log.info( getIntentResult )
+            #main.log.info( getIntentResult )
 
         ptpIntentResult = main.ONOS2.addPointIntent(
             "of:0000000000006027/1",
@@ -1336,7 +1451,7 @@
         if ptpIntentResult == main.TRUE:
             getIntentResult = main.ONOS2.intents()
             main.log.info( "Point to point intent install successful" )
-            main.log.info( getIntentResult )
+            #main.log.info( getIntentResult )
 
         print(
             "___________________________________________________________" )
diff --git a/TestON/tests/ProdFunc/ProdFunc.topo b/TestON/tests/ProdFunc/ProdFunc.topo
index c3fe280..73a0b4f 100755
--- a/TestON/tests/ProdFunc/ProdFunc.topo
+++ b/TestON/tests/ProdFunc/ProdFunc.topo
@@ -63,7 +63,7 @@
                 #Specify the Option for mininet
                 <arg1> --custom ~/mininet/custom/topo-HA.py </arg1>
                 <arg2> --topo mytopo </arg2>
-                <arg3> --switch ovs,protocols=OpenFlow13 </arg3>
+                <arg3> --switch ovs,protocols=OpenFlow10 </arg3>
                 <controller> remote </controller>
             </COMPONENTS>
         </Mininet2>
diff --git a/TestON/tests/IntentsLoad/__init__.py b/TestON/tests/ProdFunc/__init__.py
similarity index 100%
copy from TestON/tests/IntentsLoad/__init__.py
copy to TestON/tests/ProdFunc/__init__.py
diff --git a/TestON/tests/ProdFunc13/ProdFunc13.params b/TestON/tests/ProdFunc13/ProdFunc13.params
index bb3c11c..a9b212f 100755
--- a/TestON/tests/ProdFunc13/ProdFunc13.params
+++ b/TestON/tests/ProdFunc13/ProdFunc13.params
@@ -1,7 +1,6 @@
 <PARAMS>
     
-    <testcases>1,4,10,5,6,7,8,9,2,20,21,22,10,23,24</testcases>
-
+    <testcases>1,4,10,5,6,7,8,9,8,11,8,2,20,21,22,10,23,24</testcases>
     #Environment variables
     <ENV>
         <cellName>driver_test</cellName>
diff --git a/TestON/tests/ProdFunc13/ProdFunc13.py b/TestON/tests/ProdFunc13/ProdFunc13.py
index 13dc26d..44e78b7 100644
--- a/TestON/tests/ProdFunc13/ProdFunc13.py
+++ b/TestON/tests/ProdFunc13/ProdFunc13.py
@@ -133,7 +133,7 @@
                                  onpass="Switch down discovery successful",
                                  onfail="Switch down discovery failed" )
 
-    def CASE11( self, main ):
+    def CASE101( self, main ):
         """
         Cleanup sequence:
         onos-service <nodeIp> stop
@@ -528,7 +528,7 @@
         import time
         main.log.report( "This testcase is testing the assignment of" +
                          " all the switches to all the controllers and" +
-                         " discovering the hists in reactive mode" )
+                         " discovering the hosts in reactive mode" )
         main.log.report( "__________________________________" )
         main.case( "Pingall Test" )
         main.step( "Assigning switches to controllers" )
@@ -688,7 +688,113 @@
             onpass="Reactive forwarding app uninstallation successful",
             onfail="Reactive forwarding app uninstallation failed" )
 
+
+    def CASE11( self ):
+        # NOTE: This testcase require reactive forwarding mode enabled
+        # NOTE: in the beginning and then uninstall it before adding 
+        # NOTE: point intents. Again the app is installed so that 
+        # NOTE: testcase 10 can be ran successively
+        import time
+        main.log.report(
+            "This testcase moves a host from one switch to another to add" +
+            "point intents between them and then perform ping" )
+        main.log.report( "__________________________________" )
+        main.log.info( "Moving host from one switch to another" )
+        main.case( "Moving host from a device and attach it to another device" )
+        main.step( "Moving host h9 from device s9 and attach it to s8" )
+        main.Mininet1.moveHost(host = 'h9', oldSw = 's9', newSw = 's8')
+
+        time.sleep(15) #Time delay to have all the flows ready
+        main.step( "Pingall" )
+        pingResult = main.FALSE
+        time1 = time.time()
+        pingResult = main.Mininet1.pingall()
+        time2 = time.time()
+        print "Time for pingall: %2f seconds" % ( time2 - time1 )
+
+        hosts = main.ONOS2.hosts( jsonFormat = False )
+        main.log.info( hosts )
+        
+        main.case( "Uninstalling reactive forwarding app" )
+        # Unistall onos-app-fwd app to disable reactive forwarding
+        appUninstallResult = main.ONOS2.featureUninstall( "onos-app-fwd" )
+        main.log.info( "onos-app-fwd uninstalled" )
+
+        main.step( "Add point intents between hosts on the same device")
+        ptpIntentResult = main.ONOS2.addPointIntent(
+            "of:0000000000003008/1",
+            "of:0000000000003008/3" )
+        if ptpIntentResult == main.TRUE:
+            getIntentResult = main.ONOS2.intents()
+            main.log.info( "Point to point intent install successful" )
+            # main.log.info( getIntentResult )
+
+        ptpIntentResult = main.ONOS2.addPointIntent(
+            "of:0000000000003008/3",
+            "of:0000000000003008/1" )
+        if ptpIntentResult == main.TRUE:
+            getIntentResult = main.ONOS2.intents()
+            main.log.info( "Point to point intent install successful" )
+            # main.log.info( getIntentResult )
+
+        main.case( "Ping hosts on the same devices" )
+        ping = main.Mininet1.pingHost( src = 'h8', target = 'h9' )
+
+        '''
+        main.case( "Installing reactive forwarding app" )
+        # Install onos-app-fwd app to enable reactive forwarding
+        appUninstallResult = main.ONOS2.featureInstall( "onos-app-fwd" )
+        main.log.info( "onos-app-fwd installed" )
+        '''
+
+        if ping == main.FALSE:
+            main.log.report(
+                "Point intents for hosts on same devices haven't" +
+                " been installed correctly. Cleaning up" )
+        if ping == main.TRUE:
+            main.log.report(
+                "Point intents for hosts on same devices" +
+                "installed correctly. Cleaning up" )
+
+        case11Result = ping and pingResult
+        utilities.assert_equals(
+            expect = main.TRUE,
+            actual = case11Result,
+            onpass = "Point intents for hosts on same devices" +
+                    "Ping Test successful",
+            onfail = "Point intents for hosts on same devices" +
+                    "Ping Test NOT successful" )
+
+
+    def CASE12( self ):
+        """
+        Verify the default flows on each switch in proactive mode
+        """
+        main.log.report( "This testcase is verifying num of default" +
+                         " flows on each switch" )
+        main.log.report( "__________________________________" )
+        main.case( "Verify num of default flows on each switch" )
+        main.step( "Obtaining the device id's and flowrule count on them" )
+
+        case12Result = main.TRUE
+        idList = main.ONOS2.getAllDevicesId()
+        for id in idList:
+            count = main.ONOS2.FlowAddedCount( id )
+            main.log.info("count = " +count)
+            if int(count) != 3:
+                case12Result = main.FALSE
+                break
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=case12Result,
+            onpass = "Expected default num of flows exist",
+            onfail = "Expected default num of flows do not exist")
+    
+    
+        
+
     def CASE6( self ):
+        import time
         main.log.report( "This testcase is testing the addition of" +
                          " host intents and then does pingall" )
         main.log.report( "__________________________________" )
@@ -740,15 +846,15 @@
             # NOTE: get host can return None
             # TODO: handle this
             host1Id = main.ONOS2.getHost( host1 )[ 'id' ]
+      
             host2Id = main.ONOS2.getHost( host2 )[ 'id' ]
             main.ONOS2.addHostIntent( host1Id, host2Id )
-            hIntents = main.ONOS2.intents( jsonFormat=False )
-            main.log.info( "intents:" + hIntents )
 
         time.sleep( 10 )
         hIntents = main.ONOS2.intents( jsonFormat=False )
         main.log.info( "intents:" + hIntents )
-        main.ONOS2.flows()
+        flows = main.ONOS2.flows()
+        main.log.info( "flows:" + flows )     
 
         count = 1
         i = 8
@@ -970,8 +1076,8 @@
         main.step( "Determine the current number of switches and links" )
         topologyOutput = main.ONOS2.topology()
         topologyResult = main.ONOS1.getTopology( topologyOutput )
-        activeSwitches = topologyResult[ 'devices' ]
-        links = topologyResult[ 'links' ]
+        activeSwitches = topologyResult[ 'deviceCount' ]
+        links = topologyResult[ 'linkCount' ]
         print "activeSwitches = ", type( activeSwitches )
         print "links = ", type( links )
         main.log.info(
@@ -1077,14 +1183,11 @@
         intentResult = main.ONOS2.intents( jsonFormat=False )
         main.log.info( "intent_result = " + intentResult )
         intentLinewise = intentResult.split( "\n" )
-        intentList = []
-        for line in intentLinewise:
-            if line.startswith( "id=" ):
-                intentList.append( line )
 
-        intentids = []
-        for line in intentList:
-            intentids.append( line.split( "," )[ 0 ].split( "=" )[ 1 ] )
+        intentList = [line for line in intentLinewise \
+            if line.startswith( "id=")]
+        intentids = [line.split( "," )[ 0 ].split( "=" )[ 1 ] for line in \
+            intentList]
         for id in intentids:
             print "id = ", id
 
@@ -1095,8 +1198,20 @@
 
         intentResult = main.ONOS2.intents( jsonFormat=False )
         main.log.info( "intent_result = " + intentResult )
-
-        case8Result = main.TRUE
+        
+        intentList = [line for line in intentResult.split( "\n" ) \
+            if line.startswith( "id=")]
+        intentState = [line.split( "," )[ 1 ].split( "=" )[ 1 ] for line in \
+            intentList]
+        for state in intentState:
+            print state
+        
+        case8Result = main.TRUE        
+        for state in intentState:
+            if state != 'WITHDRAWN':
+                case8Result = main.FALSE
+                break
+                
         if case8Result == main.TRUE:
             main.log.report( "Intent removal successful" )
         else:
@@ -1328,7 +1443,7 @@
         if ptpIntentResult == main.TRUE:
             getIntentResult = main.ONOS2.intents()
             main.log.info( "Point to point intent install successful" )
-            main.log.info( getIntentResult )
+            #main.log.info( getIntentResult )
 
         ptpIntentResult = main.ONOS2.addPointIntent(
             "of:0000000000006027/1",
@@ -1336,7 +1451,7 @@
         if ptpIntentResult == main.TRUE:
             getIntentResult = main.ONOS2.intents()
             main.log.info( "Point to point intent install successful" )
-            main.log.info( getIntentResult )
+            #main.log.info( getIntentResult )
 
         print(
             "___________________________________________________________" )
diff --git a/TestON/tests/IntentsLoad/__init__.py b/TestON/tests/ProdFunc13/__init__.py
similarity index 100%
copy from TestON/tests/IntentsLoad/__init__.py
copy to TestON/tests/ProdFunc13/__init__.py
diff --git a/TestON/tests/ScaleOutTemplate/.ScaleOutTemplate.py.swo b/TestON/tests/ScaleOutTemplate/.ScaleOutTemplate.py.swo
new file mode 100644
index 0000000..a1a28ae
--- /dev/null
+++ b/TestON/tests/ScaleOutTemplate/.ScaleOutTemplate.py.swo
Binary files differ
diff --git a/TestON/tests/ScaleOutTemplate/README b/TestON/tests/ScaleOutTemplate/README
new file mode 100644
index 0000000..2d5ae1c
--- /dev/null
+++ b/TestON/tests/ScaleOutTemplate/README
@@ -0,0 +1,22 @@
+-------------------
+----Setup Guide----
+-------------------
+
+CASE 1: init case; cleans and sets up enviornment, starts up node 1
+
+CASE 2: Increments scale case; starts up additional nodes, determined by 'SCALE' in params 
+        Ex: cluster size = 1 and scale = 2 ==> call CASE2 ==> cluster size = 3 
+
+Params file:
+    SCALE = cluster scale step size 
+    availableNodes = number of nodes you have provided data for in .topo file 
+
+    ENV:
+        cellName = desired name of cell file to be created at runtime
+        cellFeatures = list of features desired                        
+            NOTE: webconsole, onos-api, onos-cli and onos-openflow are loaded automatically.
+            adjust your test and feature list accordingly 
+    TEST: 
+        skipCleanInstall = set yes if you want to skip for the sake of test debugging, otherwise set no
+
+    
diff --git a/TestON/tests/ScaleOutTemplate/ScaleOutTemplate.params b/TestON/tests/ScaleOutTemplate/ScaleOutTemplate.params
index 4dacc99..641d16a 100644
--- a/TestON/tests/ScaleOutTemplate/ScaleOutTemplate.params
+++ b/TestON/tests/ScaleOutTemplate/ScaleOutTemplate.params
@@ -2,11 +2,17 @@
 
     <testcases>1,2</testcases>
 
+    <SCALE>2</SCALE>
+    <availableNodes>7</availableNodes>
+ 
     <ENV>
-    <cellName>cam_cells</cellName>
+        <cellName>defaultCell</cellName>
+        <cellFeatures></cellFeatures>
     </ENV>
 
-    <SCALE>2</SCALE>
+    <TEST>
+        <skipCleanInstall>yes</skipCleanInstall>
+    </TEST>
 
     <GIT>
         <autopull>on</autopull>
@@ -15,12 +21,28 @@
 
     <CTRL>
         <USER>admin</USER>
+        
         <ip1>10.128.5.51</ip1>
         <port1>6633</port1>
+        
         <ip2>10.128.5.52</ip2>
         <port2>6633</port2>
+        
         <ip3>10.128.5.53</ip3>
         <port3>6633</port3>
+        
+        <ip4>10.128.5.54</ip4>
+        <port4>6633</port4>
+        
+        <ip5>10.128.5.65</ip5>
+        <port5>6633</port5>
+        
+        <ip6>10.128.5.66</ip6>
+        <port6>6633</port6> 
+       
+         <ip7>10.128.5.67</ip7>
+        <port7>6633</port7>
+
     </CTRL>
 
     <MN>
@@ -32,9 +54,6 @@
         <ip1>10.128.5.55</ip1>
     </BENCH>
 
-    <TEST>
-    </TEST>
-
     <JSON>
     </JSON>
 
diff --git a/TestON/tests/ScaleOutTemplate/ScaleOutTemplate.py b/TestON/tests/ScaleOutTemplate/ScaleOutTemplate.py
index a75d694..fdcd680 100644
--- a/TestON/tests/ScaleOutTemplate/ScaleOutTemplate.py
+++ b/TestON/tests/ScaleOutTemplate/ScaleOutTemplate.py
@@ -4,133 +4,131 @@
 #
 # cameron@onlab.us
 
-import sys 
-import os 
+import sys
+import os.path
 
 
 class ScaleOutTemplate:
-    def __init__(self):
+
+    def __init__( self ):
         self.default = ''
-   
-    def CASE1(self, main):
+
+    def CASE1( self, main ):            #This is the initialization case
+                                        #this case will clean up all nodes 
+        import time                     #but only node 1 is started in this case
         
-        global cluster_count 
-        cluster_count = 1        
+        global clusterCount             #number of nodes running
+        global ONOSIp                   #list of ONOS IP addresses 
+        clusterCount = 1
+        ONOSIp = [ 0 ]
 
-        checkout_branch = main.params['GIT']['checkout']
-        git_pull = main.params['GIT']['autopull']
-        cell_name = main.params['ENV']['cellName']
-        BENCH_ip = main.params['BENCH']['ip1']
-        BENCH_user = main.params['BENCH']['user']
-        ONOS1_ip = main.params['CTRL']['ip1']
-        ONOS2_ip = main.params['CTRL']['ip2']
-        ONOS3_ip = main.params['CTRL']['ip3']
-        MN1_ip = main.params['MN']['ip1']
 
-        main.log.step("Cleaning Enviornment...")
-        main.ONOSbench.onos_uninstall(ONOS1_ip)
-        main.ONOSbench.onos_uninstall(ONOS2_ip)
-        main.ONOSbench.onos_uninstall(ONOS3_ip)                                     
+        #Load values from params file
+        checkoutBranch = main.params[ 'GIT' ][ 'checkout' ]
+        gitPull = main.params[ 'GIT' ][ 'autopull' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        Features= main.params[ 'ENV' ][ 'cellFeatures' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+        MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+        maxNodes = int(main.params[ 'availableNodes' ])
+        Features = main.params[ 'ENV' ][ 'cellFeatures' ]
+        skipMvn = main.params[ 'TEST' ][ 'skipCleanInstall' ]
+
+        #Populate ONOSIp with ips from params 
+        for i in range(1, maxNodes + 1): 
+            ipString = 'ip' + str(i) 
+            ONOSIp.append(main.params[ 'CTRL' ][ ipString ])   
+
+        #############################
+        tempIp = [ ONOSIp[1],ONOSIp[2],ONOSIp[3],ONOSIp[4],ONOSIp[5]]
+        main.ONOSbench.createLinkGraphFile(BENCHIp, tempIp, str(7)) 
+
+        main.log.info("marker")
+        #############################
+
+
+        #kill off all onos processes 
+        main.log.step("Safety check, killing all ONOS processes")
+        main.log.step("before initiating enviornment setup")
+        for node in range(1, maxNodes + 1):
+            main.ONOSbench.onosDie(ONOSIp[node])
+
+
+        #construct the cell file
+        main.log.info("Creating cell file")
+        exec "a = main.ONOSbench.createCellFile"
+        cellIp = []
+        for node in range (1, maxNodes + 1):
+            cellIp.append(ONOSIp[node])
+        a(BENCHIp,cellName,MN1Ip,str(Features), *cellIp)
+
+        #Uninstall everywhere
+        main.log.step( "Cleaning Enviornment..." )
+        for i in range(1, maxNodes + 1):
+            main.log.info(" Uninstalling ONOS " + str(i) )
+            main.ONOSbench.onosUninstall( ONOSIp[i] )
         
-        main.step("Git checkout and pull "+checkout_branch)
-        if git_pull == 'on':
-            checkout_result = main.ONOSbench.git_checkout(checkout_branch)       
-            pull_result = main.ONOSbench.git_pull()
-            
-        else:
-            checkout_result = main.TRUE
-            pull_result = main.TRUE
-            main.log.info("Skipped git checkout and pull")
+        #mvn clean install, for debugging set param 'skipCleanInstall' to yes to speed up test
+        if skipMvn != "yes":
+            mvnResult = main.ONOSbench.cleanInstall()
+                        
+            #git
+            main.step( "Git checkout and pull " + checkoutBranch )
+            if gitPull == 'on':
+                checkoutResult = main.ONOSbench.gitCheckout( checkoutBranch )
+                pullResult = main.ONOSbench.gitPull()
 
-        mvn_result = main.ONOSbench.clean_install()
-                                                                   
-        main.step("Set cell for ONOS cli env")
-        main.ONOS1cli.set_cell(cell_name)
-        main.ONOS2cli.set_cell(cell_name)
-        main.ONOS3cli.set_cell(cell_name)
+            else:
+                checkoutResult = main.TRUE
+                pullResult = main.TRUE
+                main.log.info( "Skipped git checkout and pull" )
 
-        main.step("Creating ONOS package")
-        package_result = main.ONOSbench.onos_package()                             #no file or directory 
 
-        main.step("Installing ONOS package")
-        install1_result = main.ONOSbench.onos_install(node=ONOS1_ip)
-
-        cell_name = main.params['ENV']['cellName']
-        main.step("Applying cell file to environment")
-        cell_apply_result = main.ONOSbench.set_cell(cell_name)
-        main.step("verify cells")
-        verify_cell_result = main.ONOSbench.verify_cell()
-
-        main.step("Set cell for ONOS cli env")
-        main.ONOS1cli.set_cell(cell_name) 
-        cli1 = main.ONOS1cli.start_onos_cli(ONOS1_ip)  
-       
-
-    def CASE2(self, main):
-
-        '''  
-        Increase number of nodes and initiate CLI
-        '''
-        import time 
+        #main.step( "Set cell for ONOS cli env" )
+        #main.ONOS1cli.setCell( cellName )
         
-        global cluster_count
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.onosPackage()  
+
+        main.step( "Installing ONOS package" )
+        install1Result = main.ONOSbench.onosInstall( node=ONOSIp[1] )
+
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        main.step( "Applying cell file to environment" )
+        cellApplyResult = main.ONOSbench.setCell( cellName )
+        main.step( "verify cells" )
+        verifyCellResult = main.ONOSbench.verifyCell()
+
+        main.step( "Set cell for ONOS cli env" )
+        cli1 = main.ONOS1cli.startOnosCli( ONOSIp[1] )
+
         
-        ONOS1_ip = main.params['CTRL']['ip1']
-        ONOS2_ip = main.params['CTRL']['ip2']
-        ONOS3_ip = main.params['CTRL']['ip3']
-        #ONOS4_ip = main.params['CTRL']['ip4']
-        #ONOS5_ip = main.params['CTRL']['ip5']
-        #ONOS6_ip = main.params['CTRL']['ip6']
-        #ONOS7_ip = main.params['CTRL']['ip7']
-        cell_name = main.params['ENV']['cellName']
-        scale = int(main.params['SCALE'])
-       
-        #Cluster size increased everytime the case is defined
-        cluster_count += scale
- 
-        main.log.report("Increasing cluster size to "+
-                str(cluster_count))
-        install_result = main.FALSE
+    def CASE2( self, main ):
+        # This case increases the cluster size by whatever scale is
+        # Note: 'scale' is the size of the step
+        # if scaling is not a part of your test, simply run this case
+        # once after CASE1 to set up your enviornment for your desired 
+        # cluster size. If scaling is a part of you test call this case each time 
+        # you want to increase cluster size
+
+        ''                                                         
+        'Increase number of nodes and initiate CLI'
+        ''
+        import time
+        global clusterCount
         
-        if scale == 2:
-            if cluster_count == 3:
-                main.log.info("Installing nodes 2 and 3")
-                install2_result = main.ONOSbench.onos_install(node=ONOS2_ip)
-                install3_result = main.ONOSbench.onos_install(node=ONOS3_ip)
-                cli2 = main.ONOS1cli.start_onos_cli(ONOS2_ip)
-                cli3 = main.ONOS1cli.start_onos_cli(ONOS3_ip)
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        scale = int( main.params[ 'SCALE' ] )
+        clusterCount += scale
 
-            '''
-            elif cluster_count == 5:
-
-                main.log.info("Installing nodes 4 and 5")
-                node4_result = main.ONOSbench.onos_install(node=ONOS4_ip)
-                node5_result = main.ONOSbench.onos_install(node=ONOS5_ip)
-                install_result = node4_result and node5_result
-                time.sleep(5)
-
-                main.ONOS4cli.start_onos_cli(ONOS4_ip)
-                main.ONOS5cli.start_onos_cli(ONOS5_ip)
-
-            elif cluster_count == 7:
-
-                main.log.info("Installing nodes 4 and 5")
-                node6_result = main.ONOSbench.onos_install(node=ONOS6_ip)
-                node7_result = main.ONOSbench.onos_install(node=ONOS7_ip)
-                install_result = node6_result and node7_result
-                time.sleep(5)
-
-                main.ONOS6cli.start_onos_cli(ONOS6_ip)
-                main.ONOS7cli.start_onos_cli(ONOS7_ip)
-            '''
-        if scale == 1: 
-            if cluster_count == 2:
-                main.log.info("Installing node 2")
-                install2_result = main.ONOSbench.onos_install(node=ONOS2_ip)
-                cli2 = main.ONOS1cli.start_onos_cli(ONOS2_ip)
-
-            if cluster_count == 3:
-                main.log.info("Installing node 3")
-                install3_result = main.ONOSbench.onos_install(node=ONOS3_ip)
-                cli3 = main.ONOS1cli.start_onos_cli(ONOS3_ip)
+        main.log.report( "Increasing cluster size to " + str( clusterCount ) )
+        for node in range((clusterCount - scale) + 1, clusterCount + 1):
+            main.ONOSbench.onosDie(ONOSIp[node])
+            time.sleep(10)
+            main.log.info("Starting ONOS " + str(node) + " at IP: " + ONOSIp[node])    
+            main.ONOSbench.onosInstall( node=ONOSIp[node])
+            exec "a = main.ONOS%scli.startOnosCli" %str(node)
+            a(ONOSIp[node])
+         
 
diff --git a/TestON/tests/ScaleOutTemplate/ScaleOutTemplate.topo b/TestON/tests/ScaleOutTemplate/ScaleOutTemplate.topo
index 88c4d35..8bd5a9f 100644
--- a/TestON/tests/ScaleOutTemplate/ScaleOutTemplate.topo
+++ b/TestON/tests/ScaleOutTemplate/ScaleOutTemplate.topo
@@ -37,13 +37,13 @@
             <connect_order>4</connect_order>
             <COMPONENTS> </COMPONENTS>
         </ONOS3cli>
-
+       
         <ONOS1>
             <host>10.128.5.51</host>
             <user>sdn</user>
             <password>rocks</password>
             <type>OnosDriver</type>
-            <connect_order>5</connect_order>
+            <connect_order>9</connect_order>
             <COMPONENTS> </COMPONENTS>
         </ONOS1>
 
@@ -52,7 +52,7 @@
             <user>sdn</user>
             <password>rocks</password>
             <type>OnosDriver</type>
-            <connect_order>6</connect_order>
+            <connect_order>10</connect_order>
             <COMPONENTS> </COMPONENTS>
         </ONOS2>
 
@@ -61,7 +61,7 @@
             <user>sdn</user>
             <password>rocks</password>
             <type>OnosDriver</type>
-            <connect_order>7</connect_order>
+            <connect_order>11</connect_order>
             <COMPONENTS> </COMPONENTS>
         </ONOS3>
 
@@ -70,7 +70,7 @@
             <user>admin</user>
             <password>onos_test</password>
             <type>MininetCliDriver</type>
-            <connect_order>8</connect_order>
+            <connect_order>16</connect_order>
             <COMPONENTS>
                 <arg1> --custom ~/mininet/custom/topo-2sw-2host.py </arg1>
                 <arg2> --arp --mac --topo mytopo</arg2>
diff --git a/TestON/tests/IntentsLoad/__init__.py b/TestON/tests/TopoConvNext/__init__.py
similarity index 100%
copy from TestON/tests/IntentsLoad/__init__.py
copy to TestON/tests/TopoConvNext/__init__.py
diff --git a/TestON/tests/IntentsLoad/__init__.py b/TestON/tests/TopoPerfNext/__init__.py
similarity index 100%
copy from TestON/tests/IntentsLoad/__init__.py
copy to TestON/tests/TopoPerfNext/__init__.py
diff --git a/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.params b/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.params
new file mode 100644
index 0000000..09c741c
--- /dev/null
+++ b/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.params
@@ -0,0 +1,93 @@
+<PARAMS>
+    <testcases>1,2,3,4,2,3,4,2,3,4,2,3</testcases>
+
+    <ENV>
+        <cellName>topo_perf_test</cellName>
+        <cellFeatures>"webconsole,onos-core,onos-api,onos-cli,onos-app-metrics,onos-app-gui,onos-openflow"</cellFeatures>
+    </ENV>
+
+    <GIT>
+        #autoPull 'on' or 'off'
+        <autoPull>off</autoPull>
+        <checkout>master</checkout>
+    </GIT>
+
+    <CTRL>
+        <user>sdn</user>
+        <ip1>10.254.1.201</ip1>
+        <port1>6633</port1>
+        <ip2>10.254.1.202</ip2>
+        <port2>6633</port2>
+        <ip3>10.254.1.203</ip3>
+        <port3>6633</port3>
+        <ip4>10.254.1.204</ip4>
+        
+        <ip5>10.254.1.205</ip5>
+        <ip6>10.254.1.206</ip6>
+        <ip7>10.254.1.207</ip7>
+    </CTRL>
+
+    <MN>
+        <ip1>10.254.1.200</ip1>
+        <ip2>10.254.1.200</ip2>
+    </MN>
+
+    <BENCH>
+        <ip>10.254.1.200</ip>
+    </BENCH>
+
+    <TSHARK>
+        <ofpPortStatus>OF 1.3 146</ofpPortStatus>
+        <ofpRoleReply>OF 1.3 90 of_role_reply</ofpRoleReply>
+        <tcpSynAck>TCP 74 6633</tcpSynAck>
+    </TSHARK>
+
+    <TEST>
+        #'on' or 'off' debug mode.
+        #If on, logging will be more verbose and
+        #tshark pcap will be enabled
+        #pcap file located at /tmp/'capture_name'
+        <debugMode>on</debugMode>
+        <onosLogFile>/opt/onos/log/karaf*</onosLogFile>
+        <mci>off</mci>
+
+        <topoConfigFile>
+        single_topo_event_accumulator.cfg
+        </topoConfigFile>
+        <topoConfigName>
+        org.onlab.onos.net.topology.impl.DefaultTopologyProvider.cfg
+        </topoConfigName>
+
+        #Number of times to iterate each case
+        <numIter>10</numIter>
+        <numSwitch>2</numSwitch>
+        #Number of iterations to ignore initially
+        <iterIgnore>2</iterIgnore>
+
+        <singleSwThreshold>0,1000</singleSwThreshold>
+        <portUpThreshold>0,1000</portUpThreshold>
+        <portDownThreshold>0,1000</portDownThreshold>
+        <linkUpThreshold>0,10000</linkUpThreshold>
+        <linkDownThreshold>0,10000</linkDownThreshold>
+        <swDisc100Threshold>0,10000</swDisc100Threshold>
+    
+        <tabletFile>tablets_3node.json</tabletFile>
+   </TEST>
+
+    <DB>
+        <postToDB>on</postToDB>
+        <portEventResultPath>
+        /home/admin/ONLabTest/TestON/tests/TopoPerfNextBM/portEventResultDb.log
+        </portEventResultPath>
+        <switchEventResultPath>
+        /home/admin/ONLabTest/TestON/tests/TopoPerfNextBM/switchEventResultDb.log
+        </switchEventResultPath>
+    </DB>
+
+    <JSON>
+        <deviceTimestamp>topologyDeviceEventTimestamp</deviceTimestamp>
+        <hostTimestamp>topologyHostEventTimestamp</hostTimestamp>
+        <linkTimestamp>topologyLinkEventTimestamp</linkTimestamp>
+        <graphTimestamp>topologyGraphEventTimestamp</graphTimestamp>
+    </JSON>
+</PARAMS>
diff --git a/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.py b/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.py
new file mode 100644
index 0000000..872238e
--- /dev/null
+++ b/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.py
@@ -0,0 +1,1186 @@
+# 2015.03.12 10:22:05 PDT
+#Embedded file name: ../tests/TopoPerfNextBM/TopoPerfNextBM.py
+import time
+import sys
+import os
+import re
+
+class TopoPerfNextBM:
+
+    def __init__(self):
+        self.default = ''
+
+    def CASE1(self, main):
+        """
+        ONOS startup sequence
+        """
+        global clusterCount
+        global timeToPost
+        global runNum
+        import time
+        clusterCount = 1
+        timeToPost = time.strftime('%Y-%m-%d %H:%M:%S')
+        runNum = time.strftime('%d%H%M%S')
+        cellName = main.params['ENV']['cellName']
+        gitPull = main.params['GIT']['autoPull']
+        checkoutBranch = main.params['GIT']['checkout']
+        
+        ONOS1Ip = main.params['CTRL']['ip1']
+        ONOS2Ip = main.params['CTRL']['ip2']
+        ONOS3Ip = main.params['CTRL']['ip3']
+        ONOS4Ip = main.params['CTRL']['ip4']
+        ONOS5Ip = main.params['CTRL']['ip5']
+        ONOS6Ip = main.params['CTRL']['ip6']
+        ONOS7Ip = main.params['CTRL']['ip7']
+        MN1Ip = main.params['MN']['ip1']
+        BENCHIp = main.params['BENCH']['ip']
+        
+        topoCfgFile = main.params['TEST']['topoConfigFile']
+        topoCfgName = main.params['TEST']['topoConfigName']
+        portEventResultPath = main.params['DB']['portEventResultPath']
+        switchEventResultPath = main.params['DB']['switchEventResultPath']
+        mvnCleanInstall = main.params['TEST']['mci']
+        
+        main.case('Setting up test environment')
+        main.log.info('Copying topology event accumulator config' +
+                ' to ONOS /package/etc')
+        main.ONOSbench.handle.sendline('cp ~/' +
+                topoCfgFile + ' ~/ONOS/tools/package/etc/' +
+                topoCfgName)
+        main.ONOSbench.handle.expect('\\$')
+        
+        main.log.report('Setting up test environment')
+        
+        main.step('Starting mininet topology ')
+        main.Mininet1.startNet()
+        
+        main.step('Cleaning previously installed ONOS if any')
+        main.ONOSbench.onosUninstall(nodeIp=ONOS2Ip)
+        main.ONOSbench.onosUninstall(nodeIp=ONOS3Ip)
+        main.ONOSbench.onosUninstall(nodeIp=ONOS4Ip)
+        main.ONOSbench.onosUninstall(nodeIp=ONOS5Ip)
+        main.ONOSbench.onosUninstall(nodeIp=ONOS6Ip)
+        main.ONOSbench.onosUninstall(nodeIp=ONOS7Ip)
+        
+        main.step('Clearing previous DB log file')
+        
+        fPortLog = open(portEventResultPath, 'w')
+        fPortLog.write('')
+        fPortLog.close()
+        fSwitchLog = open(switchEventResultPath, 'w')
+        fSwitchLog.write('')
+        fSwitchLog.close()
+        
+        cellStr = 'webconsole,onos-core,onos-api,onos-app-metrics,' +\
+                'onos-app-gui,onos-cli,onos-openflow'
+        
+        main.step('Creating cell file')
+        cellFileResult = main.ONOSbench.createCellFile(
+                BENCHIp, cellName, MN1Ip, cellStr, ONOS1Ip)
+        
+        main.step('Applying cell file to environment')
+        cellApplyResult = main.ONOSbench.setCell(cellName)
+        verifyCellResult = main.ONOSbench.verifyCell()
+        
+        main.step('Git checkout and pull ' + checkoutBranch)
+        if gitPull == 'on':
+            checkoutResult = main.TRUE
+            pullResult = main.ONOSbench.gitPull()
+        else:
+            checkoutResult = main.TRUE
+            pullResult = main.TRUE
+            main.log.info('Skipped git checkout and pull')
+        
+        main.log.report('Commit information - ')
+        main.ONOSbench.getVersion(report=True)
+        main.step('Using mvn clean & install')
+        if mvnCleanInstall == 'on':
+            mvnResult = main.ONOSbench.cleanInstall()
+        elif mvnCleanInstall == 'off':
+            main.log.info('mci turned off by settings')
+            mvnResult = main.TRUE
+        main.step('Set cell for ONOS cli env')
+        main.ONOS1cli.setCell(cellName)
+        
+        main.step('Creating ONOS package')
+        packageResult = main.ONOSbench.onosPackage()
+        
+        main.step('Installing ONOS package')
+        install1Result = main.ONOSbench.onosInstall(node=ONOS1Ip)
+        
+        time.sleep(10)
+        
+        main.step('Start onos cli')
+        cli1 = main.ONOS1cli.startOnosCli(ONOS1Ip)
+        utilities.assert_equals(expect=main.TRUE,
+                actual=cellFileResult and cellApplyResult and\
+                        verifyCellResult and checkoutResult and\
+                        pullResult and mvnResult and\
+                        install1Result,
+                        onpass='Test Environment setup successful',
+                        onfail='Failed to setup test environment')
+
+    def CASE2(self, main):
+        """
+        Assign s1 to ONOS1 and measure latency
+        
+        There are 4 levels of latency measurements to this test:
+        1 ) End-to-end measurement: Complete end-to-end measurement
+           from TCP ( SYN/ACK ) handshake to Graph change
+        2 ) OFP-to-graph measurement: 'ONOS processing' snippet of
+           measurement from OFP Vendor message to Graph change
+        3 ) OFP-to-device measurement: 'ONOS processing without
+           graph change' snippet of measurement from OFP vendor
+           message to Device change timestamp
+        4 ) T0-to-device measurement: Measurement that includes
+           the switch handshake to devices timestamp without
+           the graph view change. ( TCP handshake -> Device
+           change )
+        """
+        import time
+        import subprocess
+        import json
+        import requests
+        import os
+        import numpy
+        
+        ONOS1Ip = main.params['CTRL']['ip1']
+        ONOS2Ip = main.params['CTRL']['ip2']
+        ONOS3Ip = main.params['CTRL']['ip3']
+        ONOS4Ip = main.params['CTRL']['ip4']
+        ONOS5Ip = main.params['CTRL']['ip5']
+        ONOS6Ip = main.params['CTRL']['ip6']
+        ONOS7Ip = main.params['CTRL']['ip7']
+        
+        ONOSUser = main.params['CTRL']['user']
+        defaultSwPort = main.params['CTRL']['port1']
+        numIter = main.params['TEST']['numIter']
+        iterIgnore = int(main.params['TEST']['iterIgnore'])
+        deviceTimestamp = main.params['JSON']['deviceTimestamp']
+        graphTimestamp = main.params['JSON']['graphTimestamp']
+        debugMode = main.params['TEST']['debugMode']
+        onosLog = main.params['TEST']['onosLogFile']
+        resultPath = main.params['DB']['switchEventResultPath']
+        thresholdStr = main.params['TEST']['singleSwThreshold']
+        thresholdObj = thresholdStr.split(',')
+        thresholdMin = int(thresholdObj[0])
+        thresholdMax = int(thresholdObj[1])
+       
+        #TODO: Look for 'role-request' messages,
+        #      which replaces the 'vendor' messages previously seen
+        #      on OVS 2.0.1
+        tsharkOfString = main.params[ 'TSHARK' ][ 'ofpRoleReply' ]
+        tsharkTcpString = main.params[ 'TSHARK' ][ 'tcpSynAck' ]
+        tsharkOfOutput = '/tmp/tshark_of_topo.txt'
+        tsharkTcpOutput = '/tmp/tshark_tcp_topo.txt'
+
+        latencyEndToEndList = []
+        latencyOfpToGraphList = []
+        latencyOfpToDeviceList = []
+        latencyT0ToDeviceList = []
+        latencyTcpToOfpList = []
+        
+        endToEndLatNodeIter = numpy.zeros((clusterCount, int(numIter)))
+        ofpToGraphLatNodeIter = numpy.zeros((clusterCount, int(numIter)))
+        ofpToDeviceLatNodeIter = numpy.zeros((clusterCount, int(numIter)))
+        
+        tcpToOfpLatIter = []
+        assertion = main.TRUE
+        localTime = time.strftime('%x %X')
+        localTime = localTime.replace('/', '')
+        localTime = localTime.replace(' ', '_')
+        localTime = localTime.replace(':', '')
+
+        if debugMode == 'on':
+            main.ONOS1.tsharkPcap('eth0',
+                    '/tmp/single_sw_lat_pcap_' + localTime)
+            main.log.info('Debug mode is on')
+        main.log.report('Latency of adding one switch to controller')
+        main.log.report('First ' + str(iterIgnore) +
+                ' iterations ignored' + ' for jvm warmup time')
+        main.log.report('Total iterations of test: ' + str(numIter))
+        
+        for i in range(0, int(numIter)):
+            main.log.info('Starting tshark capture')
+            main.ONOS1.tsharkGrep(tsharkTcpString, tsharkTcpOutput)
+            main.ONOS1.tsharkGrep(tsharkOfString, tsharkOfOutput)
+            
+            time.sleep(10)
+           
+            main.log.info('Assigning s3 to controller')
+            main.Mininet1.assignSwController(sw='3',
+                    ip1=ONOS1Ip, port1=defaultSwPort)
+            
+            time.sleep(10)
+            
+            main.log.info('Stopping all Tshark processes')
+            main.ONOS1.tsharkStop()
+            
+            main.log.info('Copying over tshark files')
+            os.system('scp ' + ONOSUser + '@' + ONOS1Ip +
+                    ':' + tsharkTcpOutput + ' /tmp/')
+            time.sleep(5)
+            tcpFile = open(tsharkTcpOutput, 'r')
+            tempText = tcpFile.readline()
+            tempText = tempText.split(' ')
+            main.log.info('Object read in from TCP capture: ' +
+                    str(tempText))
+            
+            if len(tempText) > 1:
+                t0Tcp = float(tempText[1]) * 1000.0
+            else:
+                main.log.error('Tshark output file for TCP' +
+                        ' returned unexpected results')
+                t0Tcp = 0
+                assertion = main.FALSE
+            tcpFile.close()
+            
+            os.system('scp ' + ONOSUser + '@' +
+                      ONOS1Ip + ':' + tsharkOfOutput + ' /tmp/')
+            
+            time.sleep(5)
+            ofFile = open(tsharkOfOutput, 'r')
+            lineOfp = ''
+            while True:
+                tempText = ofFile.readline()
+                if tempText != '':
+                    lineOfp = tempText
+                else:
+                    break
+
+            obj = lineOfp.split(' ')
+            main.log.info('Object read in from OFP capture: ' +
+                    str(lineOfp))
+            if len(obj) > 1:
+                t0Ofp = float(obj[1]) * 1000.0
+            else:
+                main.log.error('Tshark output file for OFP' +
+                        ' returned unexpected results')
+                t0Ofp = 0
+                assertion = main.FALSE
+            ofFile.close()
+            
+            jsonStr1 = main.ONOS1cli.topologyEventsMetrics()
+            jsonStr2 = ''
+            jsonStr3 = ''
+            jsonStr4 = ''
+            jsonStr5 = ''
+            jsonStr6 = ''
+            jsonStr7 = ''
+            
+            jsonObj1 = json.loads(jsonStr1)
+            jsonObj2 = ''
+            jsonObj3 = ''
+            jsonObj4 = ''
+            jsonObj5 = ''
+            jsonObj6 = ''
+            jsonObj7 = ''
+            
+            graphTimestamp1 = jsonObj1[graphTimestamp]['value']
+            deviceTimestamp1 = jsonObj1[deviceTimestamp]['value']
+            
+            main.log.info(' GraphTimestamp: ' + str(graphTimestamp1))
+            main.log.info(' DeviceTimestamp: ' + str(deviceTimestamp1))
+            
+            deltaDevice1 = int(deviceTimestamp1) - int(t0Tcp)
+            deltaGraph1 = int(graphTimestamp1) - int(t0Tcp)
+            deltaOfpGraph1 = int(graphTimestamp1) - int(t0Ofp)
+            deltaOfpDevice1 = int(deviceTimestamp1) - int(t0Ofp)
+            deltaTcpOfp1 = int(t0Ofp) - int(t0Tcp)
+            
+            if deltaTcpOfp1 > thresholdMin and\
+               deltaTcpOfp1 < thresholdMax and i >= iterIgnore:
+                tcpToOfpLatIter.append(deltaTcpOfp1)
+                main.log.info('ONOS1 iter' + str(i) +
+                              ' tcp-to-ofp: ' +
+                              str(deltaTcpOfp1) + ' ms')
+            else:
+                tcpToOfpLatIter.append(0)
+                main.log.info('ONOS1 iter' + str(i) +
+                        ' tcp-to-ofp: ' + str(deltaTcpOfp1) +
+                        ' ms - ignored this iteration')
+            if deltaGraph1 > thresholdMin and\
+               deltaGraph1 < thresholdMax and i >= iterIgnore:
+                endToEndLatNodeIter[0][i] = deltaGraph1
+                main.log.info('ONOS1 iter' + str(i) +
+                              ' end-to-end: ' +
+                              str(deltaGraph1) + ' ms')
+            else:
+                main.log.info('ONOS1 iter' + str(i) +
+                        ' end-to-end: ' + str(deltaGraph1) +
+                        ' ms - ignored this iteration')
+            if deltaOfpGraph1 > thresholdMin and \
+               deltaOfpGraph1 < thresholdMax and i >= iterIgnore:
+                ofpToGraphLatNodeIter[0][i] = deltaOfpGraph1
+                main.log.info('ONOS1 iter' + str(i) +
+                        ' ofp-to-graph: ' +
+                        str(deltaOfpGraph1) + ' ms')
+            if deltaOfpDevice1 > thresholdMin and\
+               deltaOfpDevice1 < thresholdMax and i >= iterIgnore:
+                ofpToDeviceLatNodeIter[0][i] = deltaOfpDevice1
+                main.log.info('ONOS1 iter' + str(i) +
+                        ' ofp-to-device: ' +
+                        str(deltaOfpDevice1))
+            
+            if clusterCount >= 3:
+                jsonStr2 = main.ONOS2cli.topologyEventsMetrics()
+                jsonStr3 = main.ONOS3cli.topologyEventsMetrics()
+                jsonObj2 = json.loads(jsonStr2)
+                jsonObj3 = json.loads(jsonStr3)
+                graphTimestamp2 = jsonObj2[graphTimestamp]['value']
+                graphTimestamp3 = jsonObj3[graphTimestamp]['value']
+                deviceTimestamp2 = jsonObj2[deviceTimestamp]['value']
+                deviceTimestamp3 = jsonObj3[deviceTimestamp]['value']
+                deltaDevice2 = int(deviceTimestamp2) - int(t0Tcp)
+                deltaDevice3 = int(deviceTimestamp3) - int(t0Tcp)
+                deltaGraph2 = int(graphTimestamp2) - int(t0Tcp)
+                deltaGraph3 = int(graphTimestamp3) - int(t0Tcp)
+                deltaOfpGraph2 = int(graphTimestamp2) - int(t0Ofp)
+                deltaOfpGraph3 = int(graphTimestamp3) - int(t0Ofp)
+                deltaOfpDevice2 = int(deviceTimestamp2) - int(t0Ofp)
+                deltaOfpDevice3 = int(deviceTimestamp3) - int(t0Ofp)
+                if deltaGraph2 > thresholdMin and\
+                   deltaGraph2 < thresholdMax and i >= iterIgnore:
+                    endToEndLatNodeIter[1][i] = deltaGraph2
+                    main.log.info('ONOS2 iter' + str(i) +
+                            ' end-to-end: ' +
+                            str(deltaGraph2) + ' ms')
+                if deltaOfpGraph2 > thresholdMin and\
+                   deltaOfpGraph2 < thresholdMax and i >= iterIgnore:
+                    ofpToGraphLatNodeIter[1][i] = deltaOfpGraph2
+                    main.log.info('ONOS2 iter' + str(i) +
+                            ' ofp-to-graph: ' +
+                            str(deltaOfpGraph2) + ' ms')
+                if deltaOfpDevice2 > thresholdMin and\
+                   deltaOfpDevice2 < thresholdMax and i >= iterIgnore:
+                    ofpToDeviceLatNodeIter[1][i] = deltaOfpDevice2
+                    main.log.info('ONOS2 iter' + str(i) +
+                            ' ofp-to-device: ' +
+                            str(deltaOfpDevice2))
+                if deltaGraph3 > thresholdMin and\
+                   deltaGraph3 < thresholdMax and i >= iterIgnore:
+                    endToEndLatNodeIter[2][i] = deltaGraph3
+                    main.log.info('ONOS3 iter' + str(i) +
+                            ' end-to-end: ' + str(deltaGraph3) + ' ms')
+                if deltaOfpGraph3 > thresholdMin and\
+                   deltaOfpGraph3 < thresholdMax and i >= iterIgnore:
+                    ofpToGraphLatNodeIter[2][i] = deltaOfpGraph3
+                    main.log.info('ONOS3 iter' + str(i) +
+                            ' ofp-to-graph: ' +
+                            str(deltaOfpGraph3) + ' ms')
+                if deltaOfpDevice3 > thresholdMin and\
+                        deltaOfpDevice3 < thresholdMax and i >= iterIgnore:
+                    ofpToDeviceLatNodeIter[2][i] = deltaOfpDevice3
+                    main.log.info('ONOS3 iter' + str(i) +
+                            ' ofp-to-device: ' + str(deltaOfpDevice3))
+            if clusterCount >= 5:
+                jsonStr4 = main.ONOS4cli.topologyEventsMetrics()
+                jsonStr5 = main.ONOS5cli.topologyEventsMetrics()
+                jsonObj4 = json.loads(jsonStr4)
+                jsonObj5 = json.loads(jsonStr5)
+                graphTimestamp4 = jsonObj4[graphTimestamp]['value']
+                graphTimestamp5 = jsonObj5[graphTimestamp]['value']
+                deviceTimestamp4 = jsonObj4[deviceTimestamp]['value']
+                deviceTimestamp5 = jsonObj5[deviceTimestamp]['value']
+                deltaDevice4 = int(deviceTimestamp4) - int(t0Tcp)
+                deltaDevice5 = int(deviceTimestamp5) - int(t0Tcp)
+                deltaGraph4 = int(graphTimestamp4) - int(t0Tcp)
+                deltaGraph5 = int(graphTimestamp5) - int(t0Tcp)
+                deltaOfpGraph4 = int(graphTimestamp4) - int(t0Ofp)
+                deltaOfpGraph5 = int(graphTimestamp5) - int(t0Ofp)
+                deltaOfpDevice4 = int(deviceTimestamp4) - int(t0Ofp)
+                deltaOfpDevice5 = int(deviceTimestamp5) - int(t0Ofp)
+                if deltaGraph4 > thresholdMin and \
+                   deltaGraph4 < thresholdMax and i >= iterIgnore:
+                    endToEndLatNodeIter[3][i] = deltaGraph4
+                    main.log.info('ONOS4 iter' + str(i) +
+                            ' end-to-end: ' + str(deltaGraph4) + ' ms')
+                if deltaOfpDevice4 > thresholdMin and \
+                   deltaOfpDevice4 < thresholdMax and i >= iterIgnore:
+                    ofpToDeviceLatNodeIter[3][i] = deltaOfpDevice4
+                    main.log.info('ONOS4 iter' + str(i) +
+                            ' ofp-to-device: ' + str(deltaOfpDevice4))
+                if deltaOfpGraph4 > thresholdMin and \
+                        deltaOfpGraph4 < thresholdMax and i >= iterIgnore:
+                    ofpToGraphLatNodeIter[3][i] = deltaOfpGraph4
+                    main.log.info('ONOS4 iter' + str(i) +
+                            ' ofp-to-graph: ' + str(deltaOfpGraph4) + ' ms')
+                if deltaGraph5 > thresholdMin and\
+                        deltaGraph5 < thresholdMax and i >= iterIgnore:
+                    endToEndLatNodeIter[4][i] = deltaGraph5
+                    main.log.info('ONOS5 iter' + str(i) +
+                            ' end-to-end: ' + str(deltaGraph5) + ' ms')
+                if deltaOfpDevice5 > thresholdMin and\
+                        deltaOfpDevice5 < thresholdMax and i >= iterIgnore:
+                    ofpToDeviceLatNodeIter[4][i] = deltaOfpDevice5
+                    main.log.info('ONOS5 iter' + str(i) +
+                            ' ofp-to-device: ' + str(deltaOfpDevice5))
+                if deltaOfpGraph5 > thresholdMin and\
+                        deltaOfpGraph5 < thresholdMax and i >= iterIgnore:
+                    ofpToGraphLatNodeIter[4][i] = deltaOfpGraph5
+                    main.log.info('ONOS5 iter' + str(i) +
+                            ' ofp-to-graph: ' +
+                            str(deltaOfpGraph5) + ' ms')
+            if clusterCount >= 7:
+                jsonStr6 = main.ONOS6cli.topologyEventsMetrics()
+                jsonStr7 = main.ONOS7cli.topologyEventsMetrics()
+                jsonObj6 = json.loads(jsonStr6)
+                jsonObj7 = json.loads(jsonStr7)
+                graphTimestamp6 = jsonObj6[graphTimestamp]['value']
+                graphTimestamp7 = jsonObj7[graphTimestamp]['value']
+                deviceTimestamp6 = jsonObj6[deviceTimestamp]['value']
+                deviceTimestamp7 = jsonObj7[deviceTimestamp]['value']
+                deltaDevice6 = int(deviceTimestamp6) - int(t0Tcp)
+                deltaDevice7 = int(deviceTimestamp7) - int(t0Tcp)
+                deltaGraph6 = int(graphTimestamp6) - int(t0Tcp)
+                deltaGraph7 = int(graphTimestamp7) - int(t0Tcp)
+                deltaOfpGraph6 = int(graphTimestamp6) - int(t0Ofp)
+                deltaOfpGraph7 = int(graphTimestamp7) - int(t0Ofp)
+                deltaOfpDevice6 = int(deviceTimestamp6) - int(t0Ofp)
+                deltaOfpDevice7 = int(deviceTimestamp7) - int(t0Ofp)
+                if deltaGraph6 > thresholdMin and \
+                   deltaGraph6 < thresholdMax and i >= iterIgnore:
+                    endToEndLatNodeIter[5][i] = deltaGraph6
+                    main.log.info('ONOS6 iter' + str(i) +
+                            ' end-to-end: ' + str(deltaGraph6) + ' ms')
+                if deltaOfpDevice6 > thresholdMin and\
+                   deltaOfpDevice6 < thresholdMax and i >= iterIgnore:
+                    ofpToDeviceLatNodeIter[5][i] = deltaOfpDevice6
+                    main.log.info('ONOS6 iter' + str(i) +
+                            ' ofp-to-device: ' + str(deltaOfpDevice6))
+                if deltaOfpGraph6 > thresholdMin and\
+                   deltaOfpGraph6 < thresholdMax and i >= iterIgnore:
+                    ofpToGraphLatNodeIter[5][i] = deltaOfpGraph6
+                    main.log.info('ONOS6 iter' + str(i) +
+                            ' ofp-to-graph: ' +
+                            str(deltaOfpGraph6) + ' ms')
+                if deltaGraph7 > thresholdMin and \
+                   deltaGraph7 < thresholdMax and i >= iterIgnore:
+                    endToEndLatNodeIter[6][i] = deltaGraph7
+                    main.log.info('ONOS7 iter' + str(i) +
+                            ' end-to-end: ' + 
+                            str(deltaGraph7) + ' ms')
+                if deltaOfpDevice7 > thresholdMin and\
+                        deltaOfpDevice7 < thresholdMax and i >= iterIgnore:
+                    ofpToDeviceLatNodeIter[6][i] = deltaOfpDevice7
+                    main.log.info('ONOS7 iter' + str(i) +
+                            ' ofp-to-device: ' +
+                            str(deltaOfpDevice7))
+                if deltaOfpGraph7 > thresholdMin and \
+                        deltaOfpGraph7 < thresholdMax and i >= iterIgnore:
+                    ofpToGraphLatNodeIter[6][i] = deltaOfpGraph7
+                    main.log.info('ONOS7 iter' + str(i) +
+                            ' ofp-to-graph: ' +
+                            str(deltaOfpGraph7) + ' ms')
+            
+            time.sleep(5)
+        
+            # Get device id to remove
+            deviceIdJsonStr = main.ONOS1cli.devices()
+            
+            main.log.info( "Device obj obtained: " + str(deviceIdJsonStr) )
+            deviceId = json.loads(deviceIdJsonStr)
+
+            deviceList = []
+            for device in deviceId:
+                deviceList.append(device['id'])
+            
+            main.step('Remove switch from controller')
+            main.Mininet1.deleteSwController('s3')
+            
+            #firstDevice = deviceList[0] 
+            firstDevice = "of:0000000000000003"
+            main.log.info( "Removing device " +str(firstDevice)+
+                    " from ONOS" )
+            #if deviceId:
+            main.ONOS1cli.deviceRemove(firstDevice)
+            
+            time.sleep(5)
+
+        endToEndAvg = 0
+        ofpToGraphAvg = 0
+        endToEndList = []
+        ofpToGraphList = []
+        ofpToDeviceList = []
+        dbCmdList = []
+        for node in range(0, clusterCount):
+            for item in endToEndLatNodeIter[node]:
+                if item > 0.0:
+                    endToEndList.append(item)
+
+            for item in ofpToGraphLatNodeIter[node]:
+                if item > 0.0:
+                    ofpToGraphList.append(item)
+
+            for item in ofpToDeviceLatNodeIter[node]:
+                if item > 0.0:
+                    ofpToDeviceList.append(item)
+
+            endToEndAvg = round(numpy.mean(endToEndList), 2)
+            ofpToGraphAvg = round(numpy.mean(ofpToGraphList), 2)
+            endToEndStd = round(numpy.std(endToEndList), 2)
+            ofpToGraphStd = round(numpy.std(ofpToGraphList), 2)
+            ofpToDeviceAvg = round(numpy.mean(ofpToDeviceList), 2)
+            ofpToDeviceStd = round(numpy.std(ofpToDeviceList), 2)
+            main.log.report(' - Node ' + str(node + 1) + ' Summary - ')
+            main.log.report(' End-to-end Avg: ' + str(endToEndAvg) +
+                    ' ms' + ' End-to-end Std dev: ' +
+                    str(endToEndStd) + ' ms')
+            main.log.report(' Ofp-to-graph Avg: ' + str(ofpToGraphAvg) +
+                    ' ms' + ' Ofp-to-graph Std dev: ' +
+                    str(ofpToGraphStd) + ' ms')
+            main.log.report(' Ofp-to-device Avg: ' + str(ofpToDeviceAvg) +
+                    ' ms' + ' Ofp-to-device Std dev: ' +
+                    str(ofpToDeviceStd) + ' ms')
+            dbCmdList.append(
+                    "INSERT INTO switch_latency_tests VALUES('" +
+                    timeToPost + "','switch_latency_results'," +
+                    runNum + ',' + str(clusterCount) + ",'baremetal" + 
+                    str(node + 1) + "'," + str(endToEndAvg) + ',' +
+                    str(endToEndStd) + ',0,0);')
+
+        if debugMode == 'on':
+            main.ONOS1.cpLogsToDir('/opt/onos/log/karaf.log',
+                    '/tmp/', copyFileName='sw_lat_karaf')
+        fResult = open(resultPath, 'a')
+        for line in dbCmdList:
+            if line:
+                fResult.write(line + '\n')
+
+        fResult.close()
+        assertion = main.TRUE
+        utilities.assert_equals(expect=main.TRUE, actual=assertion,
+                onpass='Switch latency test successful', 
+                onfail='Switch latency test failed')
+
+    def CASE3(self, main):
+        """
+        Bring port up / down and measure latency.
+        Port enable / disable is simulated by ifconfig up / down
+        
+        In ONOS-next, we must ensure that the port we are
+        manipulating is connected to another switch with a valid
+        connection. Otherwise, graph view will not be updated.
+        """
+        global timeToPost
+        import time
+        import subprocess
+        import os
+        import requests
+        import json
+        import numpy
+        ONOS1Ip = main.params['CTRL']['ip1']
+        ONOS2Ip = main.params['CTRL']['ip2']
+        ONOS3Ip = main.params['CTRL']['ip3']
+        ONOSUser = main.params['CTRL']['user']
+        defaultSwPort = main.params['CTRL']['port1']
+        assertion = main.TRUE
+        numIter = main.params['TEST']['numIter']
+        iterIgnore = int(main.params['TEST']['iterIgnore'])
+        deviceTimestamp = main.params['JSON']['deviceTimestamp']
+        graphTimestamp = main.params['JSON']['graphTimestamp']
+        linkTimestamp = main.params['JSON']['linkTimestamp']
+        
+        tsharkPortUp = '/tmp/tshark_port_up.txt'
+        tsharkPortDown = '/tmp/tshark_port_down.txt'
+        tsharkPortStatus = main.params[ 'TSHARK' ][ 'ofpPortStatus' ]
+        
+        debugMode = main.params['TEST']['debugMode']
+        postToDB = main.params['DB']['postToDB']
+        resultPath = main.params['DB']['portEventResultPath']
+        timeToPost = time.strftime('%Y-%m-%d %H:%M:%S')
+        localTime = time.strftime('%x %X')
+        localTime = localTime.replace('/', '')
+        localTime = localTime.replace(' ', '_')
+        localTime = localTime.replace(':', '')
+        
+        if debugMode == 'on':
+            main.ONOS1.tsharkPcap('eth0', '/tmp/port_lat_pcap_' + localTime)
+        
+        upThresholdStr = main.params['TEST']['portUpThreshold']
+        downThresholdStr = main.params['TEST']['portDownThreshold']
+        upThresholdObj = upThresholdStr.split(',')
+        downThresholdObj = downThresholdStr.split(',')
+        upThresholdMin = int(upThresholdObj[0])
+        upThresholdMax = int(upThresholdObj[1])
+        downThresholdMin = int(downThresholdObj[0])
+        downThresholdMax = int(downThresholdObj[1])
+        
+        interfaceConfig = 's1-eth1'
+        main.log.report('Port enable / disable latency')
+        main.log.report('Simulated by ifconfig up / down')
+        main.log.report('Total iterations of test: ' + str(numIter))
+        main.step('Assign switches s1 and s2 to controller 1')
+        
+        main.Mininet1.assignSwController(sw='1',
+                ip1=ONOS1Ip, port1=defaultSwPort)
+        main.Mininet1.assignSwController(sw='2',
+                ip1=ONOS1Ip, port1=defaultSwPort)
+        
+        time.sleep(15)
+        
+        portUpDeviceToOfpList = []
+        portUpGraphToOfpList = []
+        portDownDeviceToOfpList = []
+        portDownGraphToOfpList = []
+        
+        portUpDevNodeIter = numpy.zeros((clusterCount, int(numIter)))
+        portUpGraphNodeIter = numpy.zeros((clusterCount, int(numIter)))
+        portUpLinkLatNodeIter = numpy.zeros((clusterCount, int(numIter)))
+        portDownDevNodeIter = numpy.zeros((clusterCount, int(numIter)))
+        portDownGraphNodeIter = numpy.zeros((clusterCount, int(numIter)))
+        portDownLinkNodeIter = numpy.zeros((clusterCount, int(numIter)))
+        portUpLinkNodeIter = numpy.zeros((clusterCount, int(numIter)))
+        
+        for i in range(0, int(numIter)):
+            main.step('Starting wireshark capture for port status down')
+            main.ONOS1.tsharkGrep(tsharkPortStatus, tsharkPortDown)
+            time.sleep(5)
+            main.step('Disable port: ' + interfaceConfig)
+            main.Mininet1.handle.sendline('sh ifconfig ' +
+                    interfaceConfig + ' down')
+            main.Mininet1.handle.expect('mininet>')
+            time.sleep(3)
+            main.ONOS1.tsharkStop()
+            os.system('scp ' + ONOSUser + '@' + ONOS1Ip + ':' +
+                    tsharkPortDown + ' /tmp/')
+            fPortDown = open(tsharkPortDown, 'r')
+            fLine = fPortDown.readline()
+            objDown = fLine.split(' ')
+            if len(fLine) > 0:
+                timestampBeginPtDown = int(float(objDown[1]) * 1000)
+                if timestampBeginPtDown < 1400000000000:
+                    timestampBeginPtDown = int(float(objDown[2]) * 1000)
+                main.log.info('Port down begin timestamp: ' +
+                        str(timestampBeginPtDown))
+            else:
+                main.log.info('Tshark output file returned unexpected' +
+                        ' results: ' + str(objDown))
+                timestampBeginPtDown = 0
+            fPortDown.close()
+            
+            main.step('Obtain t1 by metrics call')
+            
+            jsonStrUp1 = main.ONOS1cli.topologyEventsMetrics()
+            jsonObj1 = json.loads(jsonStrUp1)
+            graphTimestamp1 = jsonObj1[graphTimestamp]['value']
+            deviceTimestamp1 = jsonObj1[deviceTimestamp]['value']
+            linkTimestamp1 = jsonObj1[linkTimestamp]['value']
+            ptDownGraphToOfp1 = int(graphTimestamp1) - int(timestampBeginPtDown)
+            ptDownDeviceToOfp1 = int(deviceTimestamp1) - int(timestampBeginPtDown)
+            ptDownLinkToOfp1 = int(linkTimestamp1) - int(timestampBeginPtDown)
+            
+            if ptDownGraphToOfp1 > downThresholdMin and\
+               ptDownGraphToOfp1 < downThresholdMax and i > iterIgnore:
+                portDownGraphNodeIter[0][i] = ptDownGraphToOfp1
+                main.log.info('ONOS1 iter' + str(i) +
+                        ' port down graph-to-ofp: ' +
+                        str(ptDownGraphToOfp1) + ' ms')
+            else:
+                main.log.info('ONOS1 iter' + str(i) + 
+                        ' skipped. Result: ' +
+                        str(ptDownGraphToOfp1) + ' ms')
+            if ptDownDeviceToOfp1 > downThresholdMin and \
+               ptDownDeviceToOfp1 < downThresholdMax and i > iterIgnore:
+                portDownDevNodeIter[0][i] = ptDownDeviceToOfp1
+                main.log.info('ONOS1 iter' + str(i) + 
+                        ' port down device-to-ofp: ' +
+                        str(ptDownDeviceToOfp1) + ' ms')
+            else:
+                main.log.info('ONOS1 iter' + str(i) +
+                        ' skipped. Result: ' +
+                        str(ptDownDeviceToOfp1) + ' ms')
+            if ptDownLinkToOfp1 > downThresholdMin and\
+               ptDownLinkToOfp1 < downThresholdMax and i > iterIgnore:
+                portDownLinkNodeIter[0][i] = ptDownLinkToOfp1
+                main.log.info('ONOS1 iter' + str(i) +
+                        ' port down link-to-ofp: ' +
+                        str(ptDownLinkToOfp1) + ' ms')
+            else:
+                main.log.info('ONOS1 Link-to-ofp skipped. Result: ' +
+                        str(ptDownLinkToOfp1) + ' ms')
+            if clusterCount >= 3:
+                jsonStrUp2 = main.ONOS2cli.topologyEventsMetrics()
+                jsonStrUp3 = main.ONOS3cli.topologyEventsMetrics()
+                jsonObj2 = json.loads(jsonStrUp2)
+                jsonObj3 = json.loads(jsonStrUp3)
+                graphTimestamp2 = jsonObj2[graphTimestamp]['value']
+                graphTimestamp3 = jsonObj3[graphTimestamp]['value']
+                deviceTimestamp2 = jsonObj2[deviceTimestamp]['value']
+                deviceTimestamp3 = jsonObj3[deviceTimestamp]['value']
+                linkTimestamp2 = jsonObj2[linkTimestamp]['value']
+                linkTimestamp3 = jsonObj3[linkTimestamp]['value']
+                ptDownGraphToOfp2 = int(graphTimestamp2) - int(timestampBeginPtDown)
+                ptDownGraphToOfp3 = int(graphTimestamp3) - int(timestampBeginPtDown)
+                ptDownDeviceToOfp2 = int(deviceTimestamp2) - int(timestampBeginPtDown)
+                ptDownDeviceToOfp3 = int(deviceTimestamp3) - int(timestampBeginPtDown)
+                ptDownLinkToOfp2 = int(linkTimestamp2) - int(timestampBeginPtDown)
+                ptDownLinkToOfp3 = int(linkTimestamp3) - int(timestampBeginPtDown)
+                if ptDownGraphToOfp2 > downThresholdMin and\
+                   ptDownGraphToOfp2 < downThresholdMax and i > iterIgnore:
+                    portDownGraphNodeIter[1][i] = ptDownGraphToOfp2
+                    main.log.info('ONOS2 iter' + str(i) +
+                            ' graph-to-ofp: ' +
+                            str(ptDownGraphToOfp2) + ' ms')
+                if ptDownDeviceToOfp2 > downThresholdMin and \
+                   ptDownDeviceToOfp2 < downThresholdMax and i > iterIgnore:
+                    portDownDevNodeIter[1][i] = ptDownDeviceToOfp2
+                    main.log.info('ONOS2 iter' + str(i) +
+                            ' device-to-ofp: ' +
+                            str(ptDownDeviceToOfp2) + ' ms')
+                if ptDownLinkToOfp2 > downThresholdMin and\
+                   ptDownLinkToOfp2 < downThresholdMax and i > iterIgnore:
+                    portDownLinkNodeIter[1][i] = ptDownLinkToOfp2
+                    main.log.info('ONOS2 iter' + str(i) +
+                            ' link-to-ofp: ' +
+                            str(ptDownLinkToOfp2) + ' ms')
+                if ptDownGraphToOfp3 > downThresholdMin and\
+                   ptDownGraphToOfp3 < downThresholdMax and i > iterIgnore:
+                    portDownGraphNodeIter[2][i] = ptDownGraphToOfp3
+                    main.log.info('ONOS3 iter' + str(i) +
+                            ' graph-to-ofp: ' +
+                            str(ptDownGraphToOfp3) + ' ms')
+                if ptDownDeviceToOfp3 > downThresholdMin and\
+                   ptDownDeviceToOfp3 < downThresholdMax and i > iterIgnore:
+                    portDownDevNodeIter[2][i] = ptDownDeviceToOfp3
+                    main.log.info('ONOS3 iter' + str(i) +
+                            ' device-to-ofp: ' +
+                            str(ptDownDeviceToOfp3) + ' ms')
+                if ptDownLinkToOfp3 > downThresholdMin and\
+                   ptDownLinkToOfp3 < downThresholdMax and i > iterIgnore:
+                    portDownLinkNodeIter[2][i] = ptDownLinkToOfp3
+                    main.log.info('ONOS3 iter' + str(i) +
+                            ' link-to-ofp: ' +
+                            str(ptDownLinkToOfp3) + ' ms')
+            if clusterCount >= 5:
+                jsonStrUp4 = main.ONOS4cli.topologyEventsMetrics()
+                jsonStrUp5 = main.ONOS5cli.topologyEventsMetrics()
+                jsonObj4 = json.loads(jsonStrUp4)
+                jsonObj5 = json.loads(jsonStrUp5)
+                graphTimestamp4 = jsonObj4[graphTimestamp]['value']
+                graphTimestamp5 = jsonObj5[graphTimestamp]['value']
+                deviceTimestamp4 = jsonObj4[deviceTimestamp]['value']
+                deviceTimestamp5 = jsonObj5[deviceTimestamp]['value']
+                linkTimestamp4 = jsonObj4[linkTimestamp]['value']
+                linkTimestamp5 = jsonObj5[linkTimestamp]['value']
+                ptDownGraphToOfp4 = int(graphTimestamp4) - int(timestampBeginPtDown)
+                ptDownGraphToOfp5 = int(graphTimestamp5) - int(timestampBeginPtDown)
+                ptDownDeviceToOfp4 = int(deviceTimestamp4) - int(timestampBeginPtDown)
+                ptDownDeviceToOfp5 = int(deviceTimestamp5) - int(timestampBeginPtDown)
+                ptDownLinkToOfp4 = int(linkTimestamp4) - int(timestampBeginPtDown)
+                ptDownLinkToOfp5 = int(linkTimestamp5) - int(timestampBeginPtDown)
+                if ptDownGraphToOfp4 > downThresholdMin and \
+                   ptDownGraphToOfp4 < downThresholdMax and i > iterIgnore:
+                    portDownGraphNodeIter[3][i] = ptDownGraphToOfp4
+                    main.log.info('ONOS4 iter' + str(i) +
+                            ' graph-to-ofp: ' +
+                            str(ptDownGraphToOfp4) + ' ms')
+                if ptDownDeviceToOfp4 > downThresholdMin and\
+                   ptDownDeviceToOfp4 < downThresholdMax and i > iterIgnore:
+                    portDownDevNodeIter[3][i] = ptDownDeviceToOfp4
+                    main.log.info('ONOS4 iter' + str(i) +
+                            ' device-to-ofp: ' +
+                            str(ptDownDeviceToOfp4) + ' ms')
+                if ptDownLinkToOfp4 > downThresholdMin and\
+                   ptDownLinkToOfp4 < downThresholdMax and i > iterIgnore:
+                    portDownLinkNodeIter[3][i] = ptDownLinkToOfp4
+                    main.log.info('ONOS4 iter' + str(i) +
+                            ' link-to-ofp: ' +
+                            str(ptDownLinkToOfp4) + ' ms')
+                if ptDownGraphToOfp5 > downThresholdMin and\
+                   ptDownGraphToOfp5 < downThresholdMax and i > iterIgnore:
+                    portDownGraphNodeIter[4][i] = ptDownGraphToOfp5
+                    main.log.info('ONOS5 iter' + str(i) +
+                            ' graph-to-ofp: ' +
+                            str(ptDownGraphToOfp5) + ' ms')
+                if ptDownDeviceToOfp5 > downThresholdMin and\
+                   ptDownDeviceToOfp5 < downThresholdMax and i > iterIgnore:
+                    portDownDevNodeIter[4][i] = ptDownDeviceToOfp5
+                    main.log.info('ONOS5 iter' + str(i) +
+                            ' device-to-ofp: ' +
+                            str(ptDownDeviceToOfp5) + ' ms')
+                if ptDownLinkToOfp5 > downThresholdMin and\
+                   ptDownLinkToOfp5 < downThresholdMax and i > iterIgnore:
+                    portDownLinkNodeIter[4][i] = ptDownLinkToOfp5
+                    main.log.info('ONOS5 iter' + str(i) +
+                            ' link-to-ofp: ' +
+                            str(ptDownLinkToOfp5) + ' ms')
+            if clusterCount >= 7:
+                jsonStrUp6 = main.ONOS6cli.topologyEventsMetrics()
+                jsonStrUp7 = main.ONOS7cli.topologyEventsMetrics()
+                jsonObj6 = json.loads(jsonStrUp6)
+                jsonObj7 = json.loads(jsonStrUp7)
+                graphTimestamp6 = jsonObj6[graphTimestamp]['value']
+                graphTimestamp7 = jsonObj7[graphTimestamp]['value']
+                deviceTimestamp6 = jsonObj6[deviceTimestamp]['value']
+                deviceTimestamp7 = jsonObj7[deviceTimestamp]['value']
+                linkTimestamp6 = jsonObj6[linkTimestamp]['value']
+                linkTimestamp7 = jsonObj7[linkTimestamp]['value']
+                ptDownGraphToOfp6 = int(graphTimestamp6) - int(timestampBeginPtDown)
+                ptDownGraphToOfp7 = int(graphTimestamp7) - int(timestampBeginPtDown)
+                ptDownDeviceToOfp6 = int(deviceTimestamp6) - int(timestampBeginPtDown)
+                ptDownDeviceToOfp7 = int(deviceTimestamp7) - int(timestampBeginPtDown)
+                ptDownLinkToOfp6 = int(linkTimestamp6) - int(timestampBeginPtDown)
+                ptDownLinkToOfp7 = int(linkTimestamp7) - int(timestampBeginPtDown)
+                if ptDownGraphToOfp6 > downThresholdMin and\
+                   ptDownGraphToOfp6 < downThresholdMax and i > iterIgnore:
+                    portDownGraphNodeIter[5][i] = ptDownGraphToOfp6
+                    main.log.info('ONOS6 iter' + str(i) +
+                            ' graph-to-ofp: ' +
+                            str(ptDownGraphToOfp6) + ' ms')
+                if ptDownDeviceToOfp6 > downThresholdMin and\
+                   ptDownDeviceToOfp6 < downThresholdMax and i > iterIgnore:
+                    portDownDevNodeIter[5][i] = ptDownDeviceToOfp6
+                    main.log.info('ONOS6 iter' + str(i) +
+                            ' device-to-ofp: ' +
+                            str(ptDownDeviceToOfp6) + ' ms')
+                if ptDownLinkToOfp6 > downThresholdMin and\
+                   ptDownLinkToOfp6 < downThresholdMax and i > iterIgnore:
+                    portDownLinkNodeIter[5][i] = ptDownLinkToOfp6
+                    main.log.info('ONOS6 iter' + str(i) +
+                            ' link-to-ofp: ' +
+                            str(ptDownLinkToOfp6) + ' ms')
+                if ptDownGraphToOfp7 > downThresholdMin and\
+                   ptDownGraphToOfp7 < downThresholdMax and i > iterIgnore:
+                    portDownGraphNodeIter[6][i] = ptDownGraphToOfp7
+                    main.log.info('ONOS7 iter' + str(i) +
+                            ' graph-to-ofp: ' +
+                            str(ptDownGraphToOfp7) + ' ms')
+                if ptDownDeviceToOfp7 > downThresholdMin and\
+                   ptDownDeviceToOfp7 < downThresholdMax and i > iterIgnore:
+                    portDownDevNodeIter[6][i] = ptDownDeviceToOfp7
+                    main.log.info('ONOS7 iter' + str(i) +
+                            ' device-to-ofp: ' + 
+                            str(ptDownDeviceToOfp7) + ' ms')
+                if ptDownLinkToOfp7 > downThresholdMin and\
+                   ptDownLinkToOfp7 < downThresholdMax and i > iterIgnore:
+                    portDownLinkNodeIter[6][i] = ptDownLinkToOfp7
+                    main.log.info('ONOS7 iter' + str(i) +
+                            ' link-to-ofp: ' +
+                            str(ptDownLinkToOfp7) + ' ms')
+            
+            time.sleep(3)
+            
+            main.step('Starting wireshark capture for port status up')
+            main.ONOS1.tsharkGrep(tsharkPortStatus, tsharkPortUp)
+            
+            time.sleep(5)
+            main.step('Enable port and obtain timestamp')
+            main.Mininet1.handle.sendline('sh ifconfig ' + interfaceConfig + ' up')
+            main.Mininet1.handle.expect('mininet>')
+            
+            time.sleep(5)
+            main.ONOS1.tsharkStop()
+            
+            time.sleep(3)
+            os.system('scp ' + ONOSUser + '@' +
+                    ONOS1Ip + ':' + tsharkPortUp + ' /tmp/')
+            
+            fPortUp = open(tsharkPortUp, 'r')
+            fLine = fPortUp.readline()
+            objUp = fLine.split(' ')
+            if len(fLine) > 0:
+                timestampBeginPtUp = int(float(objUp[1]) * 1000)
+                if timestampBeginPtUp < 1400000000000:
+                    timestampBeginPtUp = int(float(objUp[2]) * 1000)
+                main.log.info('Port up begin timestamp: ' + str(timestampBeginPtUp))
+            else:
+                main.log.info('Tshark output file returned unexpected' + ' results.')
+                timestampBeginPtUp = 0
+            fPortUp.close()
+            main.step('Obtain t1 by REST call')
+            jsonStrUp1 = main.ONOS1cli.topologyEventsMetrics()
+            jsonObj1 = json.loads(jsonStrUp1)
+            graphTimestamp1 = jsonObj1[graphTimestamp]['value']
+            deviceTimestamp1 = jsonObj1[deviceTimestamp]['value']
+            linkTimestamp1 = jsonObj1[linkTimestamp]['value']
+            ptUpGraphToOfp1 = int(graphTimestamp1) - int(timestampBeginPtUp)
+            ptUpDeviceToOfp1 = int(deviceTimestamp1) - int(timestampBeginPtUp)
+            ptUpLinkToOfp1 = int(linkTimestamp1) - int(timestampBeginPtUp)
+            if ptUpGraphToOfp1 > upThresholdMin and\
+               ptUpGraphToOfp1 < upThresholdMax and i > iterIgnore:
+                portUpGraphNodeIter[0][i] = ptUpGraphToOfp1
+                main.log.info('ONOS1 iter' + str(i) +
+                        ' port up graph-to-ofp: ' +
+                        str(ptUpGraphToOfp1) + ' ms')
+            else:
+                main.log.info('ONOS1 iter' + str(i) +
+                        ' skipped. Result: ' +
+                        str(ptUpGraphToOfp1) + ' ms')
+            if ptUpDeviceToOfp1 > upThresholdMin and \
+               ptUpDeviceToOfp1 < upThresholdMax and i > iterIgnore:
+                portUpDevNodeIter[0][i] = ptUpDeviceToOfp1
+                main.log.info('ONOS1 iter' + str(i) +
+                        ' port up device-to-ofp: ' +
+                        str(ptUpDeviceToOfp1) + ' ms')
+            else:
+                main.log.info('ONOS1 iter' + str(i) +
+                        ' skipped. Result: ' +
+                        str(ptUpDeviceToOfp1) + ' ms')
+            if ptUpLinkToOfp1 > downThresholdMin and\
+               ptUpLinkToOfp1 < downThresholdMax and i > iterIgnore:
+                portUpLinkNodeIter[0][i] = ptUpLinkToOfp1
+                main.log.info('ONOS1 iter' + str(i) +
+                        ' link-to-ofp: ' +
+                        str(ptUpLinkToOfp1) + ' ms')
+            if clusterCount >= 3:
+                jsonStrUp2 = main.ONOS2cli.topologyEventsMetrics()
+                jsonStrUp3 = main.ONOS3cli.topologyEventsMetrics()
+                jsonObj2 = json.loads(jsonStrUp2)
+                jsonObj3 = json.loads(jsonStrUp3)
+                graphTimestamp2 = jsonObj2[graphTimestamp]['value']
+                graphTimestamp3 = jsonObj3[graphTimestamp]['value']
+                deviceTimestamp2 = jsonObj2[deviceTimestamp]['value']
+                deviceTimestamp3 = jsonObj3[deviceTimestamp]['value']
+                linkTimestamp2 = jsonObj2[linkTimestamp]['value']
+                linkTimestamp3 = jsonObj3[linkTimestamp]['value']
+                ptUpGraphToOfp2 = int(graphTimestamp2) - int(timestampBeginPtUp)
+                ptUpGraphToOfp3 = int(graphTimestamp3) - int(timestampBeginPtUp)
+                ptUpDeviceToOfp2 = int(deviceTimestamp2) - int(timestampBeginPtUp)
+                ptUpDeviceToOfp3 = int(deviceTimestamp3) - int(timestampBeginPtUp)
+                ptUpLinkToOfp2 = int(linkTimestamp2) - int(timestampBeginPtUp)
+                ptUpLinkToOfp3 = int(linkTimestamp3) - int(timestampBeginPtUp)
+                if ptUpGraphToOfp2 > upThresholdMin and\
+                   ptUpGraphToOfp2 < upThresholdMax and i > iterIgnore:
+                    portUpGraphNodeIter[1][i] = ptUpGraphToOfp2
+                    main.log.info('ONOS2 iter' + str(i) +
+                            ' port up graph-to-ofp: ' +
+                            str(ptUpGraphToOfp2) + ' ms')
+                if ptUpDeviceToOfp2 > upThresholdMin and\
+                   ptUpDeviceToOfp2 < upThresholdMax and i > iterIgnore:
+                    portUpDevNodeIter[1][i] = ptUpDeviceToOfp2
+                    main.log.info('ONOS2 iter' + str(i) +
+                            ' port up device-to-ofp: ' +
+                            str(ptUpDeviceToOfp2) + ' ms')
+                if ptUpLinkToOfp2 > downThresholdMin and\
+                   ptUpLinkToOfp2 < downThresholdMax and i > iterIgnore:
+                    portUpLinkNodeIter[1][i] = ptUpLinkToOfp2
+                    main.log.info('ONOS2 iter' + str(i) +
+                            ' port up link-to-ofp: ' +
+                            str(ptUpLinkToOfp2) + ' ms')
+                if ptUpGraphToOfp3 > upThresholdMin and\
+                   ptUpGraphToOfp3 < upThresholdMax and i > iterIgnore:
+                    portUpGraphNodeIter[2][i] = ptUpGraphToOfp3
+                    main.log.info('ONOS3 iter' + str(i) +
+                            ' port up graph-to-ofp: ' +
+                            str(ptUpGraphToOfp3) + ' ms')
+                if ptUpDeviceToOfp3 > upThresholdMin and\
+                   ptUpDeviceToOfp3 < upThresholdMax and i > iterIgnore:
+                    portUpDevNodeIter[2][i] = ptUpDeviceToOfp3
+                    main.log.info('ONOS3 iter' + str(i) +
+                            ' port up device-to-ofp: ' +
+                            str(ptUpDeviceToOfp3) + ' ms')
+                if ptUpLinkToOfp3 > downThresholdMin and\
+                   ptUpLinkToOfp3 < downThresholdMax and i > iterIgnore:
+                    portUpLinkNodeIter[2][i] = ptUpLinkToOfp3
+                    main.log.info('ONOS3 iter' + str(i) +
+                            ' port up link-to-ofp: ' +
+                            str(ptUpLinkToOfp3) + ' ms')
+            if clusterCount >= 5:
+                jsonStrUp4 = main.ONOS4cli.topologyEventsMetrics()
+                jsonStrUp5 = main.ONOS5cli.topologyEventsMetrics()
+                jsonObj4 = json.loads(jsonStrUp4)
+                jsonObj5 = json.loads(jsonStrUp5)
+                graphTimestamp4 = jsonObj4[graphTimestamp]['value']
+                graphTimestamp5 = jsonObj5[graphTimestamp]['value']
+                deviceTimestamp4 = jsonObj4[deviceTimestamp]['value']
+                deviceTimestamp5 = jsonObj5[deviceTimestamp]['value']
+                linkTimestamp4 = jsonObj4[linkTimestamp]['value']
+                linkTimestamp5 = jsonObj5[linkTimestamp]['value']
+                ptUpGraphToOfp4 = int(graphTimestamp4) - int(timestampBeginPtUp)
+                ptUpGraphToOfp5 = int(graphTimestamp5) - int(timestampBeginPtUp)
+                ptUpDeviceToOfp4 = int(deviceTimestamp4) - int(timestampBeginPtUp)
+                ptUpDeviceToOfp5 = int(deviceTimestamp5) - int(timestampBeginPtUp)
+                ptUpLinkToOfp4 = int(linkTimestamp4) - int(timestampBeginPtUp)
+                ptUpLinkToOfp5 = int(linkTimestamp5) - int(timestampBeginPtUp)
+                if ptUpGraphToOfp4 > upThresholdMin and\
+                   ptUpGraphToOfp4 < upThresholdMax and i > iterIgnore:
+                    portUpGraphNodeIter[3][i] = ptUpGraphToOfp4
+                    main.log.info('ONOS4 iter' + str(i) +
+                            ' port up graph-to-ofp: ' +
+                            str(ptUpGraphToOfp4) + ' ms')
+                if ptUpDeviceToOfp4 > upThresholdMin and\
+                   ptUpDeviceToOfp4 < upThresholdMax and i > iterIgnore:
+                    portUpDevNodeIter[3][i] = ptUpDeviceToOfp4
+                    main.log.info('ONOS4 iter' + str(i) +
+                            ' port up device-to-ofp: ' +
+                            str(ptUpDeviceToOfp4) + ' ms')
+                if ptUpGraphToOfp5 > upThresholdMin and\
+                    ptUpGraphToOfp5 < upThresholdMax and i > iterIgnore:
+                    portUpGraphNodeIter[4][i] = ptUpGraphToOfp5
+                    main.log.info('ONSO5 iter' + str(i) +
+                            ' port up graph-to-ofp: ' +
+                            str(ptUpGraphToOfp5) + ' ms')
+                if ptUpDeviceToOfp5 > upThresholdMin and \
+                   ptUpDeviceToOfp5 < upThresholdMax and i > iterIgnore:
+                    portUpDevNodeIter[4][i] = ptUpDeviceToOfp5
+                    main.log.info('ONOS5 iter' + str(i) +
+                            ' port up device-to-ofp: ' +
+                            str(ptUpDeviceToOfp5) + ' ms')
+            if clusterCount >= 7:
+                jsonStrUp6 = main.ONOS6cli.topologyEventsMetrics()
+                jsonStrUp7 = main.ONOS7cli.topologyEventsMetrics()
+                jsonObj6 = json.loads(jsonStrUp6)
+                jsonObj7 = json.loads(jsonStrUp7)
+                graphTimestamp6 = jsonObj6[graphTimestamp]['value']
+                graphTimestamp7 = jsonObj7[graphTimestamp]['value']
+                deviceTimestamp6 = jsonObj6[deviceTimestamp]['value']
+                deviceTimestamp7 = jsonObj7[deviceTimestamp]['value']
+                ptUpGraphToOfp6 = int(graphTimestamp6) - int(timestampBeginPtUp)
+                ptUpGraphToOfp7 = int(graphTimestamp7) - int(timestampBeginPtUp)
+                ptUpDeviceToOfp6 = int(deviceTimestamp6) - int(timestampBeginPtUp)
+                ptUpDeviceToOfp7 = int(deviceTimestamp7) - int(timestampBeginPtUp)
+                if ptUpGraphToOfp6 > upThresholdMin and\
+                   ptUpGraphToOfp6 < upThresholdMax and i > iterIgnore:
+                    portUpGraphNodeIter[5][i] = ptUpGraphToOfp6
+                    main.log.info('iter' + str(i) +
+                            ' port up graph-to-ofp: ' +
+                            str(ptUpGraphToOfp6) + ' ms')
+                if ptUpDeviceToOfp6 > upThresholdMin and\
+                   ptUpDeviceToOfp6 < upThresholdMax and i > iterIgnore:
+                    portUpDevNodeIter[5][i] = ptUpDeviceToOfp6
+                    main.log.info('iter' + str(i) +
+                            ' port up device-to-ofp: ' + 
+                            str(ptUpDeviceToOfp6) + ' ms')
+                if ptUpGraphToOfp7 > upThresholdMin and \
+                   ptUpGraphToOfp7 < upThresholdMax and i > iterIgnore:
+                    portUpGraphNodeIter[6][i] = ptUpGraphToOfp7
+                    main.log.info('iter' + str(i) +
+                            ' port up graph-to-ofp: ' + 
+                            str(ptUpGraphToOfp7) + ' ms')
+                if ptUpDeviceToOfp7 > upThresholdMin and\
+                   ptUpDeviceToOfp7 < upThresholdMax and i > iterIgnore:
+                    portUpDevNodeIter[6][i] = ptUpDeviceToOfp7
+                    main.log.info('iter' + str(i) +
+                            ' port up device-to-ofp: ' +
+                            str(ptUpDeviceToOfp7) + ' ms')
+
+        dbCmdList = []
+        for node in range(0, clusterCount):
+            portUpDevList = []
+            portUpGraphList = []
+            portDownDevList = []
+            portDownGraphList = []
+            portUpDevAvg = 0
+            portUpGraphAvg = 0
+            portDownDevAvg = 0
+            portDownGraphAvg = 0
+            for item in portUpDevNodeIter[node]:
+                if item > 0.0:
+                    portUpDevList.append(item)
+
+            for item in portUpGraphNodeIter[node]:
+                if item > 0.0:
+                    portUpGraphList.append(item)
+
+            for item in portDownDevNodeIter[node]:
+                if item > 0.0:
+                    portDownDevList.append(item)
+
+            for item in portDownGraphNodeIter[node]:
+                if item > 0.0:
+                    portDownGraphList.append(item)
+
+            portUpDevAvg = round(numpy.mean(portUpDevList), 2)
+            portUpGraphAvg = round(numpy.mean(portUpGraphList), 2)
+            portDownDevAvg = round(numpy.mean(portDownDevList), 2)
+            portDownGraphAvg = round(numpy.mean(portDownGraphList), 2)
+            portUpStdDev = round(numpy.std(portUpGraphList), 2)
+            portDownStdDev = round(numpy.std(portDownGraphList), 2)
+            main.log.report(' - Node ' + str(node + 1) + ' Summary - ')
+            main.log.report(' Port up ofp-to-device ' +
+                    str(round(portUpDevAvg, 2)) + ' ms')
+            main.log.report(' Port up ofp-to-graph ' +
+                    str(portUpGraphAvg) + ' ms')
+            main.log.report(' Port down ofp-to-device ' +
+                    str(round(portDownDevAvg, 2)) + ' ms')
+            main.log.report(' Port down ofp-to-graph ' +
+                    str(portDownGraphAvg) + ' ms')
+            dbCmdList.append("INSERT INTO port_latency_tests VALUES('" + 
+                    timeToPost + "','port_latency_results'," + runNum +
+                    ',' + str(clusterCount) + ",'baremetal" + str(node + 1) +
+                    "'," + str(portUpGraphAvg) + ',' + str(portUpStdDev) +
+                    '' + str(portDownGraphAvg) + ',' + str(portDownStdDev) + ');')
+
+        fResult = open(resultPath, 'a')
+        for line in dbCmdList:
+            if line:
+                fResult.write(line + '\n')
+
+        fResult.close()
+        main.Mininet1.deleteSwController('s1')
+        main.Mininet1.deleteSwController('s2')
+        utilities.assert_equals(expect=main.TRUE,
+                actual=assertion,
+                onpass='Port discovery latency calculation successful',
+                onfail='Port discovery test failed')
+
+    def CASE4(self, main):
+        """
+        Increase number of nodes and initiate CLI
+        
+        With the most recent implementation, we need a method to
+        ensure all ONOS nodes are killed, as well as redefine
+        the cell files to ensure all nodes that will be used
+        is in the cell file. Otherwise, exceptions will
+        prohibit test from running successfully.
+        
+        3/12/15
+
+        """
+        global clusterCount
+        import time
+        import os
+
+        clusterCount += 2
+
+        benchIp = main.params[ 'BENCH' ][ 'ip' ]
+        features = main.params[ 'ENV' ][ 'cellFeatures' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        mininetIp = main.params[ 'MN' ][ 'ip1' ]
+        
+        main.log.report('Increasing cluster size to ' + str(clusterCount))
+     
+        main.log.step( "Killing all ONOS processes before scale-out" )
+        
+        for i in range( 1, 8 ):
+            main.ONOSbench.onosDie(
+                    main.params[ 'CTRL' ][ 'ip'+str(i) ] )
+            main.ONOSbench.onosUninstall(
+                    main.params[ 'CTRL' ][ 'ip'+str(i) ] )
+
+        main.step( "Creating scale-out cell file" )
+        cellIp = []
+        for node in range( 1, clusterCount + 1 ):
+            cellIp.append( main.params[ 'CTRL' ][ 'ip'+str(node) ] )
+
+        main.log.info( "Cell Ip list: " + str(cellIp) )
+        main.ONOSbench.createCellFile( benchIp, cellName, mininetIp,
+                                       str(features), *cellIp )
+        
+        main.step( "Setting cell definition" )
+        main.ONOSbench.setCell(cellName)
+
+        main.step( "Packaging cell definition" )
+        main.ONOSbench.onosPackage()
+
+        for node in range( 1, clusterCount + 1 ):
+            main.ONOSbench.onosInstall(
+                    node = main.params[ 'CTRL' ][ 'ip'+str(node) ])
+        
+        time.sleep( 20 )
+        
+        for node in range( 1, clusterCount + 1):
+            for i in range( 2 ):
+                isup = main.ONOSbench.isup( 
+                        main.params[ 'CTRL' ][ 'ip'+str(node) ] )
+                if isup:
+                    main.log.info( "ONOS "+str(node) + " is up\n")
+                    break
+            if not isup:
+                main.log.error( "ONOS "+str(node) + " did not start" )
+
+        for node in range( 1, clusterCount + 1):
+            exec "a = main.ONOS%scli.startOnosCli" %str(node)
+            a(main.params[ 'CTRL' ][ 'ip'+str(node) ])
+
diff --git a/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.topo b/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.topo
new file mode 100644
index 0000000..a92e391
--- /dev/null
+++ b/TestON/tests/TopoPerfNextBM/TopoPerfNextBM.topo
@@ -0,0 +1,163 @@
+<TOPOLOGY>
+    <COMPONENT>
+        
+        <ONOSbench>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOSbench>
+
+        <ONOS1cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1cli>
+
+        <ONOS2cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2cli>
+        
+        <ONOS3cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3cli>
+        
+        <ONOS4cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4cli>
+        
+        <ONOS5cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5cli>
+        
+        <ONOS6cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6cli>
+        
+        <ONOS7cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>8</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS7cli>
+
+        <ONOS1>
+            <host>10.254.1.201</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>9</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1>
+
+        <ONOS2>
+            <host>10.254.1.202</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>10</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2>
+
+        <ONOS3>
+            <host>10.254.1.203</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>11</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3>
+        
+        <ONOS4>
+            <host>10.254.1.204</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>12</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4>
+        
+        <ONOS5>
+            <host>10.254.1.205</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>13</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5>
+        
+        <ONOS6>
+            <host>10.254.1.206</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>14</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6>
+        
+        <ONOS7>
+            <host>10.254.1.207</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>15</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS7>
+
+        <Mininet1>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>MininetCliDriver</type>
+            <connect_order>16</connect_order>
+            <COMPONENTS>
+                <arg1> --custom topo-perf-2sw.py </arg1>
+                <arg2> --arp --mac --topo mytopo</arg2>
+                <arg3> </arg3>
+                <controller> remote </controller>
+            </COMPONENTS>
+        </Mininet1>
+
+        <Mininet2>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>RemoteMininetDriver</type>
+            <connect_order>17</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </Mininet2>
+
+    </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/IntentsLoad/__init__.py b/TestON/tests/TopoPerfNextSingleNode/__init__.py
similarity index 100%
copy from TestON/tests/IntentsLoad/__init__.py
copy to TestON/tests/TopoPerfNextSingleNode/__init__.py
diff --git a/TestON/tests/IntentsLoad/__init__.py b/TestON/tests/flowTP1g/__init__.py
similarity index 100%
copy from TestON/tests/IntentsLoad/__init__.py
copy to TestON/tests/flowTP1g/__init__.py
diff --git a/TestON/tests/flowTP1g/flowTP1g.params b/TestON/tests/flowTP1g/flowTP1g.params
new file mode 100644
index 0000000..93b3923
--- /dev/null
+++ b/TestON/tests/flowTP1g/flowTP1g.params
@@ -0,0 +1,73 @@
+<PARAMS>
+
+    <testcases>1,3</testcases>
+    
+    <isOnBaremetal>true</isOnBaremetal>
+    <SCALE>1</SCALE>
+    <availableNodes>7</availableNodes>
+    
+
+
+    <ENV>
+        <cellName>flowTP</cellName>
+        <cellFeatures>webconsole,onos-core,onos-api,onos-cli,onos-null,onos-app-demo,onos-rest,onos-app-metrics,onos-app-metrics-intent,onos-app-metrics-topology</cellFeatures>
+    </ENV>
+
+    <TEST>
+        <skipCleanInstall>yes</skipCleanInstall> 
+        <warmUp>4</warmUp>                               #number of runs to warm up the system
+        <sampleSize>20</sampleSize>                      #number of runs to take data from
+        <neighbors>6</neighbors>                    #list of number of neighbors
+        <servers>7</servers>                      #list of servers
+        <flows>122500</flows>
+        <switches>35</switches>
+
+        <testCMD0>flow-tester.py -f</testCMD0>      #base command 
+        <testCMD1> -n </testCMD1>                        #neighbors 
+        
+    </TEST>
+
+    <GIT>
+        <autopull>on</autopull>
+        <checkout>master</checkout>
+    </GIT>
+
+    <CTRL>
+        <USER>admin</USER>
+        
+        <ip1>10.254.1.201</ip1>
+        <port1>6633</port1>
+        
+        <ip2>10.254.1.202</ip2>
+        <port2>6633</port2>
+        
+        <ip3>10.254.1.203</ip3>
+        <port3>6633</port3>
+        
+        <ip4>10.254.1.204</ip4>
+        <port4>6633</port4>
+        
+        <ip5>10.254.1.205</ip5>
+        <port5>6633</port5>
+        
+        <ip6>10.254.1.206</ip6>
+        <port6>6633</port6> 
+       
+         <ip7>10.254.1.207</ip7>
+        <port7>6633</port7>
+
+    </CTRL>
+
+    <MN>
+        <ip1>10.254.1.200</ip1>
+    </MN>
+
+    <BENCH>
+        <user>admin</user>
+        <ip1>10.254.1.200</ip1>
+    </BENCH>
+
+    <JSON>
+    </JSON>
+
+</PARAMS>
diff --git a/TestON/tests/flowTP1g/flowTP1g.py b/TestON/tests/flowTP1g/flowTP1g.py
new file mode 100644
index 0000000..b8450fd
--- /dev/null
+++ b/TestON/tests/flowTP1g/flowTP1g.py
@@ -0,0 +1,412 @@
+# ScaleOutTemplate -> flowTP
+#
+# CASE1 starts number of nodes specified in param file
+#
+# cameron@onlab.us
+
+import sys
+import os.path
+
+
+class flowTP1g:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):            #This is the initialization case
+                                        #this case will clean up all nodes 
+                                        #but only node 1 is started in this case
+        
+        global clusterCount             #number of nodes running
+        global ONOSIp                   #list of ONOS IP addresses 
+        clusterCount = 1
+        ONOSIp = [ 0 ]
+
+
+        #Load values from params file
+        checkoutBranch = main.params[ 'GIT' ][ 'checkout' ]
+        gitPull = main.params[ 'GIT' ][ 'autopull' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        Features= main.params[ 'ENV' ][ 'cellFeatures' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+        MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+        maxNodes = int(main.params[ 'availableNodes' ])
+        Features = main.params[ 'ENV' ][ 'cellFeatures' ]
+        skipMvn = main.params[ 'TEST' ][ 'skipCleanInstall' ]
+        
+        main.ONOSbench.handle.sendline("export TERM=vt100")
+
+        #Populate ONOSIp with ips from params 
+        for i in range(1, maxNodes + 1): 
+            ipString = 'ip' + str(i) 
+            ONOSIp.append(main.params[ 'CTRL' ][ ipString ])   
+
+        #kill off all onos processes 
+        main.log.step("Safety check, killing all ONOS processes")
+        main.log.step("before initiating enviornment setup")
+        for node in range(1, maxNodes + 1):
+            main.ONOSbench.onosDie(ONOSIp[node])
+
+
+        #construct the cell file
+        main.log.info("Creating initial cell file")
+        exec "a = main.ONOSbench.createCellFile"
+        cellIp = []
+        for node in range(1, 2):
+        #for node in range (1, maxNodes + 1):
+            cellIp.append(ONOSIp[node])
+        a(BENCHIp,cellName,MN1Ip,str(Features), *cellIp)
+
+        main.log.info(cellIp)
+
+        #Uninstall everywhere
+        #main.log.step( "Cleaning Enviornment..." )
+        #for i in range(1, maxNodes + 1):
+        #    main.log.info(" Uninstalling ONOS " + str(i) )
+        #    main.ONOSbench.onosUninstall( ONOSIp[i] )
+        
+        #mvn clean install, for debugging set param 'skipCleanInstall' to yes to speed up test
+        if skipMvn != "yes":
+            mvnResult = main.ONOSbench.cleanInstall()
+                        
+            #git
+            main.step( "Git checkout and pull " + checkoutBranch )
+            if gitPull == 'on':
+                checkoutResult = main.ONOSbench.gitCheckout( checkoutBranch )
+                pullResult = main.ONOSbench.gitPull()
+
+            else:
+                checkoutResult = main.TRUE
+                pullResult = main.TRUE
+                main.log.info( "Skipped git checkout and pull" )
+
+
+        #main.step( "Set cell for ONOS cli env" )
+        #main.ONOS1cli.setCell( cellName )
+        
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.onosPackage()  
+
+        #main.step( "Installing ONOS package" )
+        #install1Result = main.ONOSbench.onosInstall( node=ONOSIp[1] )
+
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        main.step( "Applying cell file to environment" )
+        cellApplyResult = main.ONOSbench.setCell( cellName )
+        main.step( "verify cells" )
+        verifyCellResult = main.ONOSbench.verifyCell()
+
+        #main.step( "Set cell for ONOS cli env" )
+        #cli1 = main.ONOS1cli.startOnosCli( node=ONOSIp[1] )
+
+    def CASE2( self, main ):
+        # This case increases the cluster size by whatever scale is
+        # Note: 'scale' is the size of the step
+        # if scaling is not a part of your test, simply run this case
+        # once after CASE1 to set up your enviornment for your desired 
+        # cluster size. If scaling is a part of you test call this case each time 
+        # you want to increase cluster size
+
+        ''                                                         
+        'Increase number of nodes and initiate CLI'
+        ''
+        import time
+        global clusterCount
+
+        scale = int( main.params[ 'SCALE' ] )
+        clusterCount += scale
+
+        main.log.report( "Increasing cluster size to " + str( clusterCount ) )
+        for node in range((clusterCount - scale) + 1, clusterCount + 1):
+            main.ONOSbench.onosDie(ONOSIp[node])
+            time.sleep(10)
+            main.log.info("Starting ONOS " + str(node) + " at IP: " + ONOSIp[node])    
+            main.ONOSbench.onosInstall( node=ONOSIp[node])
+            exec "a = main.ONOS%scli.startOnosCli" %str(node)
+            a(ONOSIp[node])
+    
+    
+    def CASE3( self, main ):
+        #
+        # This is the flow TP test 
+        #
+        import os.path  
+        import numpy       
+        import math
+        import time 
+        import datetime
+        import traceback
+
+        testCMD = [ 0,0,0,0 ]
+        warmUp = int(main.params[ 'TEST' ][ 'warmUp' ])
+        sampleSize = int(main.params[ 'TEST' ][ 'sampleSize' ])
+        switches = int(main.params[ 'TEST' ][ 'switches' ])
+        neighborList = main.params[ 'TEST' ][ 'neighbors' ]
+        serverList = main.params[ 'TEST' ][ 'servers' ]
+        #flows = int(main.params[ 'TEST' ][ 'flows' ]) 
+        testCMD[0] = main.params[ 'TEST' ][ 'testCMD0' ]
+        testCMD[1] = main.params[ 'TEST' ][ 'testCMD1' ]
+        maxNodes = main.params[ 'availableNodes' ]
+        onBaremetal = main.params['isOnBaremetal']
+
+
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        Features= main.params[ 'ENV' ][ 'cellFeatures' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+        MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+        maxNodes = int(main.params[ 'availableNodes' ])
+        Features = main.params[ 'ENV' ][ 'cellFeatures' ]
+        homeDir = os.path.expanduser('~')
+    
+        serverList = serverList.split(",")
+        main.log.info("serverlist: " + str(serverList))
+        neighborList = neighborList.split(",") 
+        main.log.info("neightborlist: " + str(neighborList))
+
+        ts = time.time()
+        st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
+        logFileName = "../logs/flowTPResultsLog" + str(st)
+
+        #initialize log file, remove any previous data
+        resultsLog = open("flowTPResultsLog","w+")
+        resultsLog.close()
+
+        #write file to change mem limit to 32 gigs (BAREMETAL ONLY!)
+        if onBaremetal == "true":
+            filename = "/onos/tools/package/bin/onos-service"
+            serviceConfig = open(homeDir + filename, 'w+')
+            serviceConfig.write("#!/bin/bash\n ")
+            serviceConfig.write("#------------------------------------- \n ")
+            serviceConfig.write("# Starts ONOS Apache Karaf container\n ")
+            serviceConfig.write("#------------------------------------- \n ")
+            serviceConfig.write("#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n ")
+            serviceConfig.write("""export JAVA_OPTS="${JAVA_OPTS:--Xms256m -Xmx8G}" \n """)
+            serviceConfig.write("")
+            serviceConfig.write("ONOS_HOME=/opt/onos \n ")
+            serviceConfig.write("")
+            serviceConfig.write("[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n")
+            serviceConfig.write("""${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """)
+            serviceConfig.close()
+
+        for n in neighborList:
+            for servers in serverList:
+                main.log.step("\tSTARTING TEST")
+                main.log.step("\tSERVERS:  \t" + servers ) 
+                main.log.step("\tNEIGHBORS:\t" + n )  
+                main.log.info("=============================================================")
+                main.log.info("=============================================================")
+                #write file to configure nil link
+                ipCSV = ""
+                for i in range (1, int(maxNodes) + 1):
+                    tempstr = "ip" + str(i)
+                    ipCSV += main.params[ 'CTRL' ][ tempstr ] 
+                    if i < int(maxNodes):
+                        ipCSV +=","
+                
+                filename = "/onos/tools/package/etc/org.onosproject.provider.nil.link.impl.NullLinkProvider.cfg"
+                linkConfig = open(homeDir + filename,'w+')
+                linkConfig.write("# eventRate = 2000\n")
+                linkConfig.write("neighbors = "  + ipCSV)
+                main.log.info(" NullLinkProvider.cfg: " + ipCSV)
+                linkConfig.close()
+
+  
+                #write file for null device 
+                filename = "/onos/tools/package/etc/org.onosproject.provider.nil.device.impl.NullDeviceProvider.cfg"
+                deviceConfig = open(homeDir + filename,'w+')    
+            
+                serversToRun = max(int(servers), (int(n) + 1))
+
+                switchDistribution = [(switches/int(serversToRun))]*int(serversToRun) 
+                main.log.info("Switch distribution init: " + str(switchDistribution))
+                remainder = switches % int(serversToRun) 
+                for r in range(0, remainder): 
+                    switchDistribution[r] += 1 
+                main.log.info("Switch distribution: " + str(switchDistribution))
+                    
+                deviceSettings = ""
+                for i in range(0, serversToRun):
+                    deviceSettings += (ONOSIp[i+1] + ":" + str(switchDistribution[i]))
+                    if i < int(serversToRun)-1: 
+                        deviceSettings +=","         
+
+                deviceConfig.write("devConfigs = "  + deviceSettings)
+                main.log.info(" NullDeviceProvider.cfg: " + deviceSettings)
+                deviceConfig.close() 
+
+                main.log.info("Creating cell file for this step")
+                exec "a = main.ONOSbench.createCellFile"
+                cellIp = []
+                for node in range (1, serversToRun + 1):
+                    cellIp.append(ONOSIp[node]) 
+                main.log.info("Cells are: " + str(cellIp) )
+                a(BENCHIp,cellName,MN1Ip,str(Features), *cellIp)
+                main.step( "Applying cell file to environment for this step" )
+                cellApplyResult = main.ONOSbench.setCell( cellName )
+                main.step( "verify cells for this step" )
+                verifyCellResult = main.ONOSbench.verifyCell()
+                
+                #devide flows
+                flows = int(main.params[ 'TEST' ][ 'flows' ])
+                main.log.info("Flow Target  = " + str(flows))
+
+                flows = (flows *max(int(n)+1,int(servers)))/((int(n) + 1)*int(servers)*(switches))
+
+                main.log.info("Flows per switch = " + str(flows))
+                #main.log.info("Total flows = " + str(switches * flows))
+
+                
+                #kill off all onos processes
+                main.log.step("Safety check, killing all ONOS processes")
+                for node in range(1, int(maxNodes) + 1):
+                    main.ONOSbench.onosDie(ONOSIp[node]) 
+                  
+                #Uninstall everywhere
+                main.log.step( "Cleaning Enviornment..." )
+                for i in range(1, int(maxNodes) + 1):
+                    main.log.info(" Uninstalling ONOS " + str(i) )
+                    main.ONOSbench.onosUninstall( ONOSIp[i] )
+
+                #package
+                main.log.step( "Repackaging onos to reflect config file changes" )
+                main.ONOSbench.onosPackage()
+                
+                # install on relevant nodes
+                startNodes = max(int(n), serversToRun)
+                main.log.step( "Reinstalling ONOS on relevant nodes (1-" + str(startNodes) + ")" )          
+                for s in range(1, startNodes + 1): 
+                    main.ONOSbench.onosInstall( node=ONOSIp[s])    
+                    exec "a = main.ONOS%scli.startOnosCli" %str(s)
+                    a(ONOSIp[s])
+
+                main.log.info("sleeping 30 second waiting for null provider bundle...")
+                time.sleep(30)
+
+                #build list of servers in "$OC1, $OC2...." format
+                serverEnvVars = ""
+                for i in range (1,int(servers)+1):
+                    serverEnvVars += ("-s " + ONOSIp[i] + " ")
+                
+                data = [[""]*int(servers)]*int(sampleSize)
+                maxes = [""]*int(sampleSize)
+
+                for test in range(0, (warmUp + sampleSize)): 
+                    flowCMD = "python3 " + homeDir + "/onos/tools/test/bin/"
+                    flowCMD += testCMD[0] + " " + str(flows) + " " + testCMD[1] 
+                    flowCMD += " " + str(n) + " " + str(serverEnvVars)
+                    print("\n")                    
+                    main.log.info("COMMAND: " + flowCMD)
+                    main.log.info("Executing command") 
+                    main.ONOSbench.handle.sendline(flowCMD)
+                    result = []
+                    for s in range(0, int(servers)):
+                        result.append("q")
+                    
+                    for s in range(0, int(servers)):
+                        main.ONOSbench.handle.expect("ms")
+                        rawResult = ((main.ONOSbench.handle.before).splitlines())
+
+                        rawResult = ((rawResult.pop()).split(" "))
+                        main.log.info("Debug: rawResult: " + str(rawResult))
+
+                        myresult = int(rawResult[2])
+                        main.log.info("Result: " + str(myresult))                    
+                            
+                        myIp = rawResult[0]
+                        main.log.info("myIp: " + myIp)
+
+                        serverIndex = int(ONOSIp.index(myIp))
+                        main.log.info("server index = " + str(serverIndex))
+                            
+                        result[serverIndex - 1] = myresult
+                    
+                    if test >= warmUp:
+                        maxes[test-warmUp] = max(result)
+                        main.log.info("Data collection iteration: " + str(test-warmUp) + " of " + str(sampleSize))
+                        main.log.info("Throughput time: " + str(maxes[test-warmUp]) + "(ms)")                
+
+                    if test >= warmUp:
+                        data[test-warmUp] = result
+
+                    # wait for flows = 0 
+                    removedFlows = False
+                    repeat = 0
+                    time.sleep(3)
+                    while removedFlows == False & repeat <= 10:
+                        main.ONOSbench.handle.sendline("onos $OC1 summary| cut -d ' ' -f6")
+                        main.ONOSbench.handle.expect("~")
+                        before = main.ONOSbench.handle.before
+                        parseTest = before.splitlines()
+                        flowsummary = ""
+                        for line in parseTest:
+                            if "flow" in str(line):
+                                flowsummary = line 
+                                break
+                        currentflow = ""
+                        for word in flowsummary.split(" "): 
+                            if "flow" in str(word):
+                                currentflow = str(word)
+                        currentflow = currentflow.replace(",","")
+                        currentflow = currentflow.replace("\n","")
+                        main.log.info(currentflow)
+
+                        zeroFlow = "flows=0"                
+                        if zeroFlow in before:
+                            removedFlows = True 
+                            main.log.info("\t Wait 5 sec of cool down...")
+                            time.sleep(5)
+
+                        time.sleep(5)
+                        repeat +=1
+         
+                main.log.info("raw data: " + str(data))
+                main.log.info("maxes:" + str(maxes))
+
+                
+                # report data
+                print("")
+                main.log.info("\t Results (measurments are in milliseconds)")
+                print("")
+
+                nodeString = ""
+                for i in range(1, int(servers) + 1):
+                    nodeString += ("\tNode " + str(i)) 
+                 
+                for test in range(0, sampleSize ):
+                    main.log.info("\t Test iteration " + str(test + 1) )
+                    main.log.info("\t------------------")
+                    main.log.info(nodeString)       
+                    resultString = ""
+
+                    for i in range(0, int(servers) ):
+                        resultString += ("\t" + str(data[test][i]) ) 
+                    main.log.info(resultString)
+
+                    print("\n")
+
+                avgOfMaxes = numpy.mean(maxes)
+                main.log.info("Average of max value from each test iteration: " + str(avgOfMaxes))
+
+                stdOfMaxes = numpy.std(maxes)
+                main.log.info("Standard Deviation of max values: " + str(stdOfMaxes))       
+                print("\n\n")
+
+                avgTP = int(main.params[ 'TEST' ][ 'flows' ])  / avgOfMaxes #result in kflows/second
+                
+                tp = []
+                for i in maxes: 
+                    tp.append((int(main.params[ 'TEST' ][ 'flows' ]) / i ))
+
+                stdTP = numpy.std(tp)
+
+                main.log.info("Average thoughput:  " + str(avgTP) + " Kflows/second" )
+                main.log.info("Standard deviation of throughput: " + str(stdTP) + " Kflows/second") 
+
+                resultsLog = open(logFileName,"a")
+                resultsLog.write(str(main.params[ 'TEST' ][ 'flows' ]) + "," + n + "," + str(servers) + str(switches) + "," + str(warmUp))
+                resultsLog.write("," +str(sampleSize) + "," + str(avgTP) + "," + str(stdTP) + "\n")
+                resultsLog.close()
+ 
+                    
diff --git a/TestON/tests/flowTP1g/flowTP1g.topo b/TestON/tests/flowTP1g/flowTP1g.topo
new file mode 100644
index 0000000..0e45e0f
--- /dev/null
+++ b/TestON/tests/flowTP1g/flowTP1g.topo
@@ -0,0 +1,146 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS><home>~/onos</home></COMPONENTS>
+        </ONOSbench>
+
+        <ONOS1cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1cli>
+
+        <ONOS2cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2cli>
+
+        <ONOS3cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3cli>
+
+        <ONOS4cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4cli>
+
+        <ONOS5cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5cli>
+
+        <ONOS6cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6cli>
+
+        <ONOS7cli>
+            <host>10.254.1.200</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>8</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS7cli>
+
+        <ONOS1>
+            <host>10.254.1.201</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>9</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1>
+
+        <ONOS2>
+            <host>10.254.1.202</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>10</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2>
+
+        <ONOS3>
+            <host>10.254.1.203</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>11</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3>
+
+        <ONOS4>
+            <host>10.254.1.204</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>12</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4>
+
+    
+        <ONOS5>
+            <host>10.254.1.205</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>13</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5>
+
+        <ONOS6>
+            <host>10.254.1.206</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>14</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6>
+
+        <ONOS7>
+            <host>10.254.1.207</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>15</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS7>
+
+    </COMPONENT>
+
+</TOPOLOGY>
+
+
+    
diff --git a/TestON/tests/IntentsLoad/__init__.py b/TestON/tests/pushTestIntents/__init__.py
similarity index 100%
copy from TestON/tests/IntentsLoad/__init__.py
copy to TestON/tests/pushTestIntents/__init__.py
diff --git a/TestON/tests/pushTestIntents/pushTestIntents.params b/TestON/tests/pushTestIntents/pushTestIntents.params
new file mode 100644
index 0000000..c6b79d5
--- /dev/null
+++ b/TestON/tests/pushTestIntents/pushTestIntents.params
@@ -0,0 +1,66 @@
+<PARAMS>
+
+    <testcases>1,2,3,2,3,2,3</testcases>
+
+    <SCALE>2</SCALE>
+    <availableNodes>7</availableNodes>
+ 
+    <ENV>
+        <cellName>defaultCell</cellName>
+        <cellFeatures>webconsole,onos-core,onos-api,onos-cli,onos-null,onos-gui,onos-rest,onos-app-metrics,onos-app-metrics-intent,onos-app-metrics-topology </cellFeatures>
+    </ENV>
+
+    <TEST>
+        <skipCleanInstall>yes</skipCleanInstall>
+        <switchCount>7</switchCount>
+        <warmUp>4</warmUp>
+        <sampleSize>10</sampleSize>                     
+        <wait></wait>
+        <intents>1,1000</intents>                       #list format, will be split on ','
+        <debug></debug>                          #empty for false/no
+    </TEST>
+
+    <GIT>
+        <autopull>on</autopull>
+        <checkout>master</checkout>
+    </GIT>
+
+    <CTRL>
+        <USER>admin</USER>
+        
+        <ip1>10.128.5.51</ip1>
+        <port1>6633</port1>
+        
+        <ip2>10.128.5.52</ip2>
+        <port2>6633</port2>
+        
+        <ip3>10.128.5.53</ip3>
+        <port3>6633</port3>
+        
+        <ip4>10.128.5.54</ip4>
+        <port4>6633</port4>
+        
+        <ip5>10.128.5.65</ip5>
+        <port5>6633</port5>
+        
+        <ip6>10.128.5.66</ip6>
+        <port6>6633</port6> 
+       
+        <ip7>10.128.5.67</ip7>
+        <port7>6633</port7>
+
+    </CTRL>
+
+    <MN>
+        <ip1>10.128.5.59</ip1>
+    </MN>
+
+    <BENCH>
+        <user>admin</user>
+        <ip1>10.128.5.55</ip1>
+    </BENCH>
+
+    <JSON>
+    </JSON>
+
+</PARAMS>
diff --git a/TestON/tests/pushTestIntents/pushTestIntents.py b/TestON/tests/pushTestIntents/pushTestIntents.py
new file mode 100644
index 0000000..d5623cf
--- /dev/null
+++ b/TestON/tests/pushTestIntents/pushTestIntents.py
@@ -0,0 +1,260 @@
+# ScaleOutTemplate
+#
+# CASE1 starts number of nodes specified in param file
+#
+# cameron@onlab.us
+
+import sys
+import os.path
+
+
+class pushTestIntents:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE1( self, main ):            #This is the initialization case
+                                        #this case will clean up all nodes 
+        import time                     #but only node 1 is started in this case
+        
+        global clusterCount             #number of nodes running
+        global ONOSIp                   #list of ONOS IP addresses 
+        clusterCount = 1
+        ONOSIp = [ 0 ]
+
+
+        #Load values from params file
+        checkoutBranch = main.params[ 'GIT' ][ 'checkout' ]
+        gitPull = main.params[ 'GIT' ][ 'autopull' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        Features= main.params[ 'ENV' ][ 'cellFeatures' ]
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+        MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+        maxNodes = int(main.params[ 'availableNodes' ])
+        Features = main.params[ 'ENV' ][ 'cellFeatures' ]
+        skipMvn = main.params[ 'TEST' ][ 'skipCleanInstall' ]
+        switchCount = main.params[ 'TEST' ][ 'switchCount' ]
+
+        #Populate ONOSIp with ips from params 
+        for i in range(1, maxNodes + 1): 
+            ipString = 'ip' + str(i) 
+            ONOSIp.append(main.params[ 'CTRL' ][ ipString ])   
+    
+        tempIp = []
+        for node in range( 1, clusterCount + 1):
+            tempIp.append(ONOSIp[node])
+
+        #kill off all onos processes 
+        main.log.step("Safety check, killing all ONOS processes")
+        main.log.step("before initiating enviornment setup")
+        for node in range(1, maxNodes + 1):
+            main.ONOSbench.onosDie(ONOSIp[node])
+
+        #construct the cell file
+        main.log.info("Creating cell file")
+        exec "a = main.ONOSbench.createCellFile"
+        cellIp = []
+        for node in range (1, clusterCount + 1):
+            cellIp.append(ONOSIp[node])
+        a(BENCHIp,cellName,MN1Ip,str(Features), *cellIp)
+
+        main.step( "Applying cell file to environment" )
+        cellApplyResult = main.ONOSbench.setCell( cellName )
+
+        #Uninstall everywhere
+        main.log.step( "Cleaning Enviornment..." )
+        for i in range(1, maxNodes + 1):
+            main.log.info(" Uninstalling ONOS " + str(i) )
+            main.ONOSbench.onosUninstall( ONOSIp[i] )
+        
+        #mvn clean install, for debugging set param 'skipCleanInstall' to yes to speed up test
+        if skipMvn != "yes":
+            mvnResult = main.ONOSbench.cleanInstall()
+                        
+            #git
+            main.step( "Git checkout and pull " + checkoutBranch )
+            if gitPull == 'on':
+                checkoutResult = main.ONOSbench.gitCheckout( checkoutBranch )
+                pullResult = main.ONOSbench.gitPull()
+
+            else:
+                checkoutResult = main.TRUE
+                pullResult = main.TRUE
+                main.log.info( "Skipped git checkout and pull" )
+
+        main.ONOSbench.createLinkGraphFile(BENCHIp, tempIp, switchCount)
+        main.ONOSbench.createNullDevProviderFile(BENCHIp, tempIp, switchCount)
+        main.ONOSbench.createNullLinkProviderFile(BENCHIp)
+ 
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.onosPackage()  
+
+        main.step( "Installing ONOS package" )
+        install1Result = main.ONOSbench.onosInstall( node=ONOSIp[1] )
+
+        main.step( "verify cells" )
+        verifyCellResult = main.ONOSbench.verifyCell()
+
+        main.step( "Set cell for ONOS cli env" )
+        cli1 = main.ONOS1cli.startOnosCli( ONOSIp[1] )
+
+        
+    def CASE2( self, main ):
+        # This case increases the cluster size by whatever scale is
+        # Note: 'scale' is the size of the step
+        # if scaling is not a part of your test, simply run this case
+        # once after CASE1 to set up your enviornment for your desired 
+        # cluster size. If scaling is a part of you test call this case each time 
+        # you want to increase cluster size
+
+        ''                                                         
+        'Increase number of nodes and initiate CLI'
+        ''
+        import time
+        global clusterCount
+        
+        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+        scale = int( main.params[ 'SCALE' ] )
+        clusterCount += scale
+        switchCount = main.params[ 'TEST' ][ 'switchCount' ]        
+
+        main.log.info("Creating cell file")
+        exec "a = main.ONOSbench.createCellFile"
+        cellIp = []
+        for node in range (1, clusterCount + 1):
+            cellIp.append(ONOSIp[node])
+        a(BENCHIp,cellName,MN1Ip,str(Features), *cellIp) 
+    
+        main.step( "Applying cell file to environment" )
+        cellApplyResult = main.ONOSbench.setCell( cellName )
+
+        #Uninstall everywhere
+        main.log.step( "Cleaning Enviornment..." )
+        for node in range(1, maxNodes + 1):
+            main.ONOSbench.onosDie(ONOSIp[node])
+            main.log.info(" Uninstalling ONOS " + str(node) )
+            main.ONOSbench.onosUninstall( ONOSIp[node] )
+
+        tempIp = []
+        for node in range( 1, clusterCount + 1): 
+            tempIp.append(ONOSIp[node]) 
+
+        main.ONOSbench.createLinkGraphFile(BENCHIp, tempIp, switchCount) 
+        main.ONOSbench.createNullDevProviderFile(BENCHIp, tempIp, switchCount)
+        main.ONOSbench.createNullLinkProviderFile(BENCHIp)
+
+        main.ONOSbench.onosPackage()
+
+        main.log.report( "Increasing cluster size to " + str( clusterCount ) )
+        for node in range(1, clusterCount + 1):
+            main.log.info("Starting ONOS " + str(node) + " at IP: " + ONOSIp[node])    
+            main.ONOSbench.onosInstall( node=ONOSIp[node])
+            if node == 1: 
+                main.ONOS1cli.startOnosCli( ONOSIp[1] )
+            
+        for node in range(1, clusterCount + 1):       
+            for i in range( 2 ):
+                isup = main.ONOSbench.isup( ONOSIp[node] )
+                if isup:
+                    main.log.info("ONOS " + str(node) + " is up\n")
+                    break
+            if not isup:
+                main.log.report( "ONOS " + str(node) + " didn't start!" ) 
+    
+    def CASE3( self, main ): 
+
+        import time 
+        import numpy 
+        
+
+        sampleSize = int(main.params[ 'TEST' ][ 'sampleSize' ]) 
+        warmUp = int(main.params[ 'TEST' ][ 'warmUp' ])
+        intentsList = (main.params[ 'TEST' ][ 'intents' ]).split(",")
+        switchCount = int(main.params[ 'TEST' ][ 'switchCount' ])
+        debug = main.params[ 'TEST' ][ 'switchCount' ]
+        for i in range(0,len(intentsList)):
+            intentsList[i] = int(intentsList[i]) 
+         
+   
+        linkCount = 0
+        while True:
+            main.ONOSbench.handle.sendline("onos $OC1 links|wc -l")
+            main.ONOSbench.handle.expect(":~")
+            linkCount = main.ONOSbench.handle.before    
+            if debug: main.log.info("Link Count check: " + linkCount)   
+            if str((switchCount*2)-2) in linkCount: 
+                break 
+    
+        links = "--" 
+        while "=null:" not in links:
+            if debug: main.log.info("top of loop")
+            main.ONOSbench.handle.sendline("onos $OC1 links") 
+            main.ONOSbench.handle.expect(":~")
+            links = main.ONOSbench.handle.before
+            if debug: main.log.info(str(links)) 
+            time.sleep(1) 
+        links = links.splitlines()
+        templinks = links                
+                                   
+        tempDevices = []
+        for line in links: 
+            temp = line.split(" ") 
+            temp[0].replace("src=","")
+            temp[0] = (temp[0].split("/"))[0]
+            tempDevices.append(temp[0])                    
+
+        tempDevices.sort()
+        devices = []
+        for i in tempDevices: 
+            if "src=null" in i:
+                devices.append(i.replace("src=", ""))       
+        if debug: main.log.info(str(devices))
+
+        ingress = devices[0]
+        egress = devices.pop()               
+        if debug: main.log.info(ingress)
+        if debug: main.log.info(egress)
+
+        for intentSize in intentsList:
+            cmd = "onos $OC1 push-test-intents "
+            cmd += ingress + "/6 "
+            cmd += egress + "/5 "
+            cmd += str(intentSize) + " 1"
+            installed = []
+            withdrawn = []
+
+            for run in range(0, (warmUp + sampleSize)):
+        
+                myRawResult = "--"
+                while "ms" not in myRawResult:
+                    main.ONOSbench.handle.sendline(cmd)
+                    main.ONOSbench.handle.expect(":~")
+                    myRawResult = main.ONOSbench.handle.before
+                    if debug: main.log.info(myRawResult)
+
+                main.log.info(myRawResult)  
+
+                if run >= warmUp: 
+                    myRawResult = myRawResult.splitlines()
+                    for line in myRawResult:
+                        if "install" in line:
+                            installed.append(line.split(" ")[5])  
+                        if "withdrawn" in line: 
+                            withdrawn.append(line.split(" ")[5])
+                    print(installed)
+                    print(withdrawn)
+            
+            main.log.info("Scale: " + str(clusterCount) + "\tIntent batch size: " + str(intentSize)) 
+            
+                
+                time.sleep(5)
+
+
+
+
+
+
+
+
+
diff --git a/TestON/tests/pushTestIntents/pushTestIntents.topo b/TestON/tests/pushTestIntents/pushTestIntents.topo
new file mode 100644
index 0000000..30a1467
--- /dev/null
+++ b/TestON/tests/pushTestIntents/pushTestIntents.topo
@@ -0,0 +1,146 @@
+<TOPOLOGY>
+
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>10.128.5.55</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS><home>~/onos</home></COMPONENTS>
+        </ONOSbench>
+
+        <ONOS1cli>
+            <host>10.128.5.55</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1cli>
+
+        <ONOS2cli>
+            <host>10.128.5.55</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>3</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2cli>
+
+        <ONOS3cli>
+            <host>10.128.5.55</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>4</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3cli>
+
+        <ONOS4cli>
+            <host>10.128.5.55</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4cli>
+
+        <ONOS5cli>
+            <host>10.128.5.55</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>6</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5cli>
+
+        <ONOS6cli>
+            <host>10.128.5.55</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>7</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6cli>
+
+        <ONOS7cli>
+            <host>10.128.5.55</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>OnosCliDriver</type>
+            <connect_order>8</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS7cli>
+
+        <ONOS1>
+            <host>10.128.5.51</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>9</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS1>
+
+        <ONOS2>
+            <host>10.128.5.52</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>10</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS2>
+
+        <ONOS3>
+            <host>10.128.5.53</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>11</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS3>
+
+        <ONOS4>
+            <host>10.128.5.54</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>12</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS4>
+
+    
+        <ONOS5>
+            <host>10.128.5.65</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>13</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS5>
+
+        <ONOS6>
+            <host>10.128.5.66</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>14</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS6>
+
+        <ONOS7>
+            <host>10.128.5.67</host>
+            <user>sdn</user>
+            <password>rocks</password>
+            <type>OnosDriver</type>
+            <connect_order>15</connect_order>
+            <COMPONENTS> </COMPONENTS>
+        </ONOS7>
+
+    </COMPONENT>
+
+</TOPOLOGY>
+
+
+